diff src/cs/drivers/drv_app/ffs/board/test.c @ 0:4e78acac3d88

src/{condat,cs,gpf,nucleus}: import from Selenite
author Mychaela Falconia <falcon@freecalypso.org>
date Fri, 16 Oct 2020 06:23:26 +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 Oct 16 06:23:26 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);
+}
+
+