VirtualBox

Changeset 60417 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Apr 11, 2016 10:37:04 AM (9 years ago)
Author:
vboxsync
Message:

ValidationKit/sb/UsbTestService: Updates, implement more requests

Location:
trunk/src/VBox/ValidationKit/utils/usb
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/ValidationKit/utils/usb/UsbTestService.cpp

    r60287 r60417  
    5555#include <iprt/thread.h>
    5656
     57#include "UsbTestServiceCfg.h"
    5758#include "UsbTestServiceInternal.h"
    58 #include "UsbTestServiceCfg.h"
     59#include "UsbTestServiceGadget.h"
    5960
    6061
     
    6364*   Structures and Typedefs                                                                                                      *
    6465*********************************************************************************************************************************/
     66
     67#define UTS_USBIP_PORT_FIRST 3240
     68#define UTS_USBIP_PORT_LAST  3340
    6569
    6670/**
     
    9498    /** Client hostname. */
    9599    char                  *pszHostname;
     100    /** Gadget host handle. */
     101    UTSGADGETHOST          hGadgetHost;
     102    /** Handle fo the current configured gadget. */
     103    UTSGADGET              hGadget;
    96104} UTSCLIENT;
    97105/** Pointer to a UTS client instance. */
     
    115123/** The select transport layer. */
    116124static PCUTSTRANSPORT       g_pTransport;
    117 /** The scratch path. */
     125/** The config path. */
    118126static char                 g_szCfgPath[RTPATH_MAX];
    119127/** The scratch path. */
     
    154162/** List of new clients waiting to be picked up by the client worker thread. */
    155163static RTLISTANCHOR         g_LstClientsNew;
     164/** First USB/IP port we can use. */
     165static uint16_t             g_uUsbIpPortFirst = UTS_USBIP_PORT_FIRST;
     166/** Last USB/IP port we can use. */
     167static uint16_t             g_uUsbIpPortLast  = UTS_USBIP_PORT_LAST;
     168/** Next free port. */
     169static uint16_t             g_uUsbIpPortNext  = UTS_USBIP_PORT_FIRST;
    156170
    157171
     
    527541
    528542/**
     543 * Creates the configuration from the given GADGET CREATE packet.
     544 *
     545 * @returns IPRT status code.
     546 * @param   pReq                The gadget create request.
     547 * @param   paCfg               The array of configuration items.
     548 */
     549static int utsDoGadgetCreateFillCfg(PUTSPKTREQGDGTCTOR pReq, PUTSGADGETCFGITEM paCfg)
     550{
     551    return VERR_NOT_IMPLEMENTED;
     552}
     553
     554/**
    529555 * Verifies and acknowledges a "BYE" request.
    530556 *
     
    553579static int utsDoHowdy(PUTSCLIENT pClient, PCUTSPKTHDR pPktHdr)
    554580{
     581    int rc = VINF_SUCCESS;
     582
    555583    if (pPktHdr->cb != sizeof(UTSPKTREQHOWDY))
    556584        return utsReplyBadSize(pClient, pPktHdr, sizeof(UTSPKTREQHOWDY));
     
    576604        return utsReplyRC(pClient, pPktHdr, VERR_NO_MEMORY, "Failed to alllocate memory for the hostname string");
    577605
    578     int rc = utsReplyAck(pClient, pPktHdr);
     606    if (pReq->fUsbConn & UTSPKT_HOWDY_CONN_F_PHYSICAL)
     607        return utsReplyRC(pClient, pPktHdr, VERR_NOT_SUPPORTED, "Physical connections are not yet supported");
     608
     609    if (pReq->fUsbConn & UTSPKT_HOWDY_CONN_F_USBIP)
     610    {
     611        /* Set up the USB/IP server, find an unused port we can start the server on. */
     612        UTSGADGETCFGITEM aCfg[2];
     613
     614        uint16_t uPort = g_uUsbIpPortNext;
     615
     616        if (g_uUsbIpPortNext == g_uUsbIpPortLast)
     617            g_uUsbIpPortNext = g_uUsbIpPortFirst;
     618        else
     619            g_uUsbIpPortNext++;
     620
     621        aCfg[0].pszKey      = "UsbIp/Port";
     622        aCfg[0].Val.enmType = UTSGADGETCFGTYPE_UINT16;
     623        aCfg[0].Val.u.u16   = uPort;
     624        aCfg[1].pszKey      = NULL;
     625
     626        rc = utsGadgetHostCreate(UTSGADGETHOSTTYPE_USBIP, &aCfg[0], &pClient->hGadgetHost);
     627        if (RT_SUCCESS(rc))
     628        {
     629            /* Send the reply with the configured USB/IP port. */
     630            UTSPKTREPHOWDY Rep;
     631
     632            RT_ZERO(Rep);
     633
     634            Rep.uVersion         = UTS_PROTOCOL_VS;
     635            Rep.fUsbConn         = UTSPKT_HOWDY_CONN_F_USBIP;
     636            Rep.uUsbIpPort       = uPort;
     637            Rep.cUsbIpDevices    = 1;
     638            Rep.cPhysicalDevices = 0;
     639
     640            rc = utsReplyInternal(pClient, &Rep.Sts, "ACK     ", sizeof(Rep) - sizeof(UTSPKTSTS));
     641            if (RT_SUCCESS(rc))
     642            {
     643                g_pTransport->pfnNotifyHowdy(pClient->pTransportClient);
     644                pClient->enmState = UTSCLIENTSTATE_READY;
     645                RTDirRemoveRecursive(g_szScratchPath, RTDIRRMREC_F_CONTENT_ONLY);
     646            }
     647        }
     648        else
     649            return utsReplyRC(pClient, pPktHdr, rc, "Creating the USB/IP gadget host failed");
     650    }
     651    else
     652        return utsReplyRC(pClient, pPktHdr, VERR_INVALID_PARAMETER, "No access method requested");
     653
     654    return rc;
     655}
     656
     657/**
     658 * Verifies and processes a "GADGET CREATE" request.
     659 *
     660 * @returns IPRT status code.
     661 * @param   pClient             The UTS client structure.
     662 * @param   pPktHdr             The gadget create packet.
     663 */
     664static int utsDoGadgetCreate(PUTSCLIENT pClient, PCUTSPKTHDR pPktHdr)
     665{
     666    int rc = VINF_SUCCESS;
     667
     668    if (pPktHdr->cb < sizeof(UTSPKTREQGDGTCTOR))
     669        return utsReplyBadSize(pClient, pPktHdr, sizeof(UTSPKTREQGDGTCTOR));
     670
     671    if (   pClient->enmState != UTSCLIENTSTATE_READY
     672        || pClient->hGadgetHost == NIL_UTSGADGETHOST)
     673        return utsReplyInvalidState(pClient, pPktHdr);
     674
     675    PUTSPKTREQGDGTCTOR pReq = (PUTSPKTREQGDGTCTOR)pPktHdr;
     676
     677    if (pReq->u32GdgtType != UTSPKT_GDGT_CREATE_TYPE_TEST)
     678        return utsReplyRC(pClient, pPktHdr, VERR_INVALID_PARAMETER, "The given gadget type is not supported");
     679
     680    if (pReq->u32GdgtAccess != UTSPKT_GDGT_CREATE_ACCESS_USBIP)
     681        return utsReplyRC(pClient, pPktHdr, VERR_INVALID_PARAMETER, "The given gadget access method is not supported");
     682
     683    PUTSGADGETCFGITEM paCfg = NULL;
     684    if (pReq->u32CfgItems > 0)
     685    {
     686        paCfg = (PUTSGADGETCFGITEM)RTMemAllocZ((pReq->u32CfgItems + 1) * sizeof(UTSGADGETCFGITEM));
     687        if (RT_UNLIKELY(!paCfg))
     688            return utsReplyRC(pClient, pPktHdr, VERR_NO_MEMORY, "Failed to allocate memory for configration items");
     689
     690        rc = utsDoGadgetCreateFillCfg(pReq, paCfg);
     691        if (RT_FAILURE(rc))
     692        {
     693            RTMemFree(paCfg);
     694            return utsReplyRC(pClient, pPktHdr, rc, "Failed to parse configuration");
     695        }
     696    }
     697
     698    rc = utsGadgetCreate(pClient->hGadgetHost, UTSGADGETCLASS_TEST, paCfg, &pClient->hGadget);
    579699    if (RT_SUCCESS(rc))
    580700    {
    581         g_pTransport->pfnNotifyHowdy(pClient->pTransportClient);
    582         RTDirRemoveRecursive(g_szScratchPath, RTDIRRMREC_F_CONTENT_ONLY);
     701        UTSPKTREPGDGTCTOR Rep;
     702        RT_ZERO(Rep);
     703
     704        Rep.idGadget = 0;
     705        rc = utsReplyInternal(pClient, &Rep.Sts, "ACK     ", sizeof(Rep) - sizeof(UTSPKTSTS));
    583706    }
     707    else
     708        rc = utsReplyRC(pClient, pPktHdr, rc, "Failed to create gadget with %Rrc\n", rc);
     709
     710    return rc;
     711}
     712
     713/**
     714 * Verifies and processes a "GADGET DESTROY" request.
     715 *
     716 * @returns IPRT status code.
     717 * @param   pClient             The UTS client structure.
     718 * @param   pPktHdr             The gadget destroy packet.
     719 */
     720static int utsDoGadgetDestroy(PUTSCLIENT pClient, PCUTSPKTHDR pPktHdr)
     721{
     722    if (pPktHdr->cb != sizeof(UTSPKTREQGDGTDTOR))
     723        return utsReplyBadSize(pClient, pPktHdr, sizeof(UTSPKTREQGDGTDTOR));
     724
     725    if (   pClient->enmState != UTSCLIENTSTATE_READY
     726        || pClient->hGadgetHost == NIL_UTSGADGETHOST)
     727        return utsReplyInvalidState(pClient, pPktHdr);
     728
     729    PUTSPKTREQGDGTDTOR pReq = (PUTSPKTREQGDGTDTOR)pPktHdr;
     730
     731    if (pReq->idGadget != 0)
     732        return utsReplyRC(pClient, pPktHdr, VERR_INVALID_HANDLE, "The given gadget handle is invalid");
     733    if (pClient->hGadget == NIL_UTSGADGET)
     734        return utsReplyRC(pClient, pPktHdr, VERR_INVALID_STATE, "The gadget is not set up");
     735
     736    utsGadgetRelease(pClient->hGadget);
     737    pClient->hGadget = NIL_UTSGADGET;
     738
     739    return utsReplyAck(pClient, pPktHdr);
     740}
     741
     742/**
     743 * Verifies and processes a "GADGET CONNECT" request.
     744 *
     745 * @returns IPRT status code.
     746 * @param   pClient             The UTS client structure.
     747 * @param   pPktHdr             The gadget connect packet.
     748 */
     749static int utsDoGadgetConnect(PUTSCLIENT pClient, PCUTSPKTHDR pPktHdr)
     750{
     751    if (pPktHdr->cb != sizeof(UTSPKTREQGDGTCNCT))
     752        return utsReplyBadSize(pClient, pPktHdr, sizeof(UTSPKTREQGDGTCNCT));
     753
     754    if (   pClient->enmState != UTSCLIENTSTATE_READY
     755        || pClient->hGadgetHost == NIL_UTSGADGETHOST)
     756        return utsReplyInvalidState(pClient, pPktHdr);
     757
     758    PUTSPKTREQGDGTCNCT pReq = (PUTSPKTREQGDGTCNCT)pPktHdr;
     759
     760    if (pReq->idGadget != 0)
     761        return utsReplyRC(pClient, pPktHdr, VERR_INVALID_HANDLE, "The given gadget handle is invalid");
     762    if (pClient->hGadget == NIL_UTSGADGET)
     763        return utsReplyRC(pClient, pPktHdr, VERR_INVALID_STATE, "The gadget is not set up");
     764
     765    int rc = utsGadgetConnect(pClient->hGadget);
     766    if (RT_SUCCESS(rc))
     767        rc = utsReplyAck(pClient, pPktHdr);
     768    else
     769        rc = utsReplyRC(pClient, pPktHdr, rc, "Failed to connect the gadget");
     770
     771    return rc;
     772}
     773
     774/**
     775 * Verifies and processes a "GADGET DISCONNECT" request.
     776 *
     777 * @returns IPRT status code.
     778 * @param   pClient             The UTS client structure.
     779 * @param   pPktHdr             The gadget disconnect packet.
     780 */
     781static int utsDoGadgetDisconnect(PUTSCLIENT pClient, PCUTSPKTHDR pPktHdr)
     782{
     783    if (pPktHdr->cb != sizeof(UTSPKTREQGDGTDCNT))
     784        return utsReplyBadSize(pClient, pPktHdr, sizeof(UTSPKTREQGDGTDCNT));
     785
     786    if (   pClient->enmState != UTSCLIENTSTATE_READY
     787        || pClient->hGadgetHost == NIL_UTSGADGETHOST)
     788        return utsReplyInvalidState(pClient, pPktHdr);
     789
     790    PUTSPKTREQGDGTDCNT pReq = (PUTSPKTREQGDGTDCNT)pPktHdr;
     791
     792    if (pReq->idGadget != 0)
     793        return utsReplyRC(pClient, pPktHdr, VERR_INVALID_HANDLE, "The given gadget handle is invalid");
     794    if (pClient->hGadget == NIL_UTSGADGET)
     795        return utsReplyRC(pClient, pPktHdr, VERR_INVALID_STATE, "The gadget is not set up");
     796
     797    int rc = utsGadgetDisconnect(pClient->hGadget);
     798    if (RT_SUCCESS(rc))
     799        rc = utsReplyAck(pClient, pPktHdr);
     800    else
     801        rc = utsReplyRC(pClient, pPktHdr, rc, "Failed to disconnect the gadget");
     802
    584803    return rc;
    585804}
     
    609828    else if (utsIsSameOpcode(pPktHdr, UTSPKT_OPCODE_BYE))
    610829        rc = utsDoBye(pClient, pPktHdr);
     830    /* Gadget API. */
     831    else if (utsIsSameOpcode(pPktHdr, UTSPKT_OPCODE_GADGET_CREATE))
     832        rc = utsDoGadgetCreate(pClient, pPktHdr);
     833    else if (utsIsSameOpcode(pPktHdr, UTSPKT_OPCODE_GADGET_DESTROY))
     834        rc = utsDoGadgetCreate(pClient, pPktHdr);
     835    else if (utsIsSameOpcode(pPktHdr, UTSPKT_OPCODE_GADGET_CONNECT))
     836        rc = utsDoGadgetConnect(pClient, pPktHdr);
     837    else if (utsIsSameOpcode(pPktHdr, UTSPKT_OPCODE_GADGET_DISCONNECT))
     838        rc = utsDoGadgetDisconnect(pClient, pPktHdr);
    611839    /* Misc: */
    612840    else
     
    628856    if (pClient->pszHostname)
    629857        RTStrFree(pClient->pszHostname);
     858    if (pClient->hGadget != NIL_UTSGADGET)
     859        utsGadgetRelease(pClient->hGadget);
     860    if (pClient->hGadgetHost != NIL_UTSGADGETHOST)
     861        utsGadgetHostRelease(pClient->hGadgetHost);
    630862    RTMemFree(pClient);
    631863}
     
    7681000            pClient->enmState         = UTSCLIENTSTATE_INITIALISING;
    7691001            pClient->pTransportClient = pTransportClient;
     1002            pClient->pszHostname      = NULL;
     1003            pClient->hGadgetHost      = NIL_UTSGADGETHOST;
     1004            pClient->hGadget          = NIL_UTSGADGET;
    7701005        }
    7711006        else
  • trunk/src/VBox/ValidationKit/utils/usb/UsbTestServiceGadget.cpp

    r60375 r60417  
    144144}
    145145
     146
     147DECLHIDDEN(int) utsGadgetConnect(UTSGADGET hGadget)
     148{
     149    PUTSGADGETINT pThis = hGadget;
     150
     151    AssertPtrReturn(pThis, 0);
     152    return VERR_NOT_IMPLEMENTED;
     153}
     154
     155
     156DECLHIDDEN(int) utsGadgetDisconnect(UTSGADGET hGadget)
     157{
     158    PUTSGADGETINT pThis = hGadget;
     159
     160    AssertPtrReturn(pThis, 0);
     161    return VERR_NOT_IMPLEMENTED;
     162}
     163
  • trunk/src/VBox/ValidationKit/utils/usb/UsbTestServiceGadget.h

    r60324 r60417  
    7676    /** Signed 64bit integer. */
    7777    UTSGADGETCFGTYPE_INT64,
     78    /** 32bit hack. */
    7879    UTSGADGETCFGTYPE_32BIT_HACK = 0x7fffffff
    7980} UTSGADGETCFGTYPE;
  • trunk/src/VBox/ValidationKit/utils/usb/UsbTestServiceProtocol.h

    r60287 r60417  
    146146
    147147#define UTSPKT_OPCODE_GADGET_CREATE     "GDGTCRT "
     148
     149/**
     150 * The GADGET CREATE request structure.
     151 */
     152typedef struct UTSPKTREQGDGTCTOR
     153{
     154    /** Embedded packet header. */
     155    UTSPKTHDR       Hdr;
     156    /** Gadget type. */
     157    uint32_t        u32GdgtType;
     158    /** Access methods. */
     159    uint32_t        u32GdgtAccess;
     160    /** Number of config items - following this structure. */
     161    uint32_t        u32CfgItems;
     162    /** Reserved. */
     163    uint32_t        u32Rsvd0;
     164} UTSPKTREQGDGTCTOR;
     165AssertCompileSizeAlignment(UTSPKTREQGDGTCTOR, UTSPKT_ALIGNMENT);
     166/** Pointer to a GADGET CREATE structure. */
     167typedef UTSPKTREQGDGTCTOR *PUTSPKTREQGDGTCTOR;
     168
     169/** Gadget type - Test device. */
     170#define UTSPKT_GDGT_CREATE_TYPE_TEST UINT32_C(0x1)
     171
     172/** Gadget acess method - USB/IP. */
     173#define UTSPKT_GDGT_CREATE_ACCESS_USBIP UINT32_C(0x1)
     174
     175/**
     176 * Configuration item.
     177 */
     178typedef struct UTSPKTREQGDGTCTORCFGITEM
     179{
     180    /** Size of the key incuding termination in bytes. */
     181    uint32_t        u32KeySize;
     182    /** Item type. */
     183    uint32_t        u32Type;
     184    /** Size of the value string including termination in bytes. */
     185    uint32_t        u32ValSize;
     186    /** Reserved. */
     187    uint32_t        u32Rsvd0;
     188} UTSPKTREQGDGTCTORCFGITEM;
     189AssertCompileSizeAlignment(UTSPKTREQGDGTCTORCFGITEM, UTSPKT_ALIGNMENT);
     190/** Pointer to a configuration item. */
     191typedef UTSPKTREQGDGTCTORCFGITEM *PUTSPKTREQGDGTCTORCFGITEM;
     192
     193/** Boolean configuration item type. */
     194#define UTSPKT_GDGT_CFG_ITEM_TYPE_BOOLEAN UINT32_C(1)
     195/** String configuration item type. */
     196#define UTSPKT_GDGT_CFG_ITEM_TYPE_STRING  UINT32_C(2)
     197/** Unsigned 8-bit integer configuration item type. */
     198#define UTSPKT_GDGT_CFG_ITEM_TYPE_UINT8   UINT32_C(3)
     199/** Unsigned 16-bit integer configuration item type. */
     200#define UTSPKT_GDGT_CFG_ITEM_TYPE_UINT16  UINT32_C(4)
     201/** Unsigned 32-bit integer configuration item type. */
     202#define UTSPKT_GDGT_CFG_ITEM_TYPE_UINT32  UINT32_C(5)
     203/** Unsigned 64-bit integer configuration item type. */
     204#define UTSPKT_GDGT_CFG_ITEM_TYPE_UINT64  UINT32_C(6)
     205/** Signed 8-bit integer configuration item type. */
     206#define UTSPKT_GDGT_CFG_ITEM_TYPE_INT8    UINT32_C(7)
     207/** Signed 16-bit integer configuration item type. */
     208#define UTSPKT_GDGT_CFG_ITEM_TYPE_INT16   UINT32_C(8)
     209/** Signed 32-bit integer configuration item type. */
     210#define UTSPKT_GDGT_CFG_ITEM_TYPE_INT32   UINT32_C(9)
     211/** Signed 64-bit integer configuration item type. */
     212#define UTSPKT_GDGT_CFG_ITEM_TYPE_INT64   UINT32_C(10)
     213
     214/**
     215 * The GADGET CREATE reply structure.
     216 */
     217typedef struct UTSPKTREPGDGTCTOR
     218{
     219    /** Status packet. */
     220    UTSPKTSTS       Sts;
     221    /** The gadget ID on success. */
     222    uint32_t        idGadget;
     223    /** Padding - reserved. */
     224    uint8_t         au8Padding[12];
     225} UTSPKTREPGDGTCTOR;
     226AssertCompileSizeAlignment(UTSPKTREPGDGTCTOR, UTSPKT_ALIGNMENT);
     227/** Pointer to a GADGET CREATE structure. */
     228typedef UTSPKTREPGDGTCTOR *PUTSPKTREPGDGTCTOR;
     229
     230
    148231#define UTSPKT_OPCODE_GADGET_DESTROY    "GDGTDTOR"
    149232
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