From 2774b4c4affcbd84165fab05deffb131a6d3a9ce Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Wed, 22 Apr 2015 16:51:31 -0500 Subject: [PATCH] Fix type problem with local CA channels This commit fixes a problem introduced in Bazaar commit 12658. Local CA channels were seeing the data type of a channel as an IOC-specific (dbFldTypes.h) type value instead of the CA type value from db_access.h. We introduce a pair of dbChannel*CAType() macros which convert the dbChannel's dbr_field_type and final_type values into the CA equivalent type values, and use these macros whenever the CA encoded field type value is needed. This ensures that the meaning of the dbChannel member fields never changes (in 3.14 the addr.dbr_field_type was overwritten with the converted value when connected to by rsrv). --- src/ioc/db/dbChannel.h | 7 ++++++- src/ioc/db/dbChannelIO.cpp | 4 ++-- src/ioc/db/db_access.c | 17 ++--------------- src/ioc/db/db_test.c | 4 ++-- src/ioc/rsrv/camessage.c | 6 +++--- 5 files changed, 15 insertions(+), 23 deletions(-) diff --git a/src/ioc/db/dbChannel.h b/src/ioc/db/dbChannel.h index 2d7dc6727..fab9c6627 100644 --- a/src/ioc/db/dbChannel.h +++ b/src/ioc/db/dbChannel.h @@ -154,6 +154,8 @@ epicsShareFunc long dbChannelTest(const char *name); epicsShareFunc dbChannel * dbChannelCreate(const char *name); epicsShareFunc long dbChannelOpen(dbChannel *chan); +/*Following is also defined in db_convert.h*/ +epicsShareExtern unsigned short dbDBRnewToDBRold[]; /* In the following macros pChan is dbChannel* */ @@ -175,6 +177,9 @@ epicsShareFunc long dbChannelOpen(dbChannel *chan); /* evaluates to short */ #define dbChannelExportType(pChan) ((pChan)->addr.dbr_field_type) +/* evaluates to short */ +#define dbChannelExportCAType(pChan) (dbDBRnewToDBRold[dbChannelExportType(pChan)]) + /* evaluates to short */ #define dbChannelFieldSize(pChan) ((pChan)->addr.field_size) @@ -185,7 +190,7 @@ epicsShareFunc long dbChannelOpen(dbChannel *chan); #define dbChannelFinalFieldType(pChan) ((pChan)->final_type) /* evaluates to short */ -#define dbChannelFinalExportType(pChan) ((pChan)->final_type) +#define dbChannelFinalCAType(pChan) (dbDBRnewToDBRold[(pChan)->final_type]) /* evaluates to short */ #define dbChannelFinalFieldSize(pChan) ((pChan)->final_field_size) diff --git a/src/ioc/db/dbChannelIO.cpp b/src/ioc/db/dbChannelIO.cpp index 475d31943..6ac1efbdb 100644 --- a/src/ioc/db/dbChannelIO.cpp +++ b/src/ioc/db/dbChannelIO.cpp @@ -159,7 +159,7 @@ void dbChannelIO::show ( if ( level > 0u ) { printf ( " type %s, element count %li, field at %p\n", - dbf_type_to_text ( dbChannelExportType ( this->dbch ) ), + dbf_type_to_text ( dbChannelExportCAType ( this->dbch ) ), dbChannelElements ( this->dbch ), dbChannelField ( this->dbch ) ); if ( level > 1u ) { @@ -206,7 +206,7 @@ short dbChannelIO::nativeType ( epicsGuard < epicsMutex > & guard ) const { guard.assertIdenticalMutex ( this->mutex ); - return dbChannelExportType( this->dbch ); + return dbChannelExportCAType( this->dbch ); } void * dbChannelIO::operator new ( size_t size, diff --git a/src/ioc/db/db_access.c b/src/ioc/db/db_access.c index c399fdb88..3e957b4ed 100644 --- a/src/ioc/db/db_access.c +++ b/src/ioc/db/db_access.c @@ -99,34 +99,21 @@ #define oldDBR_STSACK_STRING oldDBR_PUT_ACKS + 1 #define oldDBR_CLASS_NAME oldDBR_STSACK_STRING + 1 -/*Following is defined in db_convert.h*/ -extern unsigned short dbDBRnewToDBRold[DBR_ENUM+1]; - typedef char DBSTRING[MAX_STRING_SIZE]; - struct dbChannel * dbChannel_create(const char *pname) { dbChannel *chan = dbChannelCreate(pname); - short ftype; if (!chan) return NULL; - ftype = chan->addr.dbr_field_type; - if (INVALID_DB_REQ(ftype)) { + if (INVALID_DB_REQ(dbChannelExportType(chan)) || + dbChannelOpen(chan)) { dbChannelDelete(chan); return NULL; } - if (dbChannelOpen(chan)) { - dbChannelDelete(chan); - return NULL; - } - - /* Convert final_type to CA's type mapping */ - chan->final_type = dbDBRnewToDBRold[chan->final_type]; - return chan; } diff --git a/src/ioc/db/db_test.c b/src/ioc/db/db_test.c index 30cb831db..4dc26a07d 100644 --- a/src/ioc/db/db_test.c +++ b/src/ioc/db/db_test.c @@ -49,7 +49,7 @@ int gft(const char *pname) precord = dbChannelRecord(chan); elements = dbChannelElements(chan); - type = dbChannelExportType(chan); + type = dbChannelExportCAType(chan); printf(" Record Name: %s\n", precord->name); printf("Record Address: 0x%p\n", precord); @@ -103,7 +103,7 @@ int pft(const char *pname, const char *pvalue) precord = dbChannelRecord(chan); elements = dbChannelElements(chan); - type = dbChannelExportType(chan); + type = dbChannelExportCAType(chan); printf(" Record Name: %s\n", precord->name); printf("Record Address: 0x%p\n", precord); diff --git a/src/ioc/rsrv/camessage.c b/src/ioc/rsrv/camessage.c index 6ade766ed..469c29b80 100644 --- a/src/ioc/rsrv/camessage.c +++ b/src/ioc/rsrv/camessage.c @@ -1255,7 +1255,7 @@ static void claim_ciu_reply ( struct channel_in_use * pciu ) } status = cas_copy_in_header ( pciu->client, CA_PROTO_CREATE_CHAN, 0u, - dbChannelFinalExportType(pciu->dbch), nElem, pciu->cid, + dbChannelFinalCAType(pciu->dbch), nElem, pciu->cid, pciu->sid, NULL ); if ( status == ECA_NORMAL ) { cas_commit_msg ( pciu->client, 0u ); @@ -1301,7 +1301,7 @@ static int claim_ciu_action ( caHdrLargeArray *mp, } DLOG ( 2, ("CAS: claim_ciu_action found '%s', type %d, count %d\n", - pName, dbChannelExportType(dbch), dbChannelElements(dbch)) ); + pName, dbChannelCAType(dbch), dbChannelElements(dbch)) ); pciu = casCreateChannel ( client, @@ -2348,7 +2348,7 @@ static int search_reply_udp ( caHdrLargeArray *mp, void *pPayload, struct client else { count = (ca_uint16_t) dbChannelFinalElements(dbch); } - type = (ca_uint16_t) dbChannelFinalExportType(dbch); + type = (ca_uint16_t) dbChannelFinalCAType(dbch); } SEND_LOCK ( client );