PageRenderTime 54ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/ATF2/control-software/epics-3.14.10/support/sncseq-2-0-12/src/pv/pvCa.cc

http://atf2flightsim.googlecode.com/
C++ | 854 lines | 473 code | 70 blank | 311 comment | 70 complexity | 7d6f449222852e06ffa8f5dfc9fed747 MD5 | raw file
Possible License(s): BSD-2-Clause, LGPL-2.0, IPL-1.0, BSD-3-Clause
  1. /* pvCa.cc,v 1.7 2001/10/04 18:33:25 jhill Exp
  2. *
  3. * Implementation of EPICS sequencer CA library (pvCa)
  4. *
  5. * William Lupton, W. M. Keck Observatory
  6. */
  7. #include <stdio.h>
  8. #include <string.h>
  9. #include "alarm.h"
  10. #include "cadef.h"
  11. #define epicsExportSharedSymbols
  12. #include "pvCa.h"
  13. /* handlers */
  14. extern "C" {
  15. void pvCaConnectionHandler( struct connection_handler_args args );
  16. void pvCaAccessHandler( struct event_handler_args args );
  17. void pvCaMonitorHandler( struct event_handler_args args );
  18. }
  19. /* utilities */
  20. static pvSevr sevrFromCA( int status ); /* CA severity as pvSevr */
  21. static pvSevr sevrFromEPICS( int sevr );
  22. /* EPICS severity as pvSevr */
  23. static pvStat statFromCA( int status ); /* CA status as pvStat */
  24. static pvStat statFromEPICS( int stat );
  25. /* EPICS status as pvStat */
  26. static pvType typeFromCA( int type ); /* DBR type as pvType */
  27. static int typeToCA( pvType type ); /* pvType as DBR type */
  28. static void copyToCA( pvType type, int count,
  29. const pvValue *value, union db_access_val *caValue );
  30. /* copy pvValue to DBR value */
  31. static void copyFromCA( int type, int count,
  32. const union db_access_val *caValue, pvValue *value );
  33. /* copy DBR value to pvValue */
  34. /* invoke CA function and send error details to system or variable object */
  35. #define INVOKE(_function) \
  36. do { \
  37. int _status = _function; \
  38. if ( _status & CA_M_SUCCESS ) \
  39. setStat( pvStatOK ); \
  40. else \
  41. setError( _status, sevrFromCA( _status ), \
  42. statFromCA( _status ), ca_message( _status ) ); \
  43. } while ( FALSE )
  44. ////////////////////////////////////////////////////////////////////////////////
  45. /*+
  46. * Routine: caSystem::caSystem
  47. *
  48. * Purpose: caSystem constructor
  49. *
  50. * Description:
  51. */
  52. epicsShareFunc caSystem::caSystem( int debug ) :
  53. pvSystem( debug ),
  54. context_( NULL )
  55. {
  56. if ( getDebug() > 0 )
  57. printf( "%8p: caSystem::caSystem( %d )\n", this, debug );
  58. INVOKE( ca_context_create(ca_enable_preemptive_callback) );
  59. this->context_ = ca_current_context ();
  60. }
  61. /*+
  62. * Routine: caSystem::~caSystem
  63. *
  64. * Purpose: caSystem destructor
  65. *
  66. * Description:
  67. */
  68. epicsShareFunc caSystem::~caSystem()
  69. {
  70. if ( getDebug() > 0 )
  71. printf( "%8p: caSystem::~caSystem()\n", this );
  72. INVOKE( ca_task_exit() );
  73. }
  74. /*+
  75. * Routine: caSystem::attach
  76. *
  77. * Purpose: caSystem attach to context of creator of caSystem
  78. *
  79. * Description:
  80. */
  81. epicsShareFunc pvStat caSystem::attach()
  82. {
  83. if ( getDebug() > 0 )
  84. printf( "%8p: caSystem::attach()\n", this );
  85. INVOKE( ca_attach_context( context_ ) );
  86. return getStat();
  87. }
  88. /*+
  89. * Routine: caSystem::flush
  90. *
  91. * Purpose: caSystem flush routine
  92. *
  93. * Description:
  94. */
  95. epicsShareFunc pvStat caSystem::flush()
  96. {
  97. if ( getDebug() > 0 )
  98. printf( "%8p: caSystem::flush()\n", this );
  99. INVOKE( ca_flush_io() );
  100. return getStat();
  101. }
  102. /*+
  103. * Routine: caSystem::pend
  104. *
  105. * Purpose: caSystem pend routine
  106. *
  107. * Description:
  108. */
  109. epicsShareFunc pvStat caSystem::pend( double seconds, int wait )
  110. {
  111. if ( getDebug() > 1 )
  112. printf( "%8p: caSystem::pend( %g, %d )\n", this, seconds, wait );
  113. if ( seconds <= 0.0 || !wait ) seconds = 1e-8;
  114. INVOKE( ca_pend_event( seconds ) );
  115. return getStat();
  116. }
  117. /*+
  118. * Routine: caSystem::newVariable
  119. *
  120. * Purpose: caSystem variable creation routine
  121. *
  122. * Description:
  123. */
  124. epicsShareFunc pvVariable *caSystem::newVariable( const char *name, pvConnFunc func, void *priv,
  125. int debug )
  126. {
  127. if ( getDebug() > 0 )
  128. printf( "%8p: caSystem::newVariable( %s, %p, %p, %d )\n",
  129. this, name, func, priv, debug );
  130. return new caVariable( this, name, func, priv, debug );
  131. }
  132. ////////////////////////////////////////////////////////////////////////////////
  133. /*+
  134. * Routine: caVariable::caVariable
  135. *
  136. * Purpose: caVariable constructor
  137. *
  138. * Description:
  139. */
  140. epicsShareFunc caVariable::caVariable( caSystem *system, const char *name, pvConnFunc func,
  141. void *priv, int debug ) :
  142. pvVariable( system, name, func, priv, debug ),
  143. chid_( NULL )
  144. {
  145. if ( getDebug() > 0 )
  146. printf( "%8p: caVariable::caVariable( %s, %d )\n",
  147. this, name, debug );
  148. if ( getFunc() != NULL )
  149. INVOKE( ca_search_and_connect( name, &chid_, pvCaConnectionHandler, this ));
  150. else
  151. INVOKE( ca_search_and_connect( name, &chid_, NULL, NULL ));
  152. }
  153. /*+
  154. * Routine: caVariable::~caVariable
  155. *
  156. * Purpose: caVariable destructor
  157. *
  158. * Description:
  159. */
  160. epicsShareFunc caVariable::~caVariable()
  161. {
  162. if ( getDebug() > 0 )
  163. printf( "%8p: caVariable::~caVariable()\n", this );
  164. INVOKE( ca_clear_channel( chid_ ) );
  165. }
  166. /*+
  167. * Routine: caVariable::get
  168. *
  169. * Purpose: caVariable blocking get routine
  170. *
  171. * Description:
  172. */
  173. epicsShareFunc pvStat caVariable::get( pvType type, int count, pvValue *value )
  174. {
  175. if ( getDebug() > 0 )
  176. printf( "%8p: caVariable::get( %d, %d )\n", this, type, count );
  177. int caType = typeToCA( type );
  178. char *caValue = new char[dbr_size_n( caType, count )];
  179. INVOKE( ca_array_get( caType, count, chid_, caValue ) );
  180. // ### must block so can convert value; should use ca_get_callback()
  181. if ( getStat() == pvStatOK )
  182. INVOKE( ca_pend_io( 5.0 ) );
  183. if ( getStat() == pvStatOK )
  184. copyFromCA( caType, count, ( union db_access_val * ) caValue, value );
  185. delete [] caValue;
  186. return getStat();
  187. }
  188. /*+
  189. * Routine: caVariable::getNoBlock
  190. *
  191. * Purpose: caVariable non-blocking get routine
  192. *
  193. * Description:
  194. */
  195. epicsShareFunc pvStat caVariable::getNoBlock( pvType type, int count, pvValue *value )
  196. {
  197. if ( getDebug() > 0 )
  198. printf( "%8p: caVariable::getNoBlock( %d, %d )\n", this,
  199. type, count );
  200. // ### must block so can convert value; should use ca_get_callback()
  201. return get( type, count, value );
  202. }
  203. /*+
  204. * Routine: caVariable::getCallback
  205. *
  206. * Purpose: caVariable get with callback routine
  207. *
  208. * Description:
  209. */
  210. epicsShareFunc pvStat caVariable::getCallback( pvType type, int count,
  211. pvEventFunc func, void *arg )
  212. {
  213. if ( getDebug() > 0 )
  214. printf( "%8p: caVariable::getCallback( %d, %d )\n",
  215. this, type, count );
  216. pvCallback *callback = new pvCallback( this, type, count, func, arg,
  217. getDebug() );
  218. INVOKE( ca_array_get_callback( typeToCA( type ), count, chid_,
  219. pvCaAccessHandler, callback ) );
  220. return getStat();
  221. }
  222. /*+
  223. * Routine: caVariable::put
  224. *
  225. * Purpose: caVariable blocking put routine
  226. *
  227. * Description:
  228. */
  229. epicsShareFunc pvStat caVariable::put( pvType type, int count, pvValue *value )
  230. {
  231. if ( getDebug() > 0 )
  232. printf( "%8p: caVariable::put( %d, %d )\n", this, type, count );
  233. int caType = typeToCA( type );
  234. char *caValue = new char[dbr_size_n( caType, count )];
  235. copyToCA( type, count, value, ( union db_access_val * ) caValue );
  236. INVOKE( ca_array_put( caType, count, chid_, caValue ) );
  237. if ( getStat() == pvStatOK )
  238. INVOKE( ca_pend_io( 5.0 ) );
  239. delete [] caValue;
  240. return getStat();
  241. }
  242. /*+
  243. * Routine: caVariable::putNoBlock
  244. *
  245. * Purpose: caVariable non-blocking put routine
  246. *
  247. * Description:
  248. */
  249. epicsShareFunc pvStat caVariable::putNoBlock( pvType type, int count, pvValue *value )
  250. {
  251. if ( getDebug() > 0 )
  252. printf( "%8p: caVariable::putNoBlock( %d, %d )\n", this,
  253. type, count );
  254. int caType = typeToCA( type );
  255. char *caValue = new char[dbr_size_n( caType, count )];
  256. copyToCA( type, count, value, ( union db_access_val * ) caValue );
  257. INVOKE( ca_array_put( caType, count, chid_, caValue ) );
  258. delete [] caValue;
  259. return getStat();
  260. }
  261. /*+
  262. * Routine: caVariable::putCallback
  263. *
  264. * Purpose: caVariable put with callback routine
  265. *
  266. * Description:
  267. */
  268. epicsShareFunc pvStat caVariable::putCallback( pvType type, int count, pvValue *value,
  269. pvEventFunc func, void *arg )
  270. {
  271. if ( getDebug() > 0 )
  272. printf( "%8p: caVariable::putCallback( %d, %d )\n",
  273. this, type, count );
  274. pvCallback *callback = new pvCallback( this, type, count, func, arg,
  275. getDebug() );
  276. INVOKE( ca_array_put_callback( typeToCA( type ), count, chid_, value,
  277. pvCaAccessHandler, callback ) );
  278. return getStat();
  279. }
  280. /*+
  281. * Routine: caVariable::monitorOn
  282. *
  283. * Purpose: caVariable monitor enable routine
  284. *
  285. * Description:
  286. */
  287. epicsShareFunc pvStat caVariable::monitorOn( pvType type, int count, pvEventFunc func,
  288. void *arg, pvCallback **pCallback )
  289. {
  290. if ( getDebug() > 0 )
  291. printf( "%8p: caVariable::monitorOn( %d, %d )\n",
  292. this, type, count );
  293. pvCallback *callback = new pvCallback( this, type, count, func, arg,
  294. getDebug() );
  295. evid id = NULL;
  296. INVOKE( ca_add_masked_array_event( typeToCA( type ), count, chid_,
  297. pvCaMonitorHandler, callback, 0.0, 0.0, 0.0,
  298. &id, DBE_VALUE|DBE_ALARM ) );
  299. callback->setPrivate( id );
  300. if ( pCallback != NULL )
  301. *pCallback = callback;
  302. return getStat();
  303. }
  304. /*+
  305. * Routine: caVariable::monitorOff
  306. *
  307. * Purpose: caVariable monitor disable routine
  308. *
  309. * Description:
  310. */
  311. epicsShareFunc pvStat caVariable::monitorOff( pvCallback *callback )
  312. {
  313. if ( getDebug() > 0 )
  314. printf( "%8p: caVariable::monitorOff()\n", this );
  315. if ( callback != NULL ) {
  316. evid id = ( evid ) callback->getPrivate();
  317. INVOKE( ca_clear_event( id ) );
  318. delete callback;
  319. return getStat();
  320. } else {
  321. return pvStatOK;
  322. }
  323. }
  324. /*+
  325. * Routine: caVariable::getConnected
  326. *
  327. * Purpose: caVariable "are we connected?" routine
  328. *
  329. * Description:
  330. */
  331. epicsShareFunc int caVariable::getConnected() const
  332. {
  333. if ( getDebug() > 1 )
  334. printf( "%8p: caVariable::getConnected()\n", this );
  335. return ( ca_state( chid_ ) == cs_conn );
  336. }
  337. /*+
  338. * Routine: caVariable::getType
  339. *
  340. * Purpose: caVariable "what type are we?" routine
  341. *
  342. * Description:
  343. */
  344. epicsShareFunc pvType caVariable::getType() const
  345. {
  346. if ( getDebug() > 1 )
  347. printf( "%8p: caVariable::getType()\n", this );
  348. return typeFromCA( ca_field_type( chid_ ) );
  349. }
  350. /*+
  351. * Routine: caVariable::getCount
  352. *
  353. * Purpose: caVariable "what count do we have?" routine
  354. *
  355. * Description:
  356. */
  357. epicsShareFunc int caVariable::getCount() const
  358. {
  359. if ( getDebug() > 1 )
  360. printf( "%8p: caVariable::getCount()\n", this );
  361. return ca_element_count( chid_ );
  362. }
  363. ////////////////////////////////////////////////////////////////////////////////
  364. /*+
  365. * Routine: pvCaConnectionHandler
  366. *
  367. * Purpose: CA connection handler
  368. *
  369. * Description:
  370. */
  371. void pvCaConnectionHandler( struct connection_handler_args args )
  372. {
  373. pvVariable *variable = ( pvVariable * ) ca_puser( args.chid );
  374. pvConnFunc func = variable->getFunc();
  375. ( *func ) ( ( void * ) variable, ( args.op == CA_OP_CONN_UP ) );
  376. }
  377. /*+
  378. * Routine: pvCaAccessHandler
  379. *
  380. * Purpose: CA get/put callback event handler
  381. *
  382. * Description:
  383. */
  384. void pvCaAccessHandler( struct event_handler_args args )
  385. {
  386. pvCaMonitorHandler( args );
  387. pvCallback *callback = ( pvCallback * ) args.usr;
  388. delete callback;
  389. }
  390. /*+
  391. * Routine: pvCaMonitorHandler
  392. *
  393. * Purpose: CA monitor event handler
  394. *
  395. * Description:
  396. */
  397. void pvCaMonitorHandler( struct event_handler_args args )
  398. {
  399. pvCallback *callback = ( pvCallback * ) args.usr;
  400. pvEventFunc func = callback->getFunc();
  401. pvVariable *variable = callback->getVariable();
  402. pvType type = callback->getType();
  403. int count = callback->getCount();
  404. void *arg = callback->getArg();
  405. // put completion messages pass a NULL value
  406. if ( args.dbr == NULL ) {
  407. ( *func ) ( ( void * ) variable, type, count, NULL, arg,
  408. statFromCA( args.status ) );
  409. } else {
  410. pvValue *value = new pvValue[count]; // ### larger than needed
  411. copyFromCA( args.type, args.count, ( union db_access_val * ) args.dbr,
  412. value );
  413. // ### should assert args.type is equiv to type and args.count is count
  414. ( *func ) ( ( void * ) variable, type, count, value, arg,
  415. statFromCA( args.status ) );
  416. delete [] value;
  417. }
  418. }
  419. ////////////////////////////////////////////////////////////////////////////////
  420. /*+
  421. * Routine: sevrFromCA
  422. *
  423. * Purpose: extract pvSevr from CA status
  424. *
  425. * Description:
  426. */
  427. static pvSevr sevrFromCA( int status )
  428. {
  429. switch ( CA_EXTRACT_SEVERITY( status ) ) {
  430. case CA_K_INFO: return pvSevrNONE;
  431. case CA_K_SUCCESS: return pvSevrNONE;
  432. case CA_K_WARNING: return pvSevrMINOR;
  433. case CA_K_ERROR: return pvSevrMAJOR;
  434. case CA_K_SEVERE: return pvSevrINVALID;
  435. default: return pvSevrERROR;
  436. }
  437. }
  438. /*+
  439. * Routine: sevrFromEPICS
  440. *
  441. * Purpose: extract pvSevr from EPICS severity
  442. *
  443. * Description:
  444. */
  445. static pvSevr sevrFromEPICS( int sevr )
  446. {
  447. switch ( sevr ) {
  448. case NO_ALARM: return pvSevrNONE;
  449. case MINOR_ALARM: return pvSevrMINOR;
  450. case MAJOR_ALARM: return pvSevrMAJOR;
  451. case INVALID_ALARM: return pvSevrINVALID;
  452. default: return pvSevrERROR;
  453. }
  454. }
  455. /*+
  456. * Routine: statFromCA
  457. *
  458. * Purpose: extract pvStat from CA status
  459. *
  460. * Description:
  461. */
  462. static pvStat statFromCA( int status )
  463. {
  464. pvSevr sevr = sevrFromCA( status );
  465. return ( sevr == pvSevrNONE || sevr == pvSevrMINOR ) ?
  466. pvStatOK : pvStatERROR;
  467. }
  468. /*+
  469. * Routine: statFromEPICS
  470. *
  471. * Purpose: extract pvStat from EPICS status
  472. *
  473. * Description:
  474. */
  475. static pvStat statFromEPICS( int stat )
  476. {
  477. switch ( stat ) {
  478. case NO_ALARM: return pvStatOK;
  479. case READ_ALARM: return pvStatREAD;
  480. case WRITE_ALARM: return pvStatWRITE;
  481. case HIHI_ALARM: return pvStatHIHI;
  482. case HIGH_ALARM: return pvStatHIGH;
  483. case LOLO_ALARM: return pvStatLOLO;
  484. case LOW_ALARM: return pvStatLOW;
  485. case STATE_ALARM: return pvStatSTATE;
  486. case COS_ALARM: return pvStatCOS;
  487. case COMM_ALARM: return pvStatCOMM;
  488. case TIMEOUT_ALARM: return pvStatTIMEOUT;
  489. case HW_LIMIT_ALARM: return pvStatHW_LIMIT;
  490. case CALC_ALARM: return pvStatCALC;
  491. case SCAN_ALARM: return pvStatSCAN;
  492. case LINK_ALARM: return pvStatLINK;
  493. case SOFT_ALARM: return pvStatSOFT;
  494. case BAD_SUB_ALARM: return pvStatBAD_SUB;
  495. case UDF_ALARM: return pvStatUDF;
  496. case DISABLE_ALARM: return pvStatDISABLE;
  497. case SIMM_ALARM: return pvStatSIMM;
  498. case READ_ACCESS_ALARM: return pvStatREAD_ACCESS;
  499. case WRITE_ACCESS_ALARM: return pvStatWRITE_ACCESS;
  500. default: return pvStatERROR;
  501. }
  502. }
  503. /*+
  504. * Routine: typeFromCA
  505. *
  506. * Purpose: extract pvType from DBR type
  507. *
  508. * Description:
  509. */
  510. static pvType typeFromCA( int type )
  511. {
  512. switch ( type ) {
  513. case DBR_CHAR: return pvTypeCHAR;
  514. case DBR_SHORT: return pvTypeSHORT;
  515. case DBR_ENUM: return pvTypeSHORT;
  516. case DBR_LONG: return pvTypeLONG;
  517. case DBR_FLOAT: return pvTypeFLOAT;
  518. case DBR_DOUBLE: return pvTypeDOUBLE;
  519. case DBR_STRING: return pvTypeSTRING;
  520. case DBR_TIME_CHAR: return pvTypeTIME_CHAR;
  521. case DBR_TIME_SHORT: return pvTypeTIME_SHORT;
  522. case DBR_TIME_ENUM: return pvTypeTIME_SHORT;
  523. case DBR_TIME_LONG: return pvTypeTIME_LONG;
  524. case DBR_TIME_FLOAT: return pvTypeTIME_FLOAT;
  525. case DBR_TIME_DOUBLE: return pvTypeTIME_DOUBLE;
  526. case DBR_TIME_STRING: return pvTypeTIME_STRING;
  527. default: return pvTypeERROR;
  528. }
  529. }
  530. /*+
  531. * Routine: typeToCA
  532. *
  533. * Purpose: extract DBR type from pvType
  534. *
  535. * Description:
  536. */
  537. static int typeToCA( pvType type )
  538. {
  539. switch ( type ) {
  540. case pvTypeCHAR: return DBR_CHAR;
  541. case pvTypeSHORT: return DBR_SHORT;
  542. case pvTypeLONG: return DBR_LONG;
  543. case pvTypeFLOAT: return DBR_FLOAT;
  544. case pvTypeDOUBLE: return DBR_DOUBLE;
  545. case pvTypeSTRING: return DBR_STRING;
  546. case pvTypeTIME_CHAR: return DBR_TIME_CHAR;
  547. case pvTypeTIME_SHORT: return DBR_TIME_SHORT;
  548. case pvTypeTIME_LONG: return DBR_TIME_LONG;
  549. case pvTypeTIME_FLOAT: return DBR_TIME_FLOAT;
  550. case pvTypeTIME_DOUBLE: return DBR_TIME_DOUBLE;
  551. case pvTypeTIME_STRING: return DBR_TIME_STRING;
  552. default: return -1;
  553. }
  554. }
  555. /*+
  556. * Routine: copyToCA
  557. *
  558. * Purpose: copy pvValue to DBR value
  559. *
  560. * Description:
  561. */
  562. static void copyToCA( pvType type, int count,
  563. const pvValue *value, union db_access_val *caValue )
  564. {
  565. // ### inefficient to do all this here
  566. dbr_char_t *charval = (dbr_char_t *) dbr_value_ptr(caValue, DBR_CHAR );
  567. dbr_short_t *shrtval = (dbr_short_t *) dbr_value_ptr(caValue, DBR_SHORT );
  568. dbr_long_t *longval = (dbr_long_t *) dbr_value_ptr(caValue, DBR_LONG );
  569. dbr_float_t *fltval = (dbr_float_t *) dbr_value_ptr(caValue, DBR_FLOAT );
  570. dbr_double_t*doubleval= (dbr_double_t *) dbr_value_ptr(caValue, DBR_DOUBLE);
  571. dbr_string_t*strval = (dbr_string_t *) dbr_value_ptr(caValue, DBR_STRING);
  572. int s = sizeof( dbr_string_t );
  573. int i;
  574. switch ( type ) {
  575. case pvTypeCHAR:
  576. for ( i = 0; i < count; i++ )
  577. charval[i] = value->charVal[i];
  578. break;
  579. case pvTypeSHORT:
  580. for ( i = 0; i < count; i++ )
  581. shrtval[i] = value->shortVal[i];
  582. break;
  583. case pvTypeLONG:
  584. for ( i = 0; i < count; i++ )
  585. longval[i] = value->longVal[i];
  586. break;
  587. case pvTypeFLOAT:
  588. for ( i = 0; i < count; i++ )
  589. fltval[i] = value->floatVal[i];
  590. break;
  591. case pvTypeDOUBLE:
  592. for ( i = 0; i < count; i++ )
  593. doubleval[i] = value->doubleVal[i];
  594. break;
  595. case pvTypeSTRING:
  596. for ( i = 0; i < count; i++ ) {
  597. strncpy( strval[i], value->stringVal[i], s );
  598. strval[i][s-1] = '\0';
  599. }
  600. break;
  601. default:
  602. // ### no check for invalid types
  603. // ### assume that no TIME_XXX types are written to CA
  604. break;
  605. }
  606. }
  607. /*+
  608. * Routine: copyFromCA
  609. *
  610. * Purpose: copy DBR value to pvValue
  611. *
  612. * Description:
  613. */
  614. static void copyFromCA( int type, int count,
  615. const union db_access_val *caValue, pvValue *value )
  616. {
  617. // ### inefficient to do all this here
  618. dbr_char_t *charval = (dbr_char_t *) dbr_value_ptr(caValue, DBR_CHAR );
  619. dbr_short_t *shrtval = (dbr_short_t *) dbr_value_ptr(caValue, DBR_SHORT );
  620. dbr_long_t *longval = (dbr_long_t *) dbr_value_ptr(caValue, DBR_LONG );
  621. dbr_float_t *fltval = (dbr_float_t *) dbr_value_ptr(caValue, DBR_FLOAT );
  622. dbr_double_t*doubleval= (dbr_double_t *) dbr_value_ptr(caValue, DBR_DOUBLE);
  623. dbr_string_t*strval = (dbr_string_t *) dbr_value_ptr(caValue, DBR_STRING);
  624. dbr_char_t *tchrval = (dbr_char_t *) dbr_value_ptr(caValue, DBR_TIME_CHAR );
  625. dbr_short_t *tshrtval = (dbr_short_t *) dbr_value_ptr(caValue, DBR_TIME_SHORT );
  626. dbr_long_t *tlngval = (dbr_long_t *) dbr_value_ptr(caValue, DBR_TIME_LONG );
  627. dbr_float_t *tfltval = (dbr_float_t *) dbr_value_ptr(caValue, DBR_TIME_FLOAT );
  628. dbr_double_t*tdblval = (dbr_double_t *) dbr_value_ptr(caValue, DBR_TIME_DOUBLE);
  629. dbr_string_t*tstrval = (dbr_string_t *) dbr_value_ptr(caValue, DBR_TIME_STRING);
  630. int s = sizeof( pvString );
  631. int i;
  632. switch ( type ) {
  633. case DBR_CHAR:
  634. for ( i = 0; i < count; i++ )
  635. value->charVal[i] = charval[i];
  636. break;
  637. case DBR_SHORT:
  638. case DBR_ENUM:
  639. for ( i = 0; i < count; i++ )
  640. value->shortVal[i] = shrtval[i];
  641. break;
  642. case DBR_LONG:
  643. for ( i = 0; i < count; i++ )
  644. value->longVal[i] = longval[i];
  645. break;
  646. case DBR_FLOAT:
  647. for ( i = 0; i < count; i++ )
  648. value->floatVal[i] = fltval[i];
  649. break;
  650. case DBR_DOUBLE:
  651. for ( i = 0; i < count; i++ )
  652. value->doubleVal[i] = doubleval[i];
  653. break;
  654. case DBR_STRING:
  655. for ( i = 0; i < count; i++ ) {
  656. strncpy( value->stringVal[i], strval[i], s );
  657. value->stringVal[i][s-1] = '\0';
  658. }
  659. break;
  660. case DBR_TIME_CHAR:
  661. value->timeCharVal.status = statFromEPICS( caValue->tchrval.status );
  662. value->timeCharVal.severity = sevrFromEPICS( caValue->tchrval.severity);
  663. value->timeCharVal.stamp = caValue->tchrval.stamp;
  664. for ( i = 0; i < count; i++ )
  665. value->timeCharVal.value[i] = tchrval[i];
  666. break;
  667. case DBR_TIME_SHORT:
  668. case DBR_TIME_ENUM:
  669. value->timeShortVal.status = statFromEPICS( caValue->tshrtval.status );
  670. value->timeShortVal.severity =sevrFromEPICS(caValue->tshrtval.severity);
  671. value->timeShortVal.stamp = caValue->tshrtval.stamp;
  672. for ( i = 0; i < count; i++ )
  673. value->timeShortVal.value[i] = tshrtval[i];
  674. break;
  675. case DBR_TIME_LONG:
  676. value->timeLongVal.status = statFromEPICS( caValue->tlngval.status );
  677. value->timeLongVal.severity = sevrFromEPICS( caValue->tlngval.severity);
  678. value->timeLongVal.stamp = caValue->tlngval.stamp;
  679. for ( i = 0; i < count; i++ )
  680. value->timeLongVal.value[i] = tlngval[i];
  681. break;
  682. case DBR_TIME_FLOAT:
  683. value->timeFloatVal.status = statFromEPICS( caValue->tfltval.status );
  684. value->timeFloatVal.severity = sevrFromEPICS(caValue->tfltval.severity);
  685. value->timeFloatVal.stamp = caValue->tfltval.stamp;
  686. for ( i = 0; i < count; i++ )
  687. value->timeFloatVal.value[i] = tfltval[i];
  688. break;
  689. case DBR_TIME_DOUBLE:
  690. value->timeDoubleVal.status = statFromEPICS( caValue->tdblval.status );
  691. value->timeDoubleVal.severity =sevrFromEPICS(caValue->tdblval.severity);
  692. value->timeDoubleVal.stamp = caValue->tdblval.stamp;
  693. for ( i = 0; i < count; i++ )
  694. value->timeDoubleVal.value[i] = tdblval[i];
  695. break;
  696. case DBR_TIME_STRING:
  697. value->timeStringVal.status = statFromEPICS( caValue->tstrval.status );
  698. value->timeStringVal.severity =sevrFromEPICS(caValue->tstrval.severity);
  699. value->timeStringVal.stamp = caValue->tstrval.stamp;
  700. for ( i = 0; i < count; i++ ) {
  701. strncpy( value->timeStringVal.value[i], tstrval[i], s );
  702. value->timeStringVal.value[i][s-1] = '\0';
  703. }
  704. break;
  705. default:
  706. // ### no check for invalid types
  707. break;
  708. }
  709. }
  710. /*
  711. * pvCa.cc,v
  712. * Revision 1.7 2001/10/04 18:33:25 jhill
  713. * context_ variable wasnt initialized
  714. *
  715. * Revision 1.6 2001/07/05 14:42:15 mrk
  716. * ca changed client contect
  717. *
  718. * Revision 1.5 2001/03/21 19:42:45 mrk
  719. * handlers must be C callable and external to satisfy all compilers
  720. *
  721. * Revision 1.4 2001/03/21 15:03:35 mrk
  722. * declare extern "C"
  723. *
  724. * Revision 1.3 2001/03/09 21:11:51 mrk
  725. * ca_pend no longer exists
  726. *
  727. * Revision 1.2 2000/04/14 21:53:28 jba
  728. * Changes for win32 build.
  729. *
  730. * Revision 1.1.1.1 2000/04/04 03:22:14 wlupton
  731. * first commit of seq-2-0-0
  732. *
  733. * Revision 1.17 2000/03/29 01:59:38 wlupton
  734. * accounted for possibility of NULL args.dbr in callback
  735. *
  736. * Revision 1.16 2000/03/18 04:00:25 wlupton
  737. * converted to use new configure scheme
  738. *
  739. * Revision 1.15 2000/03/16 02:11:28 wlupton
  740. * supported KTL_ANYPOLY (plus misc other mods)
  741. *
  742. * Revision 1.14 2000/03/07 19:55:32 wlupton
  743. * nearly sufficient tidying up
  744. *
  745. * Revision 1.13 2000/03/07 09:27:39 wlupton
  746. * drastically reduced use of references
  747. *
  748. * Revision 1.12 2000/03/07 08:46:29 wlupton
  749. * created ktlKeyword class (works but a bit messy)
  750. *
  751. * Revision 1.11 2000/03/06 19:20:22 wlupton
  752. * only set error on failure; tidy error reporting
  753. *
  754. * Revision 1.10 2000/03/01 02:07:14 wlupton
  755. * converted to use new OSI library
  756. *
  757. * Revision 1.9 2000/02/19 01:11:33 wlupton
  758. * changed INVOKE to operate on current object (sys or var)
  759. *
  760. * Revision 1.8 2000/02/16 02:31:44 wlupton
  761. * merged in v1.9.5 changes
  762. *
  763. * Revision 1.7 1999/07/07 18:50:33 wlupton
  764. * supported full mapping from EPICS status and severity to pvStat and pvSevr
  765. *
  766. * Revision 1.6 1999/07/01 20:50:19 wlupton
  767. * Working under VxWorks
  768. *
  769. * Revision 1.5 1999/06/15 10:11:03 wlupton
  770. * demo sequence mostly working with KTL
  771. *
  772. * Revision 1.4 1999/06/10 00:35:04 wlupton
  773. * demo sequencer working with pvCa
  774. *
  775. * Revision 1.3 1999/06/08 19:21:44 wlupton
  776. * CA version working; about to use in sequencer
  777. *
  778. * Revision 1.2 1999/06/08 03:25:21 wlupton
  779. * nearly complete CA implementation
  780. *
  781. * Revision 1.1 1999/06/07 21:46:45 wlupton
  782. * working with simple pvtest program
  783. *
  784. */