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).
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 );
|
||||
|
||||
Reference in New Issue
Block a user