VirtualBox

Changeset 89802 in vbox for trunk/src/VBox/Devices/Audio


Ignore:
Timestamp:
Jun 21, 2021 6:19:21 AM (4 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
145259
Message:

Audio/ValKit: Added support for CRC32 checksum calculation; now receiving data also works with bigger chunks. bugref:10008

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Audio/AudioTestServiceClient.cpp

    r89685 r89802  
    9696    int rc;
    9797
     98    LogFlowFuncEnter();
     99
    98100    ATSPKTHDR Hdr;
     101    RT_ZERO(Hdr);
    99102    size_t    cbHdr = 0;
    100     if (pClient->cbHdr)
     103    if (pClient->cbHdr) /* Header already received? */
    101104    {
    102105        memcpy(&Hdr, &pClient->abHdr, sizeof(Hdr));
     
    105108        rc = VINF_SUCCESS;
    106109    }
    107     else
     110    else /* No, receive header. */
    108111    {
    109112        rc = RTTcpRead(pClient->hSock, &Hdr, sizeof(Hdr), &cbHdr);
    110         LogFlowFunc(("rc=%Rrc, hdr=%zu, hdr.cb=%zu, %.8s -> %.*Rhxd\n", rc, sizeof(Hdr), Hdr.cb, Hdr.achOpcode, RT_MIN(cbHdr, sizeof(ATSPKTHDR)), &Hdr));
    111     }
     113    }
     114
     115    LogFlowFunc(("rc=%Rrc, hdr=%zu, hdr.cb=%zu, %.8s -> %.*Rhxd\n", rc, cbHdr, Hdr.cb, Hdr.achOpcode, RT_MIN(cbHdr, sizeof(ATSPKTHDR)), &Hdr));
     116
     117    if (RT_FAILURE(rc))
     118        return rc;
    112119
    113120    if (cbHdr != sizeof(Hdr)) /* Check for bad packet sizes. */
    114         return VERR_NET_PROTOCOL_ERROR;
    115 
    116     if (RT_SUCCESS(rc))
    117     {
    118         if (Hdr.cb < sizeof(ATSPKTHDR))
    119             return VERR_NET_PROTOCOL_ERROR;
    120 
    121         if (Hdr.cb > ATSPKT_MAX_SIZE)
    122             return VERR_NET_PROTOCOL_ERROR;
    123 
    124         /** @todo Check opcode encoding. */
    125 
    126         uint32_t cbPadding;
    127         if (Hdr.cb % ATSPKT_ALIGNMENT)
    128             cbPadding = ATSPKT_ALIGNMENT - (Hdr.cb % ATSPKT_ALIGNMENT);
    129         else
    130             cbPadding = 0;
    131 
    132         if (Hdr.cb > sizeof(ATSPKTHDR))
     121    {
     122        AssertMsgFailed(("Packet is invalid (%RU32 bytes), must be at least %zu bytes\n", cbHdr, sizeof(Hdr)));
     123        return VERR_NET_INCOMPLETE_TX_PACKET;
     124    }
     125
     126    if (Hdr.cb < sizeof(ATSPKTHDR))
     127    {
     128        AssertMsgFailed(("Packet is too small (%RU32 bytes), must be at least %zu bytes\n", Hdr.cb, sizeof(Hdr)));
     129        return VERR_NET_INCOMPLETE_TX_PACKET;
     130    }
     131
     132    if (Hdr.cb > ATSPKT_MAX_SIZE)
     133    {
     134        AssertMsgFailed(("Packet is %RU32 bytes, only %zu bytes allowed\n", Hdr.cb, ATSPKT_MAX_SIZE));
     135        return VERR_BUFFER_OVERFLOW;
     136    }
     137
     138    if (Hdr.cb > ATSPKT_MAX_SIZE)
     139    {
     140        AssertMsgFailed(("Packet is %RU32 bytes, only %zu bytes allowed\n", Hdr.cb, ATSPKT_MAX_SIZE));
     141        return VERR_BUFFER_OVERFLOW;
     142    }
     143
     144    pReply->cbPayload = Hdr.cb - sizeof(ATSPKTHDR);
     145    Log3Func(("cbHdr=%zu, Hdr.szOp=%s, Hdr.cb=%RU32 -> %zu bytes payload\n", cbHdr, Hdr.achOpcode, Hdr.cb, pReply->cbPayload));
     146    if (pReply->cbPayload)
     147    {
     148        pReply->pvPayload = RTMemAlloc(pReply->cbPayload);
     149        if (pReply->pvPayload)
    133150        {
    134             pReply->cbPayload = (Hdr.cb - sizeof(ATSPKTHDR)) + cbPadding;
    135             Log3Func(("cbPadding=%RU32, cbPayload: %RU32 -> %zu\n", cbPadding, Hdr.cb - sizeof(ATSPKTHDR), pReply->cbPayload));
    136             AssertReturn(pReply->cbPayload <= ATSPKT_MAX_SIZE, VERR_BUFFER_OVERFLOW); /* Paranoia. */
    137         }
    138 
    139         if (pReply->cbPayload)
    140         {
    141             pReply->pvPayload = RTMemAlloc(pReply->cbPayload);
    142             if (pReply->pvPayload)
     151            uint32_t cbPayloadRead = 0;
     152            while (cbPayloadRead < pReply->cbPayload)
    143153            {
    144154                size_t cbRead = 0;
    145                 rc = RTTcpRead(pClient->hSock, pReply->pvPayload, pReply->cbPayload, &cbRead);
     155                rc = RTTcpRead(pClient->hSock, (uint8_t *)pReply->pvPayload + cbPayloadRead, pReply->cbPayload - cbPayloadRead, &cbRead);
    146156                if (RT_SUCCESS(rc))
    147157                {
    148                     Log3Func(("cbPayload=%zu -> cbRead=%zu\n", pReply->cbPayload, cbRead));
    149158                    if (!cbRead)
    150159                    {
     
    153162                            rc = VERR_NET_PROTOCOL_ERROR;
    154163                    }
    155                     else
     164
     165                    cbPayloadRead += cbRead;
     166                    Assert(cbPayloadRead <= pReply->cbPayload);
     167                }
     168            }
     169
     170            if (RT_SUCCESS(rc))
     171            {
     172                Assert(cbPayloadRead == pReply->cbPayload);
     173                if (Hdr.uCrc32) /* Checksum given? */
     174                {
     175                    uint32_t uMyCrc32 = RTCrc32Start();
     176                             uMyCrc32 = RTCrc32Process(uMyCrc32, Hdr.achOpcode, sizeof(Hdr.achOpcode));
     177                             uMyCrc32 = RTCrc32Process(uMyCrc32, pReply->pvPayload, pReply->cbPayload);
     178
     179                    if (Hdr.uCrc32 != RTCrc32Finish(uMyCrc32))
     180                        AssertFailedStmt(rc = VERR_TAR_CHKSUM_MISMATCH /** @todo Fudge! */);
     181
     182                    if (RT_SUCCESS(rc))
    156183                    {
    157                         while (cbPadding--)
     184                        /* Make sure to align the payload data (if not done by the sender already). */
     185                        size_t const cbRestAlignment = RT_ALIGN_Z(pReply->cbPayload, ATSPKT_ALIGNMENT) - pReply->cbPayload;
     186                        if (cbRestAlignment)
    158187                        {
    159                             Assert(cbRead);
    160                             cbRead--;
     188                            uint8_t abAlignment[ATSPKT_ALIGNMENT];
     189                            rc = RTTcpRead(pClient->hSock, abAlignment, RT_MIN(cbRestAlignment, sizeof(abAlignment)), NULL);
    161190                        }
    162191                    }
    163192                }
    164 
    165                 if (RT_SUCCESS(rc))
    166                 {
    167                     /** @todo Check CRC-32. */
    168                     pReply->cbPayload = cbRead;
    169                     /** @todo Re-allocate pvPayload to not store padding? */
    170                 }
    171                 else
    172                     audioTestSvcClientReplyDestroy(pReply);
    173193            }
    174             else
    175                 rc = VERR_NO_MEMORY;
     194
     195            if (RT_FAILURE(rc))
     196                audioTestSvcClientReplyDestroy(pReply);
    176197        }
    177 
    178         if (RT_SUCCESS(rc))
    179         {
    180             memcpy(pReply->szOp, Hdr.achOpcode, sizeof(pReply->szOp));
    181         }
    182     }
    183 
     198        else
     199            rc = VERR_NO_MEMORY;
     200    }
     201
     202    if (RT_SUCCESS(rc))
     203        memcpy(pReply->szOp, Hdr.achOpcode, sizeof(pReply->szOp));
     204
     205    LogFlowFuncLeaveRC(rc);
    184206    return rc;
    185207}
     
    459481        ATSSRVREPLY Reply;
    460482        RT_ZERO(Reply);
    461 
    462483        rc = audioTestSvcClientRecvReply(pClient, &Reply, false /* fNoDataOk */);
    463         AssertRCBreak(rc);
    464 
    465         if (   RTStrNCmp(Reply.szOp, "DATA    ", ATSPKT_OPCODE_MAX_LEN) == 0
    466             && Reply.pvPayload
    467             && Reply.cbPayload)
     484        if (RT_SUCCESS(rc))
    468485        {
    469             /** @todo Skip uCrc32 for now. */
    470             rc = RTFileWrite(hFile, (uint8_t *)Reply.pvPayload + 4, Reply.cbPayload - 4, NULL);
    471         }
    472         else if (RTStrNCmp(Reply.szOp, "DATA EOF", ATSPKT_OPCODE_MAX_LEN) == 0)
    473         {
    474             rc = VINF_EOF;
    475         }
    476         else
    477         {
    478             AssertMsgFailed(("Got unexpected reply '%s'", Reply.szOp));
    479             rc = VERR_NET_PROTOCOL_ERROR;
     486            /* Calculate and validate checksum. */
     487            uint32_t uDataCrc32;
     488            memcpy(&uDataCrc32, Reply.pvPayload, sizeof(uint32_t));
     489
     490            if (   uDataCrc32
     491                && uDataCrc32 != RTCrc32((uint8_t *)Reply.pvPayload + 4, Reply.cbPayload - 4))
     492                rc = VERR_TAR_CHKSUM_MISMATCH; /** @todo Fudge! */
     493
     494            if (RT_SUCCESS(rc))
     495            {
     496                if (   RTStrNCmp(Reply.szOp, "DATA    ", ATSPKT_OPCODE_MAX_LEN) == 0
     497                    && Reply.pvPayload
     498                    && Reply.cbPayload)
     499                {
     500                    /** @todo Skip uCrc32 for now. */
     501                    rc = RTFileWrite(hFile, (uint8_t *)Reply.pvPayload + 4, Reply.cbPayload - 4, NULL);
     502                }
     503                else if (RTStrNCmp(Reply.szOp, "DATA EOF", ATSPKT_OPCODE_MAX_LEN) == 0)
     504                {
     505                    rc = VINF_EOF;
     506                }
     507                else
     508                {
     509                    AssertMsgFailed(("Got unexpected reply '%s'", Reply.szOp));
     510                    rc = VERR_NOT_SUPPORTED;
     511                }
     512            }
    480513        }
    481514
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