VirtualBox

Ignore:
Timestamp:
May 2, 2016 4:12:43 PM (9 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
106992
Message:

ValidationKit/UsbTestService: Updates, implement the protocol bits for passing extended configuration from the client to the gadget, detect multiple busses from dummy_hcd which creates a separate bus for high-speed and super-speed gadgets, some smaller fixes

File:
1 edited

Legend:

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

    r60548 r60793  
    542542
    543543/**
     544 * Parses an unsigned integer from the given value string.
     545 *
     546 * @returns IPRT status code.
     547 * @retval  VERR_OUT_OF_RANGE if the parsed value exceeds the given maximum.
     548 * @param   uMax                The maximum value.
     549 * @param   pu64                Where to store the parsed number on success.
     550 */
     551static int utsDoGadgetCreateCfgParseUInt(const char *pszVal, uint64_t uMax, uint64_t *pu64)
     552{
     553    int rc = RTStrToUInt64Ex(pszVal, NULL, 0, pu64);
     554    if (RT_SUCCESS(rc))
     555    {
     556        if (*pu64 > uMax)
     557            rc = VERR_OUT_OF_RANGE;
     558    }
     559
     560    return rc;
     561}
     562
     563/**
     564 * Parses a signed integer from the given value string.
     565 *
     566 * @returns IPRT status code.
     567 * @retval  VERR_OUT_OF_RANGE if the parsed value exceeds the given range.
     568 * @param   iMin                The minimum value.
     569 * @param   iMax                The maximum value.
     570 * @param   pi64                Where to store the parsed number on success.
     571 */
     572static int utsDoGadgetCreateCfgParseInt(const char *pszVal, int64_t iMin, int64_t iMax, int64_t *pi64)
     573{
     574    int rc = RTStrToInt64Ex(pszVal, NULL, 0, pi64);
     575    if (RT_SUCCESS(rc))
     576    {
     577        if (   *pi64 < iMin
     578            || *pi64 > iMax)
     579            rc = VERR_OUT_OF_RANGE;
     580    }
     581
     582    return rc;
     583}
     584
     585/**
     586 * Parses the given config item and fills in the value according to the given type.
     587 *
     588 * @returns IPRT status code.
     589 * @param   pCfgItem            The config item to parse.
     590 * @param   u32Type             The config type.
     591 * @param   pszVal              The value encoded as a string.
     592 */
     593static int utsDoGadgetCreateCfgParseItem(PUTSGADGETCFGITEM pCfgItem, uint32_t u32Type,
     594                                         const char *pszVal)
     595{
     596    int rc = VINF_SUCCESS;
     597
     598    switch (u32Type)
     599    {
     600        case UTSPKT_GDGT_CFG_ITEM_TYPE_BOOLEAN:
     601        {
     602            pCfgItem->Val.enmType = UTSGADGETCFGTYPE_BOOLEAN;
     603            if (   RTStrICmp(pszVal, "enabled")
     604                || RTStrICmp(pszVal, "1")
     605                || RTStrICmp(pszVal, "true"))
     606                pCfgItem->Val.u.f = true;
     607            else if (   RTStrICmp(pszVal, "disabled")
     608                     || RTStrICmp(pszVal, "0")
     609                     || RTStrICmp(pszVal, "false"))
     610                pCfgItem->Val.u.f = false;
     611            else
     612                rc = VERR_INVALID_PARAMETER;
     613            break;
     614        }
     615        case UTSPKT_GDGT_CFG_ITEM_TYPE_STRING:
     616        {
     617            pCfgItem->Val.enmType = UTSGADGETCFGTYPE_STRING;
     618            pCfgItem->Val.u.psz = RTStrDup(pszVal);
     619            if (!pCfgItem->Val.u.psz)
     620                rc = VERR_NO_STR_MEMORY;
     621            break;
     622        }
     623        case UTSPKT_GDGT_CFG_ITEM_TYPE_UINT8:
     624        {
     625            pCfgItem->Val.enmType = UTSGADGETCFGTYPE_UINT8;
     626
     627            uint64_t u64;
     628            rc = utsDoGadgetCreateCfgParseUInt(pszVal, UINT8_MAX, &u64);
     629            if (RT_SUCCESS(rc))
     630                pCfgItem->Val.u.u8 = (uint8_t)u64;
     631            break;
     632        }
     633        case UTSPKT_GDGT_CFG_ITEM_TYPE_UINT16:
     634        {
     635            pCfgItem->Val.enmType = UTSGADGETCFGTYPE_UINT16;
     636
     637            uint64_t u64;
     638            rc = utsDoGadgetCreateCfgParseUInt(pszVal, UINT16_MAX, &u64);
     639            if (RT_SUCCESS(rc))
     640                pCfgItem->Val.u.u16 = (uint16_t)u64;
     641            break;
     642        }
     643        case UTSPKT_GDGT_CFG_ITEM_TYPE_UINT32:
     644        {
     645            pCfgItem->Val.enmType = UTSGADGETCFGTYPE_UINT32;
     646
     647            uint64_t u64;
     648            rc = utsDoGadgetCreateCfgParseUInt(pszVal, UINT32_MAX, &u64);
     649            if (RT_SUCCESS(rc))
     650                pCfgItem->Val.u.u32 = (uint32_t)u64;
     651            break;
     652        }
     653        case UTSPKT_GDGT_CFG_ITEM_TYPE_UINT64:
     654        {
     655            pCfgItem->Val.enmType = UTSGADGETCFGTYPE_UINT64;
     656            rc = utsDoGadgetCreateCfgParseUInt(pszVal, UINT64_MAX, &pCfgItem->Val.u.u64);
     657            break;
     658        }
     659        case UTSPKT_GDGT_CFG_ITEM_TYPE_INT8:
     660        {
     661            pCfgItem->Val.enmType = UTSGADGETCFGTYPE_INT8;
     662
     663            int64_t i64;
     664            rc = utsDoGadgetCreateCfgParseInt(pszVal, INT8_MIN, INT8_MAX, &i64);
     665            if (RT_SUCCESS(rc))
     666                pCfgItem->Val.u.i8 = (int8_t)i64;
     667            break;
     668        }
     669        case UTSPKT_GDGT_CFG_ITEM_TYPE_INT16:
     670        {
     671            pCfgItem->Val.enmType = UTSGADGETCFGTYPE_INT16;
     672
     673            int64_t i64;
     674            rc = utsDoGadgetCreateCfgParseInt(pszVal, INT16_MIN, INT16_MAX, &i64);
     675            if (RT_SUCCESS(rc))
     676                pCfgItem->Val.u.i16 = (int16_t)i64;
     677            break;
     678        }
     679        case UTSPKT_GDGT_CFG_ITEM_TYPE_INT32:
     680        {
     681            pCfgItem->Val.enmType = UTSGADGETCFGTYPE_INT32;
     682
     683            int64_t i64;
     684            rc = utsDoGadgetCreateCfgParseInt(pszVal, INT32_MIN, INT32_MAX, &i64);
     685            if (RT_SUCCESS(rc))
     686                pCfgItem->Val.u.i32 = (int32_t)i64;
     687            break;
     688        }
     689        case UTSPKT_GDGT_CFG_ITEM_TYPE_INT64:
     690        {
     691            pCfgItem->Val.enmType = UTSGADGETCFGTYPE_INT64;
     692            rc = utsDoGadgetCreateCfgParseInt(pszVal, INT64_MIN, INT64_MAX, &pCfgItem->Val.u.i64);
     693            break;
     694        }
     695        default:
     696            rc = VERR_INVALID_PARAMETER;
     697    }
     698
     699    return rc;
     700}
     701
     702/**
    544703 * Creates the configuration from the given GADGET CREATE packet.
    545704 *
    546705 * @returns IPRT status code.
    547  * @param   pReq                The gadget create request.
    548  * @param   paCfg               The array of configuration items.
    549  */
    550 static int utsDoGadgetCreateFillCfg(PUTSPKTREQGDGTCTOR pReq, PUTSGADGETCFGITEM paCfg)
    551 {
    552     return VERR_NOT_IMPLEMENTED;
     706 * @param   pCfgItem            The first config item header in the request packet.
     707 * @param   cCfgItems           Number of config items in the packet to parse.
     708 * @param   cbPkt               Number of bytes left in the packet for the config data.
     709 * @param   paCfg               The array of configuration items to fill.
     710 */
     711static int utsDoGadgetCreateFillCfg(PUTSPKTREQGDGTCTORCFGITEM pCfgItem, unsigned cCfgItems,
     712                                    size_t cbPkt, PUTSGADGETCFGITEM paCfg)
     713{
     714    int rc = VINF_SUCCESS;
     715    unsigned idxCfg = 0;
     716
     717    while (   RT_SUCCESS(rc)
     718           && cCfgItems
     719           && cbPkt)
     720    {
     721        if (cbPkt >= sizeof(UTSPKTREQGDGTCTORCFGITEM))
     722        {
     723            cbPkt -= sizeof(UTSPKTREQGDGTCTORCFGITEM);
     724            if (pCfgItem->u32KeySize + pCfgItem->u32ValSize >= cbPkt)
     725            {
     726                const char *pszKey = (const char *)(pCfgItem + 1);
     727                const char *pszVal = pszKey + pCfgItem->u32KeySize;
     728
     729                /* Validate termination. */
     730                if (   *(pszKey + pCfgItem->u32KeySize - 1) != '\0'
     731                    || *(pszVal + pCfgItem->u32ValSize - 1) != '\0')
     732                    rc = VERR_INVALID_PARAMETER;
     733                else
     734                {
     735                    paCfg[idxCfg].pszKey = RTStrDup(pszKey);
     736
     737                    rc = utsDoGadgetCreateCfgParseItem(&paCfg[idxCfg], pCfgItem->u32Type, pszVal);
     738                    if (RT_SUCCESS(rc))
     739                    {
     740                        cbPkt -= pCfgItem->u32KeySize + pCfgItem->u32ValSize;
     741                        cCfgItems--;
     742                        idxCfg++;
     743                        pCfgItem = (PUTSPKTREQGDGTCTORCFGITEM)(pszVal + pCfgItem->u32ValSize);
     744                    }
     745                }
     746            }
     747            else
     748                rc = VERR_INVALID_PARAMETER;
     749        }
     750        else
     751            rc = VERR_INVALID_PARAMETER;
     752    }
     753
     754    return rc;
    553755}
    554756
     
    688890            return utsReplyRC(pClient, pPktHdr, VERR_NO_MEMORY, "Failed to allocate memory for configration items");
    689891
    690         rc = utsDoGadgetCreateFillCfg(pReq, paCfg);
     892        rc = utsDoGadgetCreateFillCfg((PUTSPKTREQGDGTCTORCFGITEM)(pReq + 1), pReq->u32CfgItems,
     893                                      pPktHdr->cb - sizeof(UTSPKTREQGDGTCTOR), paCfg);
    691894        if (RT_FAILURE(rc))
    692895        {
     
    10791282        }
    10801283        else
    1081         {
    1082             if (RTErrInfoIsSet(pErrInfo))
    1083             {
    1084                 RTMsgError("Failed to parse config with detailed error: %s (%Rrc)\n",
    1085                            pErrInfo->pszMsg, pErrInfo->rc);
    1086                 RTErrInfoFree(pErrInfo);
    1087             }
    1088             else
    1089                 RTMsgError("Faield to parse config with unknown error (%Rrc)\n", rc);
    1090             return rc;
    1091         }
     1284            RTMsgError("Initializing the platform failed with %Rrc\n", rc);
     1285    }
     1286    else
     1287    {
     1288        if (RTErrInfoIsSet(pErrInfo))
     1289        {
     1290            RTMsgError("Failed to parse config with detailed error: %s (%Rrc)\n",
     1291                       pErrInfo->pszMsg, pErrInfo->rc);
     1292            RTErrInfoFree(pErrInfo);
     1293        }
     1294        else
     1295            RTMsgError("Failed to parse config with unknown error (%Rrc)\n", rc);
    10921296    }
    10931297
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