VirtualBox

Changeset 60517 in vbox for trunk/src/VBox/ValidationKit


Ignore:
Timestamp:
Apr 15, 2016 12:20:51 PM (9 years ago)
Author:
vboxsync
Message:

ValidationKit/usb: Updates for UsbTestService

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

Legend:

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

    r60375 r60517  
    5252        UsbTestServiceProtocol.cpp \
    5353        UsbTestServiceTcp.cpp
     54UsbTestService_SOURCES.linux = \
     55        UsbTestServicePlatform-linux.cpp
    5456
    5557$(evalcall def_vbox_validationkit_process_python_sources)
  • trunk/src/VBox/ValidationKit/utils/usb/UsbTestService.cpp

    r60493 r60517  
    5858#include "UsbTestServiceInternal.h"
    5959#include "UsbTestServiceGadget.h"
     60#include "UsbTestServicePlatform.h"
    6061
    6162
     
    10451046    if (RT_SUCCESS(rc))
    10461047    {
    1047         rc = RTCritSectInit(&g_CritSectClients);
     1048        rc = utsPlatformInit();
    10481049        if (RT_SUCCESS(rc))
    10491050        {
    1050             rc = RTPipeCreate(&g_hPipeR, &g_hPipeW, 0);
     1051            rc = RTCritSectInit(&g_CritSectClients);
    10511052            if (RT_SUCCESS(rc))
    10521053            {
    1053                 /* Spin off the thread serving connections. */
    1054                 rc = RTThreadCreate(&g_hThreadServing, utsClientWorker, NULL, 0, RTTHREADTYPE_IO, RTTHREADFLAGS_WAITABLE,
    1055                                     "USBTSTSRV");
     1054                rc = RTPipeCreate(&g_hPipeR, &g_hPipeW, 0);
    10561055                if (RT_SUCCESS(rc))
    1057                     return VINF_SUCCESS;
     1056                {
     1057                    /* Spin off the thread serving connections. */
     1058                    rc = RTThreadCreate(&g_hThreadServing, utsClientWorker, NULL, 0, RTTHREADTYPE_IO, RTTHREADFLAGS_WAITABLE,
     1059                                        "USBTSTSRV");
     1060                    if (RT_SUCCESS(rc))
     1061                        return VINF_SUCCESS;
     1062                    else
     1063                        RTMsgError("Creating the client worker thread failed with %Rrc\n", rc);
     1064
     1065                    RTPipeClose(g_hPipeR);
     1066                    RTPipeClose(g_hPipeW);
     1067                }
    10581068                else
    1059                     RTMsgError("Creating the client worker thread failed with %Rrc\n", rc);
    1060 
    1061                 RTPipeClose(g_hPipeR);
    1062                 RTPipeClose(g_hPipeW);
     1069                    RTMsgError("Creating communications pipe failed with %Rrc\n", rc);
     1070
     1071                RTCritSectDelete(&g_CritSectClients);
    10631072            }
    10641073            else
    1065                 RTMsgError("Creating communications pipe failed with %Rrc\n", rc);
    1066 
    1067             RTCritSectDelete(&g_CritSectClients);
     1074                RTMsgError("Creating global critical section failed with %Rrc\n", rc);
     1075
     1076            utsConfigAstDestroy(g_pCfgAst);
    10681077        }
    10691078        else
    1070             RTMsgError("Creating global critical section failed with %Rrc\n", rc);
    1071 
    1072         utsConfigAstDestroy(g_pCfgAst);
    1073     }
    1074     else
    1075     {
    1076         if (RTErrInfoIsSet(pErrInfo))
    10771079        {
    1078             RTMsgError("Failed to parse config with detailed error: %s (%Rrc)\n",
    1079                        pErrInfo->pszMsg, pErrInfo->rc);
    1080             RTErrInfoFree(pErrInfo);
     1080            if (RTErrInfoIsSet(pErrInfo))
     1081            {
     1082                RTMsgError("Failed to parse config with detailed error: %s (%Rrc)\n",
     1083                           pErrInfo->pszMsg, pErrInfo->rc);
     1084                RTErrInfoFree(pErrInfo);
     1085            }
     1086            else
     1087                RTMsgError("Faield to parse config with unknown error (%Rrc)\n", rc);
     1088            return rc;
    10811089        }
    1082         else
    1083             RTMsgError("Faield to parse config with unknown error (%Rrc)\n", rc);
    1084         return rc;
    10851090    }
    10861091
     
    14251430    g_pTransport->pfnTerm();
    14261431
     1432    utsPlatformTerm();
     1433
    14271434    return rcExit;
    14281435}
  • trunk/src/VBox/ValidationKit/utils/usb/UsbTestServiceGadget.cpp

    r60417 r60517  
    107107            rc = pClassIf->pfnInit((PUTSGADGETCLASSINT)&pThis->abClassInst[0], paCfg);
    108108            if (RT_SUCCESS(rc))
    109                 *phGadget = pThis;
     109            {
     110                /* Connect the gadget to the host. */
     111                rc = utsGadgetHostGadgetConnect(pThis->hGadgetHost, pThis);
     112                if (RT_SUCCESS(rc))
     113                    *phGadget = pThis;
     114            }
    110115            else
    111116                RTMemFree(pThis);
     
    145150
    146151
     152DECLHIDDEN(uint32_t) utsGadgetGetBusId(UTSGADGET hGadget)
     153{
     154    PUTSGADGETINT pThis = hGadget;
     155
     156    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
     157    return pThis->pClassIf->pfnGetBusId((PUTSGADGETCLASSINT)&pThis->abClassInst[0]);
     158}
     159
     160
     161DECLHIDDEN(uint32_t) utsGadgetGetDevId(UTSGADGET hGadget)
     162{
     163    PUTSGADGETINT pThis = hGadget;
     164
     165    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
     166    return 1; /** @todo: Current assumption which is true on Linux with dummy_hcd. */
     167}
     168
     169
    147170DECLHIDDEN(int) utsGadgetConnect(UTSGADGET hGadget)
    148171{
    149172    PUTSGADGETINT pThis = hGadget;
    150173
    151     AssertPtrReturn(pThis, 0);
    152     return VERR_NOT_IMPLEMENTED;
     174    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
     175    int rc = pThis->pClassIf->pfnConnect((PUTSGADGETCLASSINT)&pThis->abClassInst[0]);
     176    if (RT_SUCCESS(rc))
     177        rc = utsGadgetHostGadgetConnect(pThis->hGadgetHost, hGadget);
     178
     179    return rc;
    153180}
    154181
     
    158185    PUTSGADGETINT pThis = hGadget;
    159186
    160     AssertPtrReturn(pThis, 0);
    161     return VERR_NOT_IMPLEMENTED;
     187    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
     188    int rc = utsGadgetHostGadgetDisconnect(pThis->hGadgetHost, hGadget);
     189    if (RT_SUCCESS(rc))
     190        rc = pThis->pClassIf->pfnDisconnect((PUTSGADGETCLASSINT)&pThis->abClassInst[0]);
     191
     192    return rc;
    162193}
    163194
  • trunk/src/VBox/ValidationKit/utils/usb/UsbTestServiceGadget.h

    r60417 r60517  
    401401 * @param   paCfg             Additional configuration parameters - optional.
    402402 *                            The array must be terminated with a NULL entry.
    403  * @param   phGadgetHost      Where to store the handle to the gadget host on success.             
     403 * @param   phGadgetHost      Where to store the handle to the gadget host on success.
    404404 */
    405405DECLHIDDEN(int) utsGadgetHostCreate(UTSGADGETHOSTTYPE enmType, PCUTSGADGETCFGITEM paCfg,
     
    430430 */
    431431DECLHIDDEN(PCUTSGADGETCFGITEM) utsGadgetHostGetCfg(UTSGADGETHOST hGadgetHost);
     432
     433/**
     434 * Connects the given gadget to the host.
     435 *
     436 * @returns IPRT status code.
     437 * @param   hGadgetHost       The gadget host handle.
     438 * @param   hGadget           The gadget handle.
     439 */
     440DECLHIDDEN(int) utsGadgetHostGadgetConnect(UTSGADGETHOST hGadgetHost, UTSGADGET hGadget);
     441
     442/**
     443 * Disconnects the given gadget from the host.
     444 *
     445 * @returns IPRT status code.
     446 * @param   hGadgetHost       The gadget host handle.
     447 * @param   hGadget           The gadget handle.
     448 */
     449DECLHIDDEN(int) utsGadgetHostGadgetDisconnect(UTSGADGETHOST hGadgetHost, UTSGADGET hGadget);
    432450
    433451/**
     
    477495
    478496/**
     497 * Returns the bus ID the gadget is on.
     498 *
     499 * @returns Bus ID of the gadget.
     500 * @param   hGadget           The gadget handle.
     501 */
     502DECLHIDDEN(uint32_t) utsGadgetGetBusId(UTSGADGET hGadget);
     503
     504/**
     505 * Returns the device ID of the gagdet.
     506 *
     507 * @returns Device ID of the gadget.
     508 * @param   hGadget           The gadget handle.
     509 */
     510DECLHIDDEN(uint32_t) utsGadgetGetDevId(UTSGADGET hGadget);
     511
     512/**
    479513 * Mark the gadget as connected to the host. Depending
    480514 * on the host type it will be appear as physically attached
  • trunk/src/VBox/ValidationKit/utils/usb/UsbTestServiceGadgetClassTest.cpp

    r60493 r60517  
    3737
    3838#include "UsbTestServiceGadgetInternal.h"
     39#include "UsbTestServicePlatform.h"
    3940
    4041/*********************************************************************************************************************************
     
    253254    /* Finally delete the gadget template. */
    254255    utsGadgetClassTestDirRemove(pClass->pszGadgetPath);
     256
     257    /* Release the UDC. */
     258    if (pClass->pszUdc)
     259    {
     260        rc = utsPlatformLnxReleaseUDC(pClass->pszUdc);
     261        AssertRC(rc);
     262        RTStrFree(pClass->pszUdc);
     263    }
    255264}
    256265
     
    343352
    344353                /* Finally enable the gadget by attaching it to a UDC. */
    345                 /** @todo: Figure out a free UDC dynamically. */
    346                 if (RT_SUCCESS(rc))
    347                     rc = RTLinuxSysFsWriteStrFile("dummy_udc.0", 0, NULL, "%s/UDC", pClass->pszGadgetPath);
     354                if (RT_SUCCESS(rc))
     355                {
     356                    pClass->pszUdc = NULL;
     357
     358                    rc = utsPlatformLnxAcquireUDC(&pClass->pszUdc, &pClass->uBusId);
     359                    if (RT_SUCCESS(rc))
     360                        rc = RTLinuxSysFsWriteStrFile(pClass->pszUdc, 0, NULL, "%s/UDC", pClass->pszGadgetPath);
     361                }
    348362            }
    349363
     
    378392
    379393
     394/**
     395 * @interface_method_impl{UTSGADGETCLASS,pfnGetBusId}
     396 */
     397static DECLCALLBACK(uint32_t) utsGadgetClassTestGetBusId(PUTSGADGETCLASSINT pClass)
     398{
     399    return pClass->uBusId;
     400}
     401
     402
     403/**
     404 * @interface_method_impl{UTSGADGETCLASS,pfnConnect}
     405 */
     406static DECLCALLBACK(int) utsGadgetClassTestConnect(PUTSGADGETCLASSINT pClass)
     407{
     408    return RTLinuxSysFsWriteStrFile("connect", 0, NULL, "/sys/class/udc/%s/soft_connect", pClass->pszUdc);
     409}
     410
     411
     412/**
     413 * @interface_method_impl{UTSGADGETCLASS,pfnDisconnect}
     414 */
     415static DECLCALLBACK(int) utsGadgetClassTestDisconnect(PUTSGADGETCLASSINT pClass)
     416{
     417    return RTLinuxSysFsWriteStrFile("disconnect", 0, NULL, "/sys/class/udc/%s/soft_connect", pClass->pszUdc);}
     418
     419
    380420
    381421/**
     
    393433    utsGadgetClassTestInit,
    394434    /** pfnTerm */
    395     utsGadgetClassTestTerm
     435    utsGadgetClassTestTerm,
     436    /** pfnGetBusId */
     437    utsGadgetClassTestGetBusId,
     438    /** pfnConnect */
     439    utsGadgetClassTestConnect,
     440    /** pfnDisconnect. */
     441    utsGadgetClassTestDisconnect
    396442};
    397443
  • trunk/src/VBox/ValidationKit/utils/usb/UsbTestServiceGadgetHost.cpp

    r60375 r60517  
    142142}
    143143
     144
     145DECLHIDDEN(int) utsGadgetHostGadgetConnect(UTSGADGETHOST hGadgetHost, UTSGADGET hGadget)
     146{
     147    PUTSGADGETHOSTINT pThis = hGadgetHost;
     148
     149    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
     150    return pThis->pHstIf->pfnGadgetConnect((PUTSGADGETHOSTTYPEINT)&pThis->abIfInst[0], hGadget);
     151}
     152
     153
     154DECLHIDDEN(int) utsGadgetHostGadgetDisconnect(UTSGADGETHOST hGadgetHost, UTSGADGET hGadget)
     155{
     156    PUTSGADGETHOSTINT pThis = hGadgetHost;
     157
     158    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
     159    return pThis->pHstIf->pfnGadgetDisconnect((PUTSGADGETHOSTTYPEINT)&pThis->abIfInst[0], hGadget);
     160}
     161
  • trunk/src/VBox/ValidationKit/utils/usb/UsbTestServiceGadgetHostUsbIp.cpp

    r60493 r60517  
    3434
    3535#include "UsbTestServiceGadgetHostInternal.h"
     36#include "UsbTestServicePlatform.h"
    3637
    3738/*********************************************************************************************************************************
     
    5758
    5859/**
    59  * Load a kernel module on a Linux host.
     60 * Worker for binding/unbinding the given gadget from the USB/IP server.
    6061 *
    6162 * @returns IPRT status code.
    62  * @param   pszModule    The module to load.
    63  */
    64 static int utsGadgetHostUsbIpLoadModule(const char *pszModule)
    65 {
    66     RTPROCESS hProcModprobe = NIL_RTPROCESS;
    67     const char *apszArgv[3];
    68 
    69     apszArgv[0] = "modprobe";
    70     apszArgv[1] = pszModule;
    71     apszArgv[2] = NULL;
    72 
    73     int rc = RTProcCreate("modprobe", apszArgv, RTENV_DEFAULT, RTPROC_FLAGS_SEARCH_PATH, &hProcModprobe);
     63 * @param   pThis             The gadget host instance.
     64 * @param   hGadget           The gadget handle.
     65 * @param   fBind             Flag whether to do a bind or unbind.
     66 */
     67static int usbGadgetHostUsbIpBindUnbind(PUTSGADGETHOSTTYPEINT pThis, UTSGADGET hGadget, bool fBind)
     68{
     69    uint32_t uBusId, uDevId;
     70    char aszBus[32];
     71
     72    uBusId = utsGadgetGetBusId(hGadget);
     73    uDevId = utsGadgetGetDevId(hGadget);
     74
     75    /* Create the busid argument string. */
     76    size_t cbRet = RTStrPrintf(&aszBus[0], RT_ELEMENTS(aszBus), "%u-%u", uBusId, uDevId);
     77    if (cbRet == RT_ELEMENTS(aszBus))
     78        return VERR_BUFFER_OVERFLOW;
     79
     80    /* Bind to the USB/IP server. */
     81    RTPROCESS hProcUsbIp = NIL_RTPROCESS;
     82    const char *apszArgv[5];
     83
     84    apszArgv[0] = "usbip";
     85    apszArgv[1] = fBind ? "bind" : "unbind";
     86    apszArgv[2] = "-b";
     87    apszArgv[3] = &aszBus[0];
     88    apszArgv[4] = NULL;
     89
     90    int rc = RTProcCreate("usbip", apszArgv, RTENV_DEFAULT, RTPROC_FLAGS_SEARCH_PATH, &hProcUsbIp);
    7491    if (RT_SUCCESS(rc))
    7592    {
    7693        RTPROCSTATUS ProcSts;
    77         rc = RTProcWait(hProcModprobe, RTPROCWAIT_FLAGS_BLOCK, &ProcSts);
     94        rc = RTProcWait(hProcUsbIp, RTPROCWAIT_FLAGS_BLOCK, &ProcSts);
    7895        if (RT_SUCCESS(rc))
    7996        {
     
    88105}
    89106
    90 
    91107/**
    92108 * @interface_method_impl{UTSGADGETHOSTIF,pfnInit}
     
    103119    {
    104120        /* Make sure the kernel drivers are loaded. */
    105         rc = utsGadgetHostUsbIpLoadModule("usbip-core");
     121        rc = utsPlatformModuleLoad("usbip-core", NULL, 0);
    106122        if (RT_SUCCESS(rc))
    107123        {
    108             rc = utsGadgetHostUsbIpLoadModule("usbip-host");
     124            rc = utsPlatformModuleLoad("usbip-host", NULL, 0);
    109125            if (RT_SUCCESS(rc))
    110126            {
    111                 rc = utsGadgetHostUsbIpLoadModule("libcomposite");
     127                char aszPort[10];
     128                char aszPidFile[64];
     129                const char *apszArgv[6];
     130
     131                RTStrPrintf(aszPort, RT_ELEMENTS(aszPort), "%u", uPort);
     132                RTStrPrintf(aszPidFile, RT_ELEMENTS(aszPidFile), "/var/run/usbipd-%u.pid", uPort);
     133                /* Start the USB/IP server process. */
     134                apszArgv[0] = "usbipd";
     135                apszArgv[1] = "--tcp-port";
     136                apszArgv[2] = aszPort;
     137                apszArgv[3] = "--pid";
     138                apszArgv[4] = aszPidFile;
     139                apszArgv[5] = NULL;
     140                rc = RTProcCreate("usbipd", apszArgv, RTENV_DEFAULT, RTPROC_FLAGS_SEARCH_PATH, &pIf->hProcUsbIp);
    112141                if (RT_SUCCESS(rc))
    113142                {
    114                     char aszPort[10];
    115                     char aszPidFile[64];
    116                     const char *apszArgv[6];
    117 
    118                     RTStrPrintf(aszPort, RT_ELEMENTS(aszPort), "%u", uPort);
    119                     RTStrPrintf(aszPidFile, RT_ELEMENTS(aszPidFile), "/var/run/usbipd-%u.pid", uPort);
    120                     /* Start the USB/IP server process. */
    121                     apszArgv[0] = "usbipd";
    122                     apszArgv[1] = "--tcp-port";
    123                     apszArgv[2] = aszPort;
    124                     apszArgv[3] = "--pid";
    125                     apszArgv[4] = aszPidFile;
    126                     apszArgv[5] = NULL;
    127                     rc = RTProcCreate("usbipd", apszArgv, RTENV_DEFAULT, RTPROC_FLAGS_SEARCH_PATH, &pIf->hProcUsbIp);
    128                     if (RT_SUCCESS(rc))
     143                    /* Wait for a bit to make sure the server started up successfully. */
     144                    uint64_t tsStart = RTTimeMilliTS();
     145                    do
    129146                    {
    130                         /* Wait for a bit to make sure the server started up successfully. */
    131                         uint64_t tsStart = RTTimeMilliTS();
    132                         do
     147                        RTPROCSTATUS ProcSts;
     148                        rc = RTProcWait(pIf->hProcUsbIp, RTPROCWAIT_FLAGS_NOBLOCK, &ProcSts);
     149                        if (rc != VERR_PROCESS_RUNNING)
    133150                        {
    134                             RTPROCSTATUS ProcSts;
    135                             rc = RTProcWait(pIf->hProcUsbIp, RTPROCWAIT_FLAGS_NOBLOCK, &ProcSts);
    136                             if (rc != VERR_PROCESS_RUNNING)
    137                             {
    138                                 rc = VERR_INVALID_HANDLE;
    139                                 break;
    140                             }
    141                             RTThreadSleep(1);
    142                             rc = VINF_SUCCESS;
    143                         } while (RTTimeMilliTS() - tsStart < 2 * 1000); /* 2 seconds. */
    144                     }
     151                            rc = VERR_INVALID_HANDLE;
     152                            break;
     153                        }
     154                        RTThreadSleep(1);
     155                        rc = VINF_SUCCESS;
     156                    } while (RTTimeMilliTS() - tsStart < 2 * 1000); /* 2 seconds. */
    145157                }
    146158            }
     
    190202static DECLCALLBACK(int) utsGadgetHostUsbIpGadgetConnect(PUTSGADGETHOSTTYPEINT pIf, UTSGADGET hGadget)
    191203{
    192    return VINF_SUCCESS;
     204    return usbGadgetHostUsbIpBindUnbind(pIf, hGadget, true /* fBind */);
    193205}
    194206
     
    199211static DECLCALLBACK(int) utsGadgetHostUsbIpGadgetDisconnect(PUTSGADGETHOSTTYPEINT pIf, UTSGADGET hGadget)
    200212{
    201     return VINF_SUCCESS;
     213    return usbGadgetHostUsbIpBindUnbind(pIf, hGadget, false /* fBind */);
    202214}
    203215
  • trunk/src/VBox/ValidationKit/utils/usb/UsbTestServiceGadgetInternal.h

    r60375 r60517  
    6969    DECLR3CALLBACKMEMBER(void, pfnTerm, (PUTSGADGETCLASSINT pClass));
    7070
     71    /**
     72     * Returns the bus ID of the class instance.
     73     *
     74     * @returns Bus ID.
     75     * @param   pClass        The interface specific instance data.
     76     */
     77    DECLR3CALLBACKMEMBER(uint32_t, pfnGetBusId, (PUTSGADGETCLASSINT pClass));
     78
     79    /**
     80     * Connects the gadget.
     81     *
     82     * @returns IPRT status code.
     83     * @param   pClass        The interface specific instance data.
     84     */
     85    DECLR3CALLBACKMEMBER(int, pfnConnect, (PUTSGADGETCLASSINT pClass));
     86
     87    /**
     88     * Disconnect the gadget.
     89     *
     90     * @returns IPRT status code.
     91     * @param   pClass        The interface specific instance data.
     92     */
     93    DECLR3CALLBACKMEMBER(int, pfnDisconnect, (PUTSGADGETCLASSINT pClass));
     94
    7195} UTSGADGETCLASSIF;
    7296/** Pointer to a gadget class callback table. */
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