FreeCalypso > hg > ffs-editor
diff src/cs/drivers/drv_app/ffs/board/test.c @ 0:92470e5d0b9e
src: partial import from FC Selenite
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Fri, 15 May 2020 01:28:16 +0000 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/cs/drivers/drv_app/ffs/board/test.c Fri May 15 01:28:16 2020 +0000 @@ -0,0 +1,416 @@ +/****************************************************************************** + * 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 <stdio.h> +#include <string.h> + +#include <sys/types.h> +#include <stdarg.h> +#include "ffs/board/win32/getopt.h" +#include <errno.h> +#include <stdlib.h> + +#ifndef WIN32 +#include <unistd.h> +#endif //nWIN32 + +#ifndef WIN32 +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#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 '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 <tcase> 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 <n> Flash image file name. Default is 'image'.\n" + " -l List all test cases\n" + " -t <char> Trace mask in human format. Same as '-t <char>'.\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<n> Trace indentation multiplier. Default is 4.\n" + " -d m<n> Trace mask. Default is 0.\n" + " -d s<n> Trace indentation multiplier (spaces). Default is 4.\n" + " -s <char> 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); +} + +