Merged commit 12741 from Michael's pcas-fake-dynamic branch

This commit is contained in:
Andrew Johnson
2016-10-10 15:12:26 -05:00
parent 928ebe82bd
commit 6e2705c23f
5 changed files with 31 additions and 11 deletions

View File

@@ -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

View File

@@ -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;

View File

@@ -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

View File

@@ -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,

View File

@@ -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];