view src/cs/drivers/drv_app/ffs/board/test.c @ 275:79cfefc1e2b4

audio mode load: gracefully handle mode files of wrong AEC version Unfortunately our change of enabling L1_NEW_AEC (which is necessary in order to bring our Calypso ARM fw into match with the underlying DSP reality) brings along a change in the audio mode file binary format and file size - all those new tunable AEC parameters do need to be stored somewhere, after all. But we already have existing mode files in the old format, and setting AEC config to garbage when loading old audio modes (which is what would happen without the present change) is not an appealing proposition. The solution implemented in the present change is as follows: the audio mode loading code checks the file size, and if it differs from the active version of T_AUDIO_MODE, the T_AUDIO_AEC_CFG structure is cleared - set to the default (disabled AEC) for the compiled type of AEC. We got lucky in that this varying T_AUDIO_AEC_CFG structure sits at the end of T_AUDIO_MODE!
author Mychaela Falconia <falcon@freecalypso.org>
date Fri, 30 Jul 2021 02:55:48 +0000
parents 4e78acac3d88
children
line wrap: on
line source

/******************************************************************************
 * 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);
}