www.pudn.com > drivers.rar > test.c


/****************************************************************************** 
 * Flash File System (ffs) 
 * Idea, design and coding by Mads Meisner-Jensen, mmj@ti.com 
 * 
 * ffs test core 
 * 
 * $Id: test.c 1.43.1.105.1.7 Thu, 18 Dec 2003 10:50:52 +0100 tsj $ 
 * 
 ******************************************************************************/ 
 
#include "ffs/ffs.h" 
#include "ffs/board/tffs.h" 
#include "ffs/board/core.h" 
#include "ffs/board/tmffs.h" 
#include "ffs/board/ffstrace.h" 
 
#define COMPILE_ON_WIN32 1 
 
#if (COMPILE_ON_WIN32 == 0) 
#include "ffs/board/pcm.h" 
#endif 
 
#include  
#include  
 
#include  
#include  
#include "ffs/board/win32/getopt.h" 
#include  
#include  
 
#ifndef WIN32 
#include  
#endif //nWIN32 
 
#ifndef WIN32 
#include  
#include  
#include  
#endif //nWIN32 
 
extern char *ffs_strerror(effs_t error); 
 
/****************************************************************************** 
 * Prototypes and Globals 
 ******************************************************************************/ 
 
static void main_args(int argc, char *argv[]); 
static void main_usage(void); 
static long arg_long_get(char *s); 
 
#ifndef WIN32 
static int ffs_server(char type); 
#endif //nWIN32 
 
char *arg_imagename = "image"; // flash image file to use for test 
char *arg_test = "all";        // default test case to run 
int  arg_keepgoing = 0;        // keep going on error 
int  arg_removeimage = 0;      // remove image file first 
char arg_server = 0; 
char arg_pctm = 1; 
 
int  arg_trmask = TrTest;  // trace mask 
int  arg_trspaces = 2;     // indentation multiplier 
 
 
/****************************************************************************** 
 * Globals and Main 
 ******************************************************************************/ 
 
int main(int argc, char *argv[]) 
{ 
    int result; 
 
    main_args(argc, argv); 
 
    tr_init(arg_trmask, arg_trspaces, NULL ); 
 
    if (arg_server == 't' || arg_server == 'u') { 
#ifdef WIN32 
      fprintf(stdout, "FFS_server not supported in WIN32"); 
#else //WIN32 
        result = ffs_server(arg_server); 
#endif //WIN32 
    } 
    else { 
        test_init(arg_keepgoing); 
        result = test_run(arg_test); 
        test_exit(); 
        fprintf(stdout, "TEST TOTAL cases failed: %d\n", result); 
        if (result > 0) 
            fprintf(stderr, "TEST TOTAL cases failed: %d\n", result); 
    } 
 
    exit(0); 
} 
 
 
/****************************************************************************** 
 * Command line parsing 
 ******************************************************************************/ 
 
static void main_args_debug(char *optarg) 
{ 
    char sign; 
    unsigned int mask; 
 
    while (*optarg) { 
        sign = '+'; 
        mask = 0; 
        if (*optarg == '+' || *optarg == '-') 
            sign = *optarg++; 
        if (*optarg) { 
            switch (*optarg) { 
            case 't': mask = TrTest; break; 
            case 'x': mask = TrTestHigh; break; 
            case 'y': mask = TrTestLow; break; 
            case 'p': mask = TrPowerfail; break; 
            case 'b': mask = TrBstat; break; 
            case 'a': mask = TrApi; break; 
            case 'f': mask = TrFsck; break; 
            case 'F': mask = TrFsckLow; break; 
            case 'o': mask = TrObject; break; 
            case 'i': mask = TrIReclaim; break; 
            case 'd': mask = TrDReclaim; break; 
            case 'r': mask = TrReclaimLow; break; 
            case 'w': mask = TrDrvWrite; break; 
            case 'e': mask = TrDrvErase; break; 
            case 'j': mask = TrJournal; break; 
            case 'h': mask = TrUtil; break; 
            case 's': mask = TrServer; break; 
            case '?': mask = TrTrace; break; 
            } 
            switch (*optarg) { 
            case '*': 
                arg_trmask = TrAll & 
//                    ~(TrTrace|TrTmffs|TrDrvWrite|TrDrvErase|TrJournal|TrUtil|TrBstat); 
                    ~(TrTrace|TrDrvWrite|TrDrvErase|TrJournal|TrUtil|TrBstat); 
                break; 
            default: 
                if (sign == '+') 
                    arg_trmask |= mask; 
                else 
                    arg_trmask &= ~mask; 
                break; 
            } 
            optarg++; 
        } 
    } 
    printf("arg_trmask = 0x%X\n", arg_trmask); 
} 
 
static void main_usage(void) 
{ 
    printf("Usage: ffs [OPTIONS...]\n" 
           "\n" 
           /* $Format: "\"Revision $ProjectVersion$, \""$ */ 
"Revision 5.53, " 
           __DATE__ ".\n" 
           "\n" 
           "OPTIONS:\n" 
	   "  -c  Semi-colon separated list of test cases to run.\n" 
           "             Each test case name can be suffixed with one or more\n" 
           "             numerical parameter(s).\n" 
           "             Default is 'all'.\n" 
	   "  -f      Flash image file name. Default is 'image'.\n" 
	   "  -l         List all test cases\n" 
           "  -t   Trace mask in human format. Same as '-t '.\n" 
           "             Default is 't'.\n" 
	   "               * = All\n" 
	   "               t = Test\n" 
	   "               x = TestHigh\n" 
	   "               y = TestLow\n" 
	   "               b = Bstat\n" 
	   "               a = Api\n" 
	   "               f = Fsck\n" 
	   "               F = FsckLow\n" 
	   "               i = IReclaim\n" 
	   "               d = DReclaim\n" 
	   "               r = ReclaimLow\n" 
	   "               j = Journalling\n" 
	   "               w = DrvWrite\n" 
	   "               e = DrvErase\n" 
	   "               h = Helper/Utility Functions\n" 
	   "               s = FFS Server\n" 
	   "               0 = None\n" 
           "  -d i    Trace indentation multiplier. Default is 4.\n" 
           "  -d m    Trace mask. Default is 0.\n" 
	   "  -d s    Trace indentation multiplier (spaces). Default is 4.\n" 
	   "  -s   Start as an FFS server, using either TCP or UDP:\n" 
           "               t = tcp (default)\n" 
           "               u = udp\n" 
	   "  -k         Keep going on error\n" 
	   "  -r         Remove flash image file first\n" 
	   "  -h         Display this help\n"); 
 
    exit(0); 
} 
 
static void main_args(int argc, char *argv[]) 
{ 
    char c; 
     
    while ( (c = getopt(argc, argv, "c:f:krls:t:d:h")) != -1) 
    { 
        switch (c) 
        { 
        case 'c': arg_test = optarg; break; 
        case 'f': arg_imagename = optarg; break; 
        case 'k': arg_keepgoing = 1; break; 
        case 'r': arg_removeimage = 1; break; 
        case 'l': test_listall(); exit(0); break; 
        case 's': arg_server = *optarg; break; 
        case 't': 
            main_args_debug(optarg); 
            break; 
        case 'd': 
            switch(*optarg) { 
            case 's': arg_trspaces = arg_long_get(optarg); break; 
            case 'm': arg_trmask = arg_long_get(optarg); break; 
            } 
            break; 
        case 'h': main_usage(); break; 
        default: 
            main_usage(); 
        } 
    } 
} 
 
static long arg_long_get(char *s) 
{ 
    long value; 
    char *endp; 
 
    errno = 0; 
    value = strtol(optarg, &endp, 0); 
 
    if (errno == ERANGE || *endp != 0) { 
	fprintf(stderr, "Invalid command line argument value: '%s'", s); 
	exit(1); 
    } 
    return value; 
} 
 
 
/****************************************************************************** 
 * Globals and Main 
 ******************************************************************************/ 
#ifndef WIN32 
 
void server_error(char *msg) 
{ 
    perror(msg); 
    exit(1); 
} 
 
#define FFS_SERVER_PORT  (21588) 
 
#define INBUF_SIZE  (2 * 65536) 
#define OUTBUF_SIZE (2 * 65536) 
 
 
static int ffs_server(char type) 
{ 
    char inbuf[INBUF_SIZE], *inbufp; 
    char outbuf[OUTBUF_SIZE], *outbufp; 
    int insize, outsize; 
    int error; 
 
    struct sockaddr_in myaddr; 
    struct sockaddr_in clientaddr; 
    int myfd, clientfd, addr_len; 
 
    error = ffs_initialize(); 
     
    if (type == 'u') 
    { 
        // Code for using UDP datagrams 
 
        /* get an internet domain socket */ 
        if ((myfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) 
            server_error("socket()"); 
        tr(TR_FUNC, TrServer, "socket()\n"); 
 
        /* complete the socket structure */ 
        memset(&myaddr, 0, sizeof(myaddr)); 
        myaddr.sin_family = AF_INET; 
        myaddr.sin_addr.s_addr = INADDR_ANY; 
        myaddr.sin_port = htons(FFS_SERVER_PORT); 
 
        /* bind the socket to the port number */ 
        if (bind(myfd, (struct sockaddr *) &myaddr, sizeof(myaddr)) == -1) 
            server_error("bind()"); 
        tr(TR_FUNC, TrServer, "bind(%d)\n", FFS_SERVER_PORT); 
 
        tr(TR_FUNC, TrServer, 
           "FFS UDP/IP server Waiting for client requests...\n"); 
        for (;;) 
        { 
            addr_len = sizeof(struct sockaddr); 
            if ((insize = recvfrom(myfd, inbuf, sizeof(inbuf), 0,  
                                   (struct sockaddr *) &clientaddr, 
                                   &addr_len)) < 0) 
                server_error("recvfrom()"); 
            tr(TR_FUNC, TrServer, "recv() %d bytes from %s\n", 
               insize, inet_ntoa(clientaddr.sin_addr)); 
             
            outsize = tm_ffs(outbuf, OUTBUF_SIZE, inbuf, insize); 
             
            if(sendto(myfd, outbuf, outsize, 0, 
                      (struct sockaddr *) &clientaddr, 
                      sizeof(struct sockaddr)) < 0) 
                server_error("sendto()"); 
            tr(TR_FUNC, TrServer, "send(%d)\n", outsize); 
        } 
        close(clientfd); 
        close(myfd); 
    } 
    else 
    { 
        // Code for using TCP/IP 
 
        /* get an internet domain socket */ 
        if ((myfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) 
            server_error("socket()"); 
        tr(TR_FUNC, TrServer, "socket()\n"); 
 
        /* complete the socket structure */ 
        memset(&myaddr, 0, sizeof(myaddr)); 
        myaddr.sin_family = AF_INET; 
        myaddr.sin_addr.s_addr = INADDR_ANY; 
        myaddr.sin_port = htons(FFS_SERVER_PORT); 
 
        /* bind the socket to the port number */ 
        if (bind(myfd, (struct sockaddr *) &myaddr, sizeof(myaddr)) == -1) 
            server_error("bind()"); 
        tr(TR_FUNC, TrServer, "bind(%d)\n", FFS_SERVER_PORT); 
 
        /* show that we are willing to listen */ 
        if (listen(myfd, 5) == -1) 
            server_error("listen()"); 
        tr(TR_FUNC, TrServer, "listen()\n"); 
 
        error = 0; 
        while (error == 0 || error == ESHUTDOWN) 
        { 
            tr(TR_FUNC, TrServer, 
               "FFS TCP/IP server waiting for client connection...\n"); 
 
            if ((clientfd = accept(myfd, 0, 0)) < 0) 
                server_error("accept()"); 
            tr(TR_FUNC, TrServer, "accept()\n"); 
 
            error = 0; 
            while (error == 0) 
            { 
                inbufp  = inbuf; 
                outbufp = outbuf; 
 
                if ((insize = read(clientfd, inbufp, sizeof(inbuf))) < 0) { 
                    if (errno == ESHUTDOWN) { 
                        error = ESHUTDOWN; 
                        continue; 
                    } 
                    else { 
                        server_error("recv()"); 
                    } 
                } 
                tr(TR_FUNC, TrServer, "recv() %d bytes\n", insize); 
 
                if (insize == 1 && inbuf[0] == 0) 
                    break; 
 
                if (arg_pctm) { 
                    inbufp++; 
                    insize--; 
                    outbufp = outbuf; 
                    *outbufp++ = 0x70; 
                    *outbufp++ = 0x00; 
                } 
 
                outsize = tm_ffs(outbufp, OUTBUF_SIZE, inbufp, insize); 
             
                if (arg_pctm) { 
                    outsize += 2; 
                } 
                if (write(clientfd, outbuf, outsize) < 0) 
                    server_error("send()"); 
                tr(TR_FUNC, TrServer, "send(%d)\n", outsize); 
            } 
            close(clientfd); 
        } 
        close(myfd); 
    } 
 
    return(0); 
} 
#endif //nWIN32 
 
/****************************************************************************** 
 * Prototypes and Globals 
 ******************************************************************************/ 
 
void test_fatal_printf(char *format, ...) 
{ 
    va_list args; 
    static char buf[1024]; 
 
    va_start(args, format); 
    vsprintf(buf, format, args); 
     
    fprintf(stderr, "%s", buf); 
 
    exit(1); 
}