Merged commit 12741 from Michael's pcas-fake-dynamic branch
This commit is contained in:
@@ -13,6 +13,15 @@
|
||||
|
||||
<!-- Insert new items immediately below here ... -->
|
||||
|
||||
<h3>Add dynamic (variable length) array support to PCAS</h3>
|
||||
|
||||
<p>Dynamic array sizing support was added to the IOC server (RSRV) in the
|
||||
Base-3.14.12 release, but has not until now been supported in the <q>Portable
|
||||
Channel Access Server</q> (PCAS). Channel Access server applications using the
|
||||
PCAS will have to be modified slightly to provide full support for variable
|
||||
length arrays, but unmodified applications will continue to build and work as
|
||||
before against this release.</p>
|
||||
|
||||
<h3>Additional epicsTime conversion</h3>
|
||||
|
||||
<p>The EPICS timestamp library (epicsTime) inside libCom's OSI layer has
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
# include "shareLib.h"
|
||||
#endif
|
||||
|
||||
static const unsigned char CA_MINOR_PROTOCOL_REVISION = 12;
|
||||
static const unsigned char CA_MINOR_PROTOCOL_REVISION = 13;
|
||||
|
||||
typedef ca_uint32_t caResId;
|
||||
|
||||
|
||||
@@ -18,6 +18,8 @@
|
||||
|
||||
#include "caHdrLargeArray.h"
|
||||
|
||||
class casStrmClient;
|
||||
|
||||
class casCtx {
|
||||
public:
|
||||
casCtx();
|
||||
@@ -41,6 +43,7 @@ private:
|
||||
casChannelI * pChannel;
|
||||
casPVI * pPV;
|
||||
unsigned nAsyncIO; // checks for improper use of async io
|
||||
friend class casStrmClient;
|
||||
};
|
||||
|
||||
inline const caHdrLargeArray * casCtx::getMsg() const
|
||||
|
||||
@@ -390,14 +390,12 @@ caStatus casStrmClient::echoAction ( epicsGuard < casClientMutex > & )
|
||||
//
|
||||
// casStrmClient::verifyRequest()
|
||||
//
|
||||
caStatus casStrmClient::verifyRequest ( casChannelI * & pChan )
|
||||
caStatus casStrmClient::verifyRequest (casChannelI * & pChan , bool allowdyn)
|
||||
{
|
||||
const caHdrLargeArray * mp = this->ctx.getMsg();
|
||||
|
||||
//
|
||||
// channel exists for this resource id ?
|
||||
//
|
||||
chronIntId tmpId ( mp->m_cid );
|
||||
chronIntId tmpId ( ctx.msg.m_cid );
|
||||
pChan = this->chanTable.lookup ( tmpId );
|
||||
if ( ! pChan ) {
|
||||
return ECA_BADCHID;
|
||||
@@ -406,14 +404,24 @@ caStatus casStrmClient::verifyRequest ( casChannelI * & pChan )
|
||||
//
|
||||
// data type out of range ?
|
||||
//
|
||||
if ( mp->m_dataType > ((unsigned)LAST_BUFFER_TYPE) ) {
|
||||
if ( ctx.msg.m_dataType > ((unsigned)LAST_BUFFER_TYPE) ) {
|
||||
return ECA_BADTYPE;
|
||||
}
|
||||
|
||||
//
|
||||
// element count out of range ?
|
||||
//
|
||||
if ( mp->m_count > pChan->getPVI().nativeCount() || mp->m_count == 0u ) {
|
||||
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 ) {
|
||||
return ECA_BADCOUNT;
|
||||
}
|
||||
|
||||
@@ -446,7 +454,7 @@ caStatus casStrmClient::readAction ( epicsGuard < casClientMutex > & guard )
|
||||
casChannelI * pChan;
|
||||
|
||||
{
|
||||
caStatus status = this->verifyRequest ( pChan );
|
||||
caStatus status = this->verifyRequest ( pChan, true );
|
||||
if ( status != ECA_NORMAL ) {
|
||||
if ( pChan ) {
|
||||
return this->sendErr ( guard, mp, pChan->getCID(),
|
||||
@@ -587,7 +595,7 @@ caStatus casStrmClient::readNotifyAction ( epicsGuard < casClientMutex > & guard
|
||||
casChannelI * pChan;
|
||||
|
||||
{
|
||||
caStatus status = this->verifyRequest ( pChan );
|
||||
caStatus status = this->verifyRequest ( pChan, true );
|
||||
if ( status != ECA_NORMAL ) {
|
||||
return this->readNotifyFailureResponse ( guard, * mp, status );
|
||||
}
|
||||
@@ -1942,7 +1950,7 @@ caStatus casStrmClient::eventAddAction (
|
||||
|
||||
casChannelI *pciu;
|
||||
{
|
||||
caStatus status = casStrmClient::verifyRequest ( pciu );
|
||||
caStatus status = casStrmClient::verifyRequest ( pciu, true );
|
||||
if ( status != ECA_NORMAL ) {
|
||||
if ( pciu ) {
|
||||
return this->sendErr ( guard, mp,
|
||||
|
||||
@@ -69,7 +69,7 @@ private:
|
||||
bool responseIsPending;
|
||||
|
||||
caStatus createChannel ( const char * pName );
|
||||
caStatus verifyRequest ( casChannelI * & pChan );
|
||||
caStatus verifyRequest ( casChannelI * & pChan, bool allowdyn = false );
|
||||
typedef caStatus ( casStrmClient :: * pCASMsgHandler )
|
||||
( epicsGuard < casClientMutex > & );
|
||||
static pCASMsgHandler const msgHandlers[CA_PROTO_LAST_CMMD+1u];
|
||||
|
||||
Reference in New Issue
Block a user