VirtualBox

Ignore:
Timestamp:
Apr 1, 2016 12:49:19 PM (9 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
106330
Message:

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

File:
1 edited

Legend:

Unmodified
Added
Removed
  • 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);
Note: See TracChangeset for help on using the changeset viewer.

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