diff --git a/src/cas/generic/casStrmClient.cc b/src/cas/generic/casStrmClient.cc index 468aa17a5..b1e321120 100644 --- a/src/cas/generic/casStrmClient.cc +++ b/src/cas/generic/casStrmClient.cc @@ -411,17 +411,8 @@ caStatus casStrmClient::verifyRequest (casChannelI * & pChan , bool allowdyn) // // element count out of range ? // - if ( allowdyn && ctx.msg.m_count==0 && - CA_V413 ( this->minor_version_number ) ) { - // Hack - // Since GDD interface doesn't support variable sized arrays - // we present dynamic requests as max size. - // This allows PCAS to claim support for dynamic arrays w/o - // going to the trouble of fixing GDD. - ctx.msg.m_count = pChan->getPVI().nativeCount(); - } - else if ( ctx.msg.m_count > pChan->getPVI().nativeCount() || - ctx.msg.m_count == 0u ) { + if ( ctx.msg.m_count > pChan->getPVI().nativeCount() || + ( !allowdyn && ctx.msg.m_count == 0u ) ) { return ECA_BADCOUNT; } @@ -454,7 +445,7 @@ caStatus casStrmClient::readAction ( epicsGuard < casClientMutex > & guard ) casChannelI * pChan; { - caStatus status = this->verifyRequest ( pChan, true ); + caStatus status = this->verifyRequest ( pChan, CA_V413 ( this->minor_version_number ) ); if ( status != ECA_NORMAL ) { if ( pChan ) { return this->sendErr ( guard, mp, pChan->getCID(), @@ -541,11 +532,15 @@ caStatus casStrmClient::readResponse ( epicsGuard < casClientMutex > & guard, pChan->getCID(), status, ECA_GETFAIL ); } + ca_uint32_t count = (msg.m_count == 0) ? + (ca_uint32_t)desc.getDataSizeElements() : + msg.m_count; + void * pPayload; { - unsigned payloadSize = dbr_size_n ( msg.m_dataType, msg.m_count ); + unsigned payloadSize = dbr_size_n ( msg.m_dataType, count ); caStatus localStatus = this->out.copyInHeader ( msg.m_cmmd, payloadSize, - msg.m_dataType, msg.m_count, pChan->getCID (), + msg.m_dataType, count, pChan->getCID (), msg.m_available, & pPayload ); if ( localStatus ) { if ( localStatus==S_cas_hugeRequest ) { @@ -561,21 +556,21 @@ caStatus casStrmClient::readResponse ( epicsGuard < casClientMutex > & guard, // (places the data in network format) // int mapDBRStatus = gddMapDbr[msg.m_dataType].conv_dbr( - pPayload, msg.m_count, desc, pChan->enumStringTable() ); + pPayload, count, desc, pChan->enumStringTable() ); if ( mapDBRStatus < 0 ) { desc.dump (); errPrintf ( S_cas_badBounds, __FILE__, __LINE__, "- get with PV=%s type=%u count=%u", - pChan->getPVI().getName(), msg.m_dataType, msg.m_count ); + pChan->getPVI().getName(), msg.m_dataType, count ); return this->sendErrWithEpicsStatus ( guard, & msg, pChan->getCID(), S_cas_badBounds, ECA_GETFAIL ); } int cacStatus = caNetConvert ( - msg.m_dataType, pPayload, pPayload, true, msg.m_count ); + msg.m_dataType, pPayload, pPayload, true, count ); if ( cacStatus != ECA_NORMAL ) { return this->sendErrWithEpicsStatus ( guard, & msg, pChan->getCID(), S_cas_internal, cacStatus ); } - if ( msg.m_dataType == DBR_STRING && msg.m_count == 1u ) { + if ( msg.m_dataType == DBR_STRING && count == 1u ) { unsigned reducedPayloadSize = strlen ( static_cast < char * > ( pPayload ) ) + 1u; this->out.commitMsg ( reducedPayloadSize ); } @@ -595,7 +590,7 @@ caStatus casStrmClient::readNotifyAction ( epicsGuard < casClientMutex > & guard casChannelI * pChan; { - caStatus status = this->verifyRequest ( pChan, true ); + caStatus status = this->verifyRequest ( pChan, CA_V413 ( this->minor_version_number ) ); if ( status != ECA_NORMAL ) { return this->readNotifyFailureResponse ( guard, * mp, status ); } @@ -666,11 +661,15 @@ caStatus casStrmClient::readNotifyResponse ( epicsGuard < casClientMutex > & gua return ecaStatus; } + ca_uint32_t count = (msg.m_count == 0) ? + (ca_uint32_t)desc.getDataSizeElements() : + msg.m_count; + void *pPayload; { - unsigned size = dbr_size_n ( msg.m_dataType, msg.m_count ); + unsigned size = dbr_size_n ( msg.m_dataType, count ); caStatus status = this->out.copyInHeader ( msg.m_cmmd, size, - msg.m_dataType, msg.m_count, ECA_NORMAL, + msg.m_dataType, count, ECA_NORMAL, msg.m_available, & pPayload ); if ( status ) { if ( status == S_cas_hugeRequest ) { @@ -685,23 +684,23 @@ caStatus casStrmClient::readNotifyResponse ( epicsGuard < casClientMutex > & gua // convert gdd to db_access type // int mapDBRStatus = gddMapDbr[msg.m_dataType].conv_dbr ( pPayload, - msg.m_count, desc, pChan->enumStringTable() ); + count, desc, pChan->enumStringTable() ); if ( mapDBRStatus < 0 ) { desc.dump(); errPrintf ( S_cas_badBounds, __FILE__, __LINE__, "- get notify with PV=%s type=%u count=%u", - pChan->getPVI().getName(), msg.m_dataType, msg.m_count ); + pChan->getPVI().getName(), msg.m_dataType, count ); return this->readNotifyFailureResponse ( guard, msg, ECA_NOCONVERT ); } int cacStatus = caNetConvert ( - msg.m_dataType, pPayload, pPayload, true, msg.m_count ); + msg.m_dataType, pPayload, pPayload, true, count ); if ( cacStatus != ECA_NORMAL ) { return this->sendErrWithEpicsStatus ( guard, & msg, pChan->getCID(), S_cas_internal, cacStatus ); } - if ( msg.m_dataType == DBR_STRING && msg.m_count == 1u ) { + if ( msg.m_dataType == DBR_STRING && count == 1u ) { unsigned reducedPayloadSize = strlen ( static_cast < char * > ( pPayload ) ) + 1u; this->out.commitMsg ( reducedPayloadSize ); } @@ -859,11 +858,15 @@ caStatus casStrmClient::monitorResponse ( casChannelI & chan, const caHdrLargeArray & msg, const gdd & desc, const caStatus completionStatus ) { + ca_uint32_t count = (msg.m_count == 0) ? + (ca_uint32_t)desc.getDataSizeElements() : + msg.m_count; + void * pPayload = 0; { - ca_uint32_t size = dbr_size_n ( msg.m_dataType, msg.m_count ); + ca_uint32_t size = dbr_size_n ( msg.m_dataType, count ); caStatus status = out.copyInHeader ( msg.m_cmmd, size, - msg.m_dataType, msg.m_count, ECA_NORMAL, + msg.m_dataType, count, ECA_NORMAL, msg.m_available, & pPayload ); if ( status ) { if ( status == S_cas_hugeRequest ) { @@ -881,7 +884,7 @@ caStatus casStrmClient::monitorResponse ( gdd * pDBRDD = 0; if ( completionStatus == S_cas_success ) { - caStatus status = createDBRDD ( msg.m_dataType, msg.m_count, pDBRDD ); + caStatus status = createDBRDD ( msg.m_dataType, count, pDBRDD ); if ( status != S_cas_success ) { caStatus ecaStatus; if ( status == S_cas_badType ) { @@ -902,7 +905,7 @@ caStatus casStrmClient::monitorResponse ( pDBRDD->unreference (); errPrintf ( S_cas_noConvert, __FILE__, __LINE__, "no conversion between event app type=%d and DBR type=%d Element count=%d", - desc.applicationType (), msg.m_dataType, msg.m_count); + desc.applicationType (), msg.m_dataType, count); return monitorFailureResponse ( guard, msg, ECA_NOCONVERT ); } } @@ -925,14 +928,14 @@ caStatus casStrmClient::monitorResponse ( } int mapDBRStatus = gddMapDbr[msg.m_dataType].conv_dbr ( - pPayload, msg.m_count, *pDBRDD, chan.enumStringTable() ); + pPayload, count, *pDBRDD, chan.enumStringTable() ); if ( mapDBRStatus < 0 ) { pDBRDD->unreference (); return monitorFailureResponse ( guard, msg, ECA_NOCONVERT ); } int cacStatus = caNetConvert ( - msg.m_dataType, pPayload, pPayload, true, msg.m_count ); + msg.m_dataType, pPayload, pPayload, true, count ); if ( cacStatus != ECA_NORMAL ) { pDBRDD->unreference (); return this->sendErrWithEpicsStatus ( @@ -942,7 +945,7 @@ caStatus casStrmClient::monitorResponse ( // // force string message size to be the true size // - if ( msg.m_dataType == DBR_STRING && msg.m_count == 1u ) { + if ( msg.m_dataType == DBR_STRING && count == 1u ) { ca_uint32_t reducedPayloadSize = strlen ( static_cast < char * > ( pPayload ) ) + 1u; this->out.commitMsg ( reducedPayloadSize ); } @@ -1950,7 +1953,7 @@ caStatus casStrmClient::eventAddAction ( casChannelI *pciu; { - caStatus status = casStrmClient::verifyRequest ( pciu, true ); + caStatus status = casStrmClient::verifyRequest ( pciu, CA_V413 ( this->minor_version_number ) ); if ( status != ECA_NORMAL ) { if ( pciu ) { return this->sendErr ( guard, mp,