VirtualBox

Changeset 60287 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Apr 1, 2016 12:49:19 PM (9 years ago)
Author:
vboxsync
Message:

ValidationKit/usb: Updates to the new USB test service, add configuration file parsing. Work in progress (Backup because switching to something else)

Location:
trunk/src/VBox/ValidationKit/utils/usb
Files:
2 added
3 edited
1 copied

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/ValidationKit/utils/usb/Makefile.kmk

    r60279 r60287  
    4444UsbTestService_SOURCES = \
    4545        UsbTestService.cpp \
     46        UsbTestServiceCfg.cpp \
     47        UsbTestServiceProtocol.cpp \
    4648        UsbTestServiceTcp.cpp
    4749
  • trunk/src/VBox/ValidationKit/utils/usb/UsbTestService.cpp

    r60280 r60287  
    5656
    5757#include "UsbTestServiceInternal.h"
     58#include "UsbTestServiceCfg.h"
    5859
    5960
     
    6465
    6566/**
     67 * UTS client state.
     68 */
     69typedef enum UTSCLIENTSTATE
     70{
     71    /** Invalid client state. */
     72    UTSCLIENTSTATE_INVALID = 0,
     73    /** Client is initialising, only the HOWDY and BYE packets are allowed. */
     74    UTSCLIENTSTATE_INITIALISING,
     75    /** Client is in fully cuntional state and ready to process all requests. */
     76    UTSCLIENTSTATE_READY,
     77    /** Client is destroying. */
     78    UTSCLIENTSTATE_DESTROYING,
     79    /** 32bit hack. */
     80    UTSCLIENTSTATE_32BIT_HACK = 0x7fffffff
     81} UTSCLIENTSTATE;
     82
     83/**
    6684 * UTS client instance.
    6785 */
     
    7088    /** List node for new clients. */
    7189    RTLISTNODE             NdLst;
     90    /** The current client state. */
     91    UTSCLIENTSTATE         enmState;
    7292    /** Transport backend specific data. */
    7393    PUTSTRANSPORTCLIENT    pTransportClient;
     94    /** Client hostname. */
     95    char                  *pszHostname;
    7496} UTSCLIENT;
    7597/** Pointer to a UTS client instance. */
     
    93115/** The select transport layer. */
    94116static PCUTSTRANSPORT       g_pTransport;
     117/** The scratch path. */
     118static char                 g_szCfgPath[RTPATH_MAX];
    95119/** The scratch path. */
    96120static char                 g_szScratchPath[RTPATH_MAX];
     
    118142 * @todo implement signals and stuff.  */
    119143static bool volatile        g_fTerminate = false;
     144/** Configuration AST. */
     145static PCFGAST              g_pCfgAst = NULL;
    120146/** Pipe for communicating with the serving thread about new clients. - read end */
    121147static RTPIPE               g_hPipeR;
     
    129155static RTLISTANCHOR         g_LstClientsNew;
    130156
     157
     158
     159/**
     160 * Returns the string represenation of the given state.
     161 */
     162static const char *utsClientStateStringify(UTSCLIENTSTATE enmState)
     163{
     164    switch (enmState)
     165    {
     166        case UTSCLIENTSTATE_INVALID:
     167            return "INVALID";
     168        case UTSCLIENTSTATE_INITIALISING:
     169            return "INITIALISING";
     170        case UTSCLIENTSTATE_READY:
     171            return "READY";
     172        case UTSCLIENTSTATE_DESTROYING:
     173            return "DESTROYING";
     174        case UTSCLIENTSTATE_32BIT_HACK:
     175        default:
     176            break;
     177    }
     178
     179    AssertMsgFailed(("Unknown state %#x\n", enmState));
     180    return "UNKNOWN";
     181}
    131182
    132183/**
     
    451502
    452503/**
    453  * Checks if the two opcodes match.
    454  *
    455  * @returns true on match, false on mismatch.
    456  * @param   pPktHdr             The packet header.
    457  * @param   pszOpcode2          The opcode we're comparing with.  Does not have
    458  *                              to be the whole 8 chars long.
    459  */
    460 DECLINLINE(bool) utsIsSameOpcode(PCUTSPKTHDR pPktHdr, const char *pszOpcode2)
    461 {
    462     if (pPktHdr->achOpcode[0] != pszOpcode2[0])
    463         return false;
    464     if (pPktHdr->achOpcode[1] != pszOpcode2[1])
    465         return false;
    466 
    467     unsigned i = 2;
    468     while (   i < RT_SIZEOFMEMB(UTSPKTHDR, achOpcode)
    469            && pszOpcode2[i] != '\0')
    470     {
    471         if (pPktHdr->achOpcode[i] != pszOpcode2[i])
    472             break;
    473         i++;
    474     }
    475 
    476     if (   i < RT_SIZEOFMEMB(UTSPKTHDR, achOpcode)
    477         && pszOpcode2[i] == '\0')
    478     {
    479         while (   i < RT_SIZEOFMEMB(UTSPKTHDR, achOpcode)
    480                && pPktHdr->achOpcode[i] == ' ')
    481             i++;
    482     }
    483 
    484     return i == RT_SIZEOFMEMB(UTSPKTHDR, achOpcode);
     504 * Deals with a command which contains an unterminated string.
     505 *
     506 * @returns IPRT status code of the send.
     507 * @param   pClient             The UTS client structure.
     508 * @param   pPktHdr             The packet containing the unterminated string.
     509 */
     510static int utsReplyBadStrTermination(PUTSCLIENT pClient, PCUTSPKTHDR pPktHdr)
     511{
     512    return utsReplyFailure(pClient, pPktHdr, "BAD TERM", VERR_INVALID_PARAMETER, "Opcode '%.8s' contains an unterminated string", pPktHdr->achOpcode);
     513}
     514
     515/**
     516 * Deals with a command sent in an invalid client state.
     517 *
     518 * @returns IPRT status code of the send.
     519 * @param   pClient             The UTS client structure.
     520 * @param   pPktHdr             The packet containing the unterminated string.
     521 */
     522static int utsReplyInvalidState(PUTSCLIENT pClient, PCUTSPKTHDR pPktHdr)
     523{
     524    return utsReplyFailure(pClient, pPktHdr, "INVSTATE", VERR_INVALID_STATE, "Opcode '%.8s' is not supported at client state '%s",
     525                           pPktHdr->achOpcode, utsClientStateStringify(pClient->enmState));
    485526}
    486527
     
    512553static int utsDoHowdy(PUTSCLIENT pClient, PCUTSPKTHDR pPktHdr)
    513554{
    514     if (pPktHdr->cb != sizeof(UTSPKTHDR))
    515         return utsReplyBadSize(pClient, pPktHdr, sizeof(UTSPKTHDR));
     555    if (pPktHdr->cb != sizeof(UTSPKTREQHOWDY))
     556        return utsReplyBadSize(pClient, pPktHdr, sizeof(UTSPKTREQHOWDY));
     557
     558    if (pClient->enmState != UTSCLIENTSTATE_INITIALISING)
     559        return utsReplyInvalidState(pClient, pPktHdr);
     560
     561    PUTSPKTREQHOWDY pReq = (PUTSPKTREQHOWDY)pPktHdr;
     562
     563    if (pReq->uVersion != UTS_PROTOCOL_VS)
     564        return utsReplyRC(pClient, pPktHdr, VERR_VERSION_MISMATCH, "The given version %#x is not supported", pReq->uVersion);
     565
     566    /* Verify hostname string. */
     567    if (pReq->cchHostname >= sizeof(pReq->achHostname))
     568        return utsReplyBadSize(pClient, pPktHdr, sizeof(pReq->achHostname) - 1);
     569
     570    if (pReq->achHostname[pReq->cchHostname] != '\0')
     571        return utsReplyBadStrTermination(pClient, pPktHdr);
     572
     573    /* Extract string. */
     574    pClient->pszHostname = RTStrDup(pClient->pszHostname);
     575    if (!pClient->pszHostname)
     576        return utsReplyRC(pClient, pPktHdr, VERR_NO_MEMORY, "Failed to alllocate memory for the hostname string");
     577
    516578    int rc = utsReplyAck(pClient, pPktHdr);
    517579    if (RT_SUCCESS(rc))
     
    564626static void utsClientDestroy(PUTSCLIENT pClient)
    565627{
     628    if (pClient->pszHostname)
     629        RTStrFree(pClient->pszHostname);
    566630    RTMemFree(pClient);
    567631}
     
    702766        if (RT_LIKELY(pClient))
    703767        {
     768            pClient->enmState         = UTSCLIENTSTATE_INITIALISING;
    704769            pClient->pTransportClient = pTransportClient;
    705770        }
     
    724789{
    725790    int rc = VINF_SUCCESS;
     791    PRTERRINFO pErrInfo = NULL;
    726792
    727793    RTListInit(&g_LstClientsNew);
    728794
    729     rc = RTCritSectInit(&g_CritSectClients);
     795    rc = utsParseConfig(g_szCfgPath, &g_pCfgAst, &pErrInfo);
    730796    if (RT_SUCCESS(rc))
    731797    {
    732         rc = RTPipeCreate(&g_hPipeR, &g_hPipeW, 0);
     798        rc = RTCritSectInit(&g_CritSectClients);
    733799        if (RT_SUCCESS(rc))
    734800        {
    735             /* Spin off the thread serving connections. */
    736             rc = RTThreadCreate(&g_hThreadServing, utsClientWorker, NULL, 0, RTTHREADTYPE_IO, RTTHREADFLAGS_WAITABLE,
    737                                 "USBTSTSRV");
     801            rc = RTPipeCreate(&g_hPipeR, &g_hPipeW, 0);
    738802            if (RT_SUCCESS(rc))
    739                 return VINF_SUCCESS;
     803            {
     804                /* Spin off the thread serving connections. */
     805                rc = RTThreadCreate(&g_hThreadServing, utsClientWorker, NULL, 0, RTTHREADTYPE_IO, RTTHREADFLAGS_WAITABLE,
     806                                    "USBTSTSRV");
     807                if (RT_SUCCESS(rc))
     808                    return VINF_SUCCESS;
     809                else
     810                    RTMsgError("Creating the client worker thread failed with %Rrc\n", rc);
     811
     812                RTPipeClose(g_hPipeR);
     813                RTPipeClose(g_hPipeW);
     814            }
    740815            else
    741                 RTMsgError("Creating the client worker thread failed with %Rrc\n", rc);
    742 
    743             RTPipeClose(g_hPipeR);
    744             RTPipeClose(g_hPipeW);
     816                RTMsgError("Creating communications pipe failed with %Rrc\n", rc);
     817
     818            RTCritSectDelete(&g_CritSectClients);
    745819        }
    746820        else
    747             RTMsgError("Creating communications pipe failed with %Rrc\n", rc);
    748 
    749         RTCritSectDelete(&g_CritSectClients);
     821            RTMsgError("Creating global critical section failed with %Rrc\n", rc);
     822
     823        utsConfigAstDestroy(g_pCfgAst);
    750824    }
    751825    else
    752         RTMsgError("Creating global critical section failed with %Rrc\n", rc);
     826    {
     827        if (RTErrInfoIsSet(pErrInfo))
     828        {
     829            RTMsgError("Failed to parse config with detailed error: %s (%Rrc)\n",
     830                       pErrInfo->pszMsg, pErrInfo->rc);
     831            RTErrInfoFree(pErrInfo);
     832        }
     833        else
     834            RTMsgError("Faield to parse config with unknown error (%Rrc)\n", rc);
     835        return rc;
     836    }
    753837
    754838    return rc;
     
    821905
    822906    /*
     907     * Config file location.
     908     */
     909    /** @todo: Improve */
     910#if !defined(RT_OS_WINDOWS)
     911    strcpy(g_szCfgPath, "/etc/uts.conf");
     912#else
     913    strcpy(g_szCfgPath, "");
     914#endif
     915
     916    /*
    823917     * The default transporter is the first one.
    824918     */
     
    838932                 "\n"
    839933                 "Options:\n"
     934                 "  --config <path>\n"
     935                 "      Where to load the config from\n"
    840936                 "  --cdrom <path>\n"
    841937                 "      Where the CD/DVD-ROM will be mounted.\n"
     
    891987     * Storage for locally handled options.
    892988     */
    893     bool        fDaemonize      = true;
    894     bool        fDaemonized    = false;
     989    bool fDaemonize  = true;
     990    bool fDaemonized = false;
    895991
    896992    /*
     
    899995    static const RTGETOPTDEF s_aBaseOptions[] =
    900996    {
     997        { "--config",           'C', RTGETOPT_REQ_STRING  },
    901998        { "--transport",        't', RTGETOPT_REQ_STRING  },
    902999        { "--cdrom",            'c', RTGETOPT_REQ_STRING  },
     
    9371034        switch (ch)
    9381035        {
     1036            case 'C':
     1037                rc = RTStrCopy(g_szCfgPath, sizeof(g_szCfgPath), Val.psz);
     1038                if (RT_FAILURE(rc))
     1039                    return RTMsgErrorExit(RTEXITCODE_FAILURE, "Config file path is path too long (%Rrc)\n", rc);
     1040                break;
     1041
    9391042            case 'c':
    9401043                rc = RTStrCopy(g_szCdRomPath, sizeof(g_szCdRomPath), Val.psz);
  • trunk/src/VBox/ValidationKit/utils/usb/UsbTestServiceCfg.cpp

    r60281 r60287  
    11/* $Id$ */
    22/** @file
    3  * VBoxAutostart - VirtualBox Autostart service, configuration parser.
     3 * UsbTestServ - Remote USB test configuration and execution server, Config file API.
    44 */
    55
    66/*
    7  * Copyright (C) 2012 Oracle Corporation
     7 * Copyright (C) 2016 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    2828#include <iprt/message.h>
    2929
    30 #include "VBoxAutostart.h"
     30#include "UsbTestServiceCfg.h"
    3131
    3232
     
    126126 * @param   pToken           The token to free.
    127127 */
    128 static void autostartConfigTokenFree(PCFGTOKENIZER pCfgTokenizer, PCFGTOKEN pToken)
     128static void utsConfigTokenFree(PCFGTOKENIZER pCfgTokenizer, PCFGTOKEN pToken)
    129129{
    130130    NOREF(pCfgTokenizer);
     
    138138 * @param   pCfgTokenizer    The config tokenizer.
    139139 */
    140 static int autostartConfigTokenizerReadNextLine(PCFGTOKENIZER pCfgTokenizer)
     140static int utsConfigTokenizerReadNextLine(PCFGTOKENIZER pCfgTokenizer)
    141141{
    142142    int rc = VINF_SUCCESS;
     
    184184 * @param   ppCfgToken       Where to store the pointer to the next token on success.
    185185 */
    186 static int autostartConfigTokenizerCreateToken(PCFGTOKENIZER pCfgTokenizer,
     186static int utsConfigTokenizerCreateToken(PCFGTOKENIZER pCfgTokenizer,
    187187                                               PCFGTOKEN pCfgTokenUse, PCFGTOKEN *ppCfgToken)
    188188{
     
    208208            || *pszToken == '#')
    209209        {
    210             rc = autostartConfigTokenizerReadNextLine(pCfgTokenizer);
     210            rc = utsConfigTokenizerReadNextLine(pCfgTokenizer);
    211211            if (rc == VERR_EOF)
    212212            {
     
    267267                || enmType == CFGTOKENTYPE_ID))
    268268        {
    269             autostartConfigTokenFree(pCfgTokenizer, pCfgTokenUse);
     269            utsConfigTokenFree(pCfgTokenizer, pCfgTokenUse);
    270270            pCfgTokenUse = NULL;
    271271        }
     
    295295        }
    296296        else if (pCfgTokenUse)
    297             autostartConfigTokenFree(pCfgTokenizer, pCfgTokenUse);
     297            utsConfigTokenFree(pCfgTokenizer, pCfgTokenUse);
    298298
    299299        if (RT_SUCCESS(rc))
     
    315315 * @param   pCfgTokenizer    The config tokenizer to destroy.
    316316 */
    317 static void autostartConfigTokenizerDestroy(PCFGTOKENIZER pCfgTokenizer)
     317static void utsConfigTokenizerDestroy(PCFGTOKENIZER pCfgTokenizer)
    318318{
    319319    if (pCfgTokenizer->pszLine)
     
    334334 *                         success.
    335335 */
    336 static int autostartConfigTokenizerCreate(const char *pszFilename, PCFGTOKENIZER *ppCfgTokenizer)
     336static int utsConfigTokenizerCreate(const char *pszFilename, PCFGTOKENIZER *ppCfgTokenizer)
    337337{
    338338    int rc = VINF_SUCCESS;
     
    349349            if (RT_SUCCESS(rc))
    350350            {
    351                 rc = autostartConfigTokenizerReadNextLine(pCfgTokenizer);
     351                rc = utsConfigTokenizerReadNextLine(pCfgTokenizer);
    352352                if (RT_SUCCESS(rc))
    353                     rc = autostartConfigTokenizerCreateToken(pCfgTokenizer, NULL,
     353                    rc = utsConfigTokenizerCreateToken(pCfgTokenizer, NULL,
    354354                                                             &pCfgTokenizer->pTokenNext);
    355355            }
     
    365365    else if (   RT_FAILURE(rc)
    366366             && pCfgTokenizer)
    367         autostartConfigTokenizerDestroy(pCfgTokenizer);
     367        utsConfigTokenizerDestroy(pCfgTokenizer);
    368368
    369369    return rc;
     
    377377 * @param   ppCfgToken      Where to store the next token.
    378378 */
    379 static int autostartConfigTokenizerGetNextToken(PCFGTOKENIZER pCfgTokenizer,
     379static int utsConfigTokenizerGetNextToken(PCFGTOKENIZER pCfgTokenizer,
    380380                                                PCFGTOKEN *ppCfgToken)
    381381{
    382382    *ppCfgToken = pCfgTokenizer->pTokenNext;
    383     return autostartConfigTokenizerCreateToken(pCfgTokenizer, NULL, &pCfgTokenizer->pTokenNext);
     383    return utsConfigTokenizerCreateToken(pCfgTokenizer, NULL, &pCfgTokenizer->pTokenNext);
    384384}
    385385
     
    390390 * @param   enmType         Token type.
    391391 */
    392 static const char *autostartConfigTokenTypeToStr(CFGTOKENTYPE enmType)
     392static const char *utsConfigTokenTypeToStr(CFGTOKENTYPE enmType)
    393393{
    394394    switch (enmType)
     
    421421 * @param   pToken         Token.
    422422 */
    423 static const char *autostartConfigTokenToString(PCFGTOKEN pToken)
     423static const char *utsConfigTokenToString(PCFGTOKEN pToken)
    424424{
    425425    if (pToken->enmType == CFGTOKENTYPE_ID)
    426426        return pToken->u.Id.achToken;
    427427    else
    428         return autostartConfigTokenTypeToStr(pToken->enmType);
     428        return utsConfigTokenTypeToStr(pToken->enmType);
    429429}
    430430
     
    435435 * @param   pToken          Token.
    436436 */
    437 static size_t autostartConfigTokenGetLength(PCFGTOKEN pToken)
     437static size_t utsConfigTokenGetLength(PCFGTOKEN pToken)
    438438{
    439439    switch (pToken->enmType)
     
    463463 * @param   pToken          The token which caused the error.
    464464 * @param   pszExpected     String of the token which was expected.
    465  */
    466 static void autostartConfigTokenizerMsgUnexpectedToken(PCFGTOKEN pToken, const char *pszExpected)
    467 {
    468     autostartSvcLogError("Unexpected token '%s' at %d:%d.%d, expected '%s'",
    469                          autostartConfigTokenToString(pToken),
    470                          pToken->iLine, pToken->cchStart,
    471                          pToken->cchStart + autostartConfigTokenGetLength(pToken) - 1, pszExpected);
     465 * @param   ppErrInfo       Where to store the detailed error info.
     466 */
     467static void utsConfigTokenizerMsgUnexpectedToken(PCFGTOKEN pToken, const char *pszExpected,
     468                                                 PRTERRINFO *ppErrInfo)
     469{
     470    if (ppErrInfo)
     471    {
     472        PRTERRINFO pErrInfo = RTErrInfoAlloc(256);
     473        if (RT_LIKELY(pErrInfo))
     474        {
     475            RTErrInfoSetF(pErrInfo, VERR_INVALID_STATE, "Unexpected token '%s' at %d:%d.%d, expected '%s'",
     476                          utsConfigTokenToString(pToken),
     477                          pToken->iLine, pToken->cchStart,
     478                          pToken->cchStart + utsConfigTokenGetLength(pToken) - 1, pszExpected);
     479            *ppErrInfo = pErrInfo;
     480        }
     481    }
    472482}
    473483
     
    478488 * @param   pCfgTokenizer    The config tokenizer.
    479489 * @param   pszTokenCheck    The token to check for.
    480  */
    481 static int autostartConfigTokenizerCheckAndConsume(PCFGTOKENIZER pCfgTokenizer, CFGTOKENTYPE enmType)
     490 * @param   ppErrInfo        Where to store the detailed error info.
     491 */
     492static int utsConfigTokenizerCheckAndConsume(PCFGTOKENIZER pCfgTokenizer, CFGTOKENTYPE enmType,
     493                                             PRTERRINFO *ppErrInfo)
    482494{
    483495    int rc = VINF_SUCCESS;
    484496    PCFGTOKEN pCfgToken = NULL;
    485497
    486     rc = autostartConfigTokenizerGetNextToken(pCfgTokenizer, &pCfgToken);
     498    rc = utsConfigTokenizerGetNextToken(pCfgTokenizer, &pCfgToken);
    487499    if (RT_SUCCESS(rc))
    488500    {
    489501        if (pCfgToken->enmType != enmType)
    490502        {
    491             autostartConfigTokenizerMsgUnexpectedToken(pCfgToken, autostartConfigTokenTypeToStr(enmType));
     503            utsConfigTokenizerMsgUnexpectedToken(pCfgToken, utsConfigTokenTypeToStr(enmType), ppErrInfo);
    492504            rc = VERR_INVALID_PARAMETER;
    493505        }
    494506
    495         autostartConfigTokenFree(pCfgTokenizer, pCfgToken);
     507        utsConfigTokenFree(pCfgTokenizer, pCfgToken);
    496508    }
    497509    return rc;
     
    504516 * @param   pCfgTokenizer    Tokenizer instance data.
    505517 */
    506 static int autostartConfigTokenizerConsume(PCFGTOKENIZER pCfgTokenizer)
     518static int utsConfigTokenizerConsume(PCFGTOKENIZER pCfgTokenizer)
    507519{
    508520    int rc = VINF_SUCCESS;
    509521    PCFGTOKEN pCfgToken = NULL;
    510522
    511     rc = autostartConfigTokenizerGetNextToken(pCfgTokenizer, &pCfgToken);
     523    rc = utsConfigTokenizerGetNextToken(pCfgTokenizer, &pCfgToken);
    512524    if (RT_SUCCESS(rc))
    513         autostartConfigTokenFree(pCfgTokenizer, pCfgToken);
     525        utsConfigTokenFree(pCfgTokenizer, pCfgToken);
    514526
    515527    return rc;
     
    522534 * @param   pCfgTokenizer    Tokenizer instance data.
    523535 */
    524 DECLINLINE(PCFGTOKEN) autostartConfigTokenizerPeek(PCFGTOKENIZER pCfgTokenizer)
     536DECLINLINE(PCFGTOKEN) utsConfigTokenizerPeek(PCFGTOKENIZER pCfgTokenizer)
    525537{
    526538    return pCfgTokenizer->pTokenNext;
     
    534546 * @param   pszToken    The token to check for.
    535547 */
    536 DECLINLINE(bool) autostartConfigTokenizerPeekIsEqual(PCFGTOKENIZER pCfgTokenizer, CFGTOKENTYPE enmType)
    537 {
    538     PCFGTOKEN pToken = autostartConfigTokenizerPeek(pCfgTokenizer);
     548DECLINLINE(bool) utsConfigTokenizerPeekIsEqual(PCFGTOKENIZER pCfgTokenizer, CFGTOKENTYPE enmType)
     549{
     550    PCFGTOKEN pToken = utsConfigTokenizerPeek(pCfgTokenizer);
    539551    return pToken->enmType == enmType;
    540552}
     
    547559 * @param   pszKey           The key for the pair.
    548560 * @param   ppCfgAst         Where to store the resulting AST on success.
    549  */
    550 static int autostartConfigParseValue(PCFGTOKENIZER pCfgTokenizer, const char *pszKey,
    551                                      PCFGAST *ppCfgAst)
     561 * @param   ppErrInfo        Where to store the detailed error info.
     562 */
     563static int utsConfigParseValue(PCFGTOKENIZER pCfgTokenizer, const char *pszKey,
     564                               PCFGAST *ppCfgAst, PRTERRINFO *ppErrInfo)
    552565{
    553566    int rc = VINF_SUCCESS;
    554567    PCFGTOKEN pToken = NULL;
    555568
    556     rc = autostartConfigTokenizerGetNextToken(pCfgTokenizer, &pToken);
     569    rc = utsConfigTokenizerGetNextToken(pCfgTokenizer, &pToken);
    557570    if (   RT_SUCCESS(rc)
    558571        && pToken->enmType == CFGTOKENTYPE_ID)
     
    578591    else
    579592    {
    580         autostartConfigTokenizerMsgUnexpectedToken(pToken, "non reserved token");
     593        utsConfigTokenizerMsgUnexpectedToken(pToken, "non reserved token", ppErrInfo);
    581594        rc = VERR_INVALID_PARAMETER;
    582595    }
     
    593606 * @param   ppCfgAst         Where to store the resulting AST on success.
    594607 */
    595 static int autostartConfigParseCompoundNode(PCFGTOKENIZER pCfgTokenizer, const char *pszScopeId,
    596                                             PCFGAST *ppCfgAst)
     608static int utsConfigParseCompoundNode(PCFGTOKENIZER pCfgTokenizer, const char *pszScopeId,
     609                                      PCFGAST *ppCfgAst, PRTERRINFO *ppErrInfo)
    597610{
    598611    int rc = VINF_SUCCESS;
     
    619632        PCFGAST pAstNode = NULL;
    620633
    621         if (   autostartConfigTokenizerPeekIsEqual(pCfgTokenizer, CFGTOKENTYPE_CURLY_CLOSING)
    622             || autostartConfigTokenizerPeekIsEqual(pCfgTokenizer, CFGTOKENTYPE_EOF))
     634        if (   utsConfigTokenizerPeekIsEqual(pCfgTokenizer, CFGTOKENTYPE_CURLY_CLOSING)
     635            || utsConfigTokenizerPeekIsEqual(pCfgTokenizer, CFGTOKENTYPE_EOF))
    623636            break;
    624637
    625         rc = autostartConfigTokenizerGetNextToken(pCfgTokenizer, &pToken);
     638        rc = utsConfigTokenizerGetNextToken(pCfgTokenizer, &pToken);
    626639        if (   RT_SUCCESS(rc)
    627640            && pToken->enmType == CFGTOKENTYPE_ID)
    628641        {
    629642            /* Next must be a = token in all cases at this place. */
    630             rc = autostartConfigTokenizerCheckAndConsume(pCfgTokenizer, CFGTOKENTYPE_EQUAL);
     643            rc = utsConfigTokenizerCheckAndConsume(pCfgTokenizer, CFGTOKENTYPE_EQUAL, ppErrInfo);
    631644            if (RT_SUCCESS(rc))
    632645            {
    633646                /* Check whether this is a compound node. */
    634                 if (autostartConfigTokenizerPeekIsEqual(pCfgTokenizer, CFGTOKENTYPE_CURLY_OPEN))
     647                if (utsConfigTokenizerPeekIsEqual(pCfgTokenizer, CFGTOKENTYPE_CURLY_OPEN))
    635648                {
    636                     rc = autostartConfigTokenizerConsume(pCfgTokenizer);
     649                    rc = utsConfigTokenizerConsume(pCfgTokenizer);
    637650                    if (RT_SUCCESS(rc))
    638                         rc = autostartConfigParseCompoundNode(pCfgTokenizer, pToken->u.Id.achToken,
    639                                                               &pAstNode);
     651                        rc = utsConfigParseCompoundNode(pCfgTokenizer, pToken->u.Id.achToken,
     652                                                        &pAstNode, ppErrInfo);
    640653
    641654                    if (RT_SUCCESS(rc))
    642                         rc = autostartConfigTokenizerCheckAndConsume(pCfgTokenizer, CFGTOKENTYPE_CURLY_CLOSING);
     655                        rc = utsConfigTokenizerCheckAndConsume(pCfgTokenizer, CFGTOKENTYPE_CURLY_CLOSING, ppErrInfo);
    643656                }
    644657                else
    645                     rc = autostartConfigParseValue(pCfgTokenizer, pToken->u.Id.achToken,
    646                                                    &pAstNode);
     658                    rc = utsConfigParseValue(pCfgTokenizer, pToken->u.Id.achToken,
     659                                             &pAstNode, ppErrInfo);
    647660            }
    648661        }
    649662        else if (RT_SUCCESS(rc))
    650663        {
    651             autostartConfigTokenizerMsgUnexpectedToken(pToken, "non reserved token");
     664            utsConfigTokenizerMsgUnexpectedToken(pToken, "non reserved token", ppErrInfo);
    652665            rc = VERR_INVALID_PARAMETER;
    653666        }
     
    674687        }
    675688
    676         autostartConfigTokenFree(pCfgTokenizer, pToken);
     689        utsConfigTokenFree(pCfgTokenizer, pToken);
    677690
    678691    } while (RT_SUCCESS(rc));
     
    681694        *ppCfgAst = pCfgAst;
    682695    else
    683         autostartConfigAstDestroy(pCfgAst);
     696        utsConfigAstDestroy(pCfgAst);
    684697
    685698    return rc;
    686699}
    687700
    688 DECLHIDDEN(int) autostartParseConfig(const char *pszFilename, PCFGAST *ppCfgAst)
     701DECLHIDDEN(int) utsParseConfig(const char *pszFilename, PCFGAST *ppCfgAst, PRTERRINFO *ppErrInfo)
    689702{
    690703    PCFGTOKENIZER pCfgTokenizer = NULL;
     
    695708    AssertPtrReturn(ppCfgAst, VERR_INVALID_POINTER);
    696709
    697     rc = autostartConfigTokenizerCreate(pszFilename, &pCfgTokenizer);
     710    rc = utsConfigTokenizerCreate(pszFilename, &pCfgTokenizer);
    698711    if (RT_SUCCESS(rc))
    699712    {
    700         rc = autostartConfigParseCompoundNode(pCfgTokenizer, "", &pCfgAst);
     713        rc = utsConfigParseCompoundNode(pCfgTokenizer, "", &pCfgAst, ppErrInfo);
    701714        if (RT_SUCCESS(rc))
    702             rc = autostartConfigTokenizerCheckAndConsume(pCfgTokenizer, CFGTOKENTYPE_EOF);
     715            rc = utsConfigTokenizerCheckAndConsume(pCfgTokenizer, CFGTOKENTYPE_EOF, ppErrInfo);
    703716    }
    704717
    705718    if (pCfgTokenizer)
    706         autostartConfigTokenizerDestroy(pCfgTokenizer);
     719        utsConfigTokenizerDestroy(pCfgTokenizer);
    707720
    708721    if (RT_SUCCESS(rc))
     
    712725}
    713726
    714 DECLHIDDEN(void) autostartConfigAstDestroy(PCFGAST pCfgAst)
     727DECLHIDDEN(void) utsConfigAstDestroy(PCFGAST pCfgAst)
    715728{
    716729    AssertPtrReturnVoid(pCfgAst);
     
    726739        {
    727740            for (unsigned i = 0; i < pCfgAst->u.Compound.cAstNodes; i++)
    728                 autostartConfigAstDestroy(pCfgAst->u.Compound.apAstNodes[i]);
     741                utsConfigAstDestroy(pCfgAst->u.Compound.apAstNodes[i]);
    729742            RTMemFree(pCfgAst);
    730743            break;
     
    736749}
    737750
    738 DECLHIDDEN(PCFGAST) autostartConfigAstGetByName(PCFGAST pCfgAst, const char *pszName)
     751DECLHIDDEN(PCFGAST) utsConfigAstGetByName(PCFGAST pCfgAst, const char *pszName)
    739752{
    740753    if (!pCfgAst)
  • trunk/src/VBox/ValidationKit/utils/usb/UsbTestServiceProtocol.h

    r60279 r60287  
    7979#define UTSPKT_OPCODE_HOWDY             "HOWDY   "
    8080
     81/** 32bit protocol version consisting of a 16bit major and 16bit minor part. */
     82#define UTS_PROTOCOL_VS (UTS_PROTOCOL_VS_MAJOR | UTS_PROTOCOL_VS_MINOR)
     83/** The major version part of the protocol version. */
     84#define UTS_PROTOCOL_VS_MAJOR (1 << 16)
     85/** The minor version part of the protocol version. */
     86#define UTS_PROTOCOL_VS_MINOR (0)
     87
    8188/**
    8289 * The HOWDY request structure.
     
    96103} UTSPKTREQHOWDY;
    97104AssertCompileSizeAlignment(UTSPKTREQHOWDY, UTSPKT_ALIGNMENT);
     105/** Pointer to a HOWDY request structure. */
     106typedef UTSPKTREQHOWDY *PUTSPKTREQHOWDY;
    98107
    99108/**
     
    122131} UTSPKTREPHOWDY;
    123132AssertCompileSizeAlignment(UTSPKTREPHOWDY, UTSPKT_ALIGNMENT);
     133/** Pointer to a HOWDY reply structure. */
     134typedef UTSPKTREPHOWDY *PUTSPKTREPHOWDY;
    124135
    125136/** Connections over USB/IP are supported. */
     
    150161} UTSPKTREQGDGTDTOR;
    151162AssertCompileSizeAlignment(UTSPKTREQGDGTDTOR, UTSPKT_ALIGNMENT);
     163/** Pointer to a GADGET DESTROY structure. */
     164typedef UTSPKTREQGDGTDTOR *PUTSPKTREQGDGTDTOR;
    152165
    153166/* No additional structure for the reply (just standard STATUS packet). */
     
    168181} UTSPKTREQGDGTCNCT;
    169182AssertCompileSizeAlignment(UTSPKTREQGDGTCNCT, UTSPKT_ALIGNMENT);
     183/** Pointer to a GADGET CONNECT request structure. */
     184typedef UTSPKTREQGDGTCNCT *PUTSPKTREQGDGTCNCT;
    170185
    171186/* No additional structure for the reply (just standard STATUS packet). */
     
    174189
    175190/**
    176  * The GADGET CONNECT request structure.
     191 * The GADGET DISCONNECT request structure.
    177192 */
    178193typedef struct UTSPKTREQGDGTDCNT
     
    186201} UTSPKTREQGDGTDCNT;
    187202AssertCompileSizeAlignment(UTSPKTREQGDGTDCNT, UTSPKT_ALIGNMENT);
     203/** Pointer to a GADGET CONNECT request structure. */
     204typedef UTSPKTREQGDGTDCNT *PUTSPKTREQGDGTDCNT;
    188205
    189206/* No additional structure for the reply (just standard STATUS packet). */
    190207
     208/**
     209 * Checks if the two opcodes match.
     210 *
     211 * @returns true on match, false on mismatch.
     212 * @param   pPktHdr             The packet header.
     213 * @param   pszOpcode2          The opcode we're comparing with.  Does not have
     214 *                              to be the whole 8 chars long.
     215 */
     216DECLINLINE(bool) utsIsSameOpcode(PCUTSPKTHDR pPktHdr, const char *pszOpcode2)
     217{
     218    if (pPktHdr->achOpcode[0] != pszOpcode2[0])
     219        return false;
     220    if (pPktHdr->achOpcode[1] != pszOpcode2[1])
     221        return false;
     222
     223    unsigned i = 2;
     224    while (   i < RT_SIZEOFMEMB(UTSPKTHDR, achOpcode)
     225           && pszOpcode2[i] != '\0')
     226    {
     227        if (pPktHdr->achOpcode[i] != pszOpcode2[i])
     228            break;
     229        i++;
     230    }
     231
     232    if (   i < RT_SIZEOFMEMB(UTSPKTHDR, achOpcode)
     233        && pszOpcode2[i] == '\0')
     234    {
     235        while (   i < RT_SIZEOFMEMB(UTSPKTHDR, achOpcode)
     236               && pPktHdr->achOpcode[i] == ' ')
     237            i++;
     238    }
     239
     240    return i == RT_SIZEOFMEMB(UTSPKTHDR, achOpcode);
     241}
     242
     243/**
     244 * Converts a UTS request packet from host to network byte ordering.
     245 *
     246 * @returns nothing.
     247 * @param   pPktHdr           The packet to convert.
     248 */
     249DECLHIDDEN(void) utsProtocolReqH2N(PUTSPKTHDR pPktHdr);
     250
     251/**
     252 * Converts a UTS request packet from network to host byte ordering.
     253 *
     254 * @returns nothing.
     255 * @param   pPktHdr           The packet to convert.
     256 */
     257DECLHIDDEN(void) utsProtocolReqN2H(PUTSPKTHDR pPktHdr);
     258
     259/**
     260 * Converts a UTS reply packet from host to network byte ordering.
     261 *
     262 * @returns nothing.
     263 * @param   pPktHdr           The packet to convert.
     264 */
     265DECLHIDDEN(void) utsProtocolRepH2N(PUTSPKTHDR pPktHdr);
     266
     267/**
     268 * Converts a UTS reply packet from network to host byte ordering.
     269 *
     270 * @returns nothing.
     271 * @param   pPktHdr           The packet to convert.
     272 */
     273DECLHIDDEN(void) utsProtocolRepN2H(PUTSPKTHDR pPktHdr);
     274
    191275RT_C_DECLS_END
    192276
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette