diff --git a/src/ca/caProto.h b/src/ca/caProto.h index 84190bf56..f61f52e08 100644 --- a/src/ca/caProto.h +++ b/src/ca/caProto.h @@ -41,6 +41,7 @@ # define CA_V410(MINOR) ((MINOR)>=10u) /* beacon counter */ # define CA_V411(MINOR) ((MINOR)>=11u) /* sequence numbers in UDP version command */ # define CA_V412(MINOR) ((MINOR)>=12u) /* TCP-based search requests */ +# define CA_V413(MINOR) ((MINOR)>=13u) /* Allow zero length in requests. */ #elif CA_MAJOR_PROTOCOL_REVISION > 4u # define CA_V41(MINOR) ( 1u ) # define CA_V42(MINOR) ( 1u ) @@ -54,6 +55,7 @@ # define CA_V410(MINOR) ( 1u ) # define CA_V411(MINOR) ( 1u ) # define CA_V412(MINOR) ( 1u ) +# define CA_V413(MINOR) ( 1u ) #else # define CA_V41(MINOR) ( 0u ) # define CA_V42(MINOR) ( 0u ) @@ -67,6 +69,7 @@ # define CA_V410(MINOR) ( 0u ) # define CA_V411(MINOR) ( 0u ) # define CA_V412(MINOR) ( 0u ) +# define CA_V413(MINOR) ( 0u ) #endif /* diff --git a/src/ca/nciu.cpp b/src/ca/nciu.cpp index f61172808..c5ae941b2 100644 --- a/src/ca/nciu.cpp +++ b/src/ca/nciu.cpp @@ -291,9 +291,6 @@ cacChannel::ioStatus nciu::read ( if ( countIn > this->count ) { throw cacChannel::outOfBounds (); } - if ( countIn == 0 ) { - countIn = this->count; - } // // fail out if their arguments are invalid diff --git a/src/ca/nciu.h b/src/ca/nciu.h index 5660a8c85..de070dcea 100644 --- a/src/ca/nciu.h +++ b/src/ca/nciu.h @@ -41,7 +41,7 @@ # include "shareLib.h" #endif -#define CA_MINOR_PROTOCOL_REVISION 12 +#define CA_MINOR_PROTOCOL_REVISION 13 #include "caProto.h" #include "cacIO.h" @@ -205,6 +205,7 @@ public: void disconnectAllIO ( epicsGuard < epicsMutex > &, epicsGuard < epicsMutex > & ); bool connected ( epicsGuard < epicsMutex > & ) const; + unsigned getcount() const { return count; } private: tsDLList < class baseNMIU > eventq; diff --git a/src/ca/netIO.h b/src/ca/netIO.h index b694bc141..57273427a 100644 --- a/src/ca/netIO.h +++ b/src/ca/netIO.h @@ -83,7 +83,7 @@ public: void show ( epicsGuard < epicsMutex > &, unsigned level ) const; arrayElementCount getCount ( - epicsGuard < epicsMutex > & ) const; + epicsGuard < epicsMutex > &, bool allow_zero ) const; unsigned getType ( epicsGuard < epicsMutex > & ) const; unsigned getMask ( @@ -242,11 +242,11 @@ inline netSubscription * netSubscription::factory ( } inline arrayElementCount netSubscription::getCount ( - epicsGuard < epicsMutex > & guard ) const // X aCC 361 + epicsGuard < epicsMutex > & guard, bool allow_zero ) const // X aCC 361 { //guard.assertIdenticalMutex ( this->mutex ); arrayElementCount nativeCount = this->privateChanForIO.nativeElementCount ( guard ); - if ( this->count == 0u || this->count > nativeCount ) { + if ( (this->count == 0u && !allow_zero) || this->count > nativeCount ) { return nativeCount; } else { diff --git a/src/ca/oldChannelNotify.cpp b/src/ca/oldChannelNotify.cpp index 48ddde124..8865f8d63 100644 --- a/src/ca/oldChannelNotify.cpp +++ b/src/ca/oldChannelNotify.cpp @@ -280,6 +280,9 @@ int epicsShareAPI ca_array_get ( chtype type, if ( type < 0 ) { return ECA_BADTYPE; } + if ( count == 0 ) + return ECA_BADCOUNT; + unsigned tmpType = static_cast < unsigned > ( type ); epicsGuard < epicsMutex > guard ( pChan->cacCtx.mutexRef () ); pChan->eliminateExcessiveSendBacklog ( guard ); diff --git a/src/ca/tcpiiu.cpp b/src/ca/tcpiiu.cpp index 214b0687c..20e2abc3b 100644 --- a/src/ca/tcpiiu.cpp +++ b/src/ca/tcpiiu.cpp @@ -1464,6 +1464,8 @@ void tcpiiu::readNotifyRequest ( epicsGuard < epicsMutex > & guard, // X aCC 431 if ( nElem > maxElem ) { throw cacChannel::msgBodyCacheTooSmall (); } + if (nElem == 0 && !CA_V413(this->minorProtocolVersion)) + nElem = chan.getcount(); comQueSendMsgMinder minder ( this->sendQue, guard ); this->sendQue.insertRequestHeader ( CA_PROTO_READ_NOTIFY, 0u, @@ -1559,7 +1561,8 @@ void tcpiiu::subscriptionRequest ( if ( mask > 0xffff ) { throw cacChannel::badEventSelection (); } - arrayElementCount nElem = subscr.getCount ( guard ); + arrayElementCount nElem = subscr.getCount ( + guard, CA_V413(this->minorProtocolVersion) ); arrayElementCount maxBytes; if ( CA_V49 ( this->minorProtocolVersion ) ) { maxBytes = this->cacRef.largeBufferSizeTCP (); @@ -1605,7 +1608,8 @@ void tcpiiu::subscriptionUpdateRequest ( if ( this->state != iiucs_connected ) { return; } - arrayElementCount nElem = subscr.getCount ( guard ); + arrayElementCount nElem = subscr.getCount ( + guard, CA_V413(this->minorProtocolVersion) ); arrayElementCount maxBytes; if ( CA_V49 ( this->minorProtocolVersion ) ) { maxBytes = this->cacRef.largeBufferSizeTCP (); @@ -1643,7 +1647,8 @@ void tcpiiu::subscriptionCancelRequest ( epicsGuard < epicsMutex > & guard, // X this->sendQue.insertRequestHeader ( CA_PROTO_EVENT_CANCEL, 0u, static_cast < ca_uint16_t > ( subscr.getType ( guard ) ), - static_cast < ca_uint16_t > ( subscr.getCount ( guard ) ), + static_cast < ca_uint16_t > ( subscr.getCount ( + guard, CA_V413(this->minorProtocolVersion) ) ), chan.getSID(guard), subscr.getId(), CA_V49 ( this->minorProtocolVersion ) ); minder.commit ();