cas: Add real implementation for variable length arrays (Bruce Hill, Matej Sekoranja)
This commit is contained in:
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user