Files
cdev-1.7.2n/doc/html/cdevCbinding.html
2022-12-13 12:44:04 +01:00

700 lines
24 KiB
HTML
Executable File

<! This document generated using mif2html Version 1.0 - Walt Akers - 1996 !>
<head>
<title>CDEV Documentation</title>
</head>
<body bgcolor="#E0E0FF">
<body>
<! ************************ FILE : cdevCbindingTITLE.mif *****************************!>
<br><hr><br>
<table width=100%>
<tr><td>
<! ***** Empty Column ***** !>
</td>
<td valign=top>
<!*** Start ADDRESS ***!><font size=+12 color=Black><strong><em>
CDEV C Binding Guide
<!*** Finish ADDRESS ***!></p></strong></em></font>
<!*** Start ADDRESS-VERSION ***!><font size=+2 color=Black>
</p>
Chip Watson, Jie Chen, Danjin Wu, Walt Akers
</p>
</p>
Version 1.4 October 24, 1996
</p>
</p>
TJNAF - Thomas Jefferson National Accelerator Facility
</p>
<!*** Finish ADDRESS-VERSION ***!></p></font>
</td></tr>
</table>
<! *************************** TABLE OF CONTENTS ****************************!>
<! **************************** LIST OF FIGURES *****************************!>
<! ************************ FILE : ./cdevCbinding.mif *****************************!>
<br><hr><br>
<table width=100%>
<tr><td>
<! ***** Empty Column ***** !>
</td>
<td valign=top align=center>
<!*** Start Title ***!><font size=+5 color=Black><strong>
cdev C Binding
<!*** Finish Title ***!></p></strong></font>
<!*** Start Centered ***!><font size=+2 color=Black>
Updated:
</p>
<!*** Finish Centered ***!></p></font>
</td></tr>
<tr><td>
<! ***** Empty Column ***** !>
</td>
<td valign=top>
<!*** Start Body ***!><font size=+2 color=Black>
This working document describes a C binding to the cdev control system interface (see the cdev
Design Document, and the cdev User's Guide).
<!*** Finish Body ***!></p></font>
<!*** Start Heading1 ***!><font size=+3 color=Black><strong>
Design Choices:
<!*** Finish Heading1 ***!></p></strong></font>
<table>
<tr><td valign=top>
<!*** Start Numbered1 ***!><font size=+2 color=Black>
1.
<!*** Finish Numbered1 ***!></p></font>
</td>
<td valign=top>
<!*** Start Numbered1 ***!><font size=+2 color=Black>
All C routine names begin with &quot;cdev&quot; (common device).
<!*** Finish Numbered1 ***!></p></font>
</td></tr>
<tr><td valign=top>
<!*** Start Numbered ***!><font size=+2 color=Black>
2.
<!*** Finish Numbered ***!></p></font>
</td>
<td valign=top>
<!*** Start Numbered ***!><font size=+2 color=Black>
Most C routines return completion status; 0==success (allows enumerated errors). A few
return integer values (prefixed in this document with &quot;int&quot;).
<!*** Finish Numbered ***!></p></font>
</td></tr>
<tr><td valign=top>
<!*** Start Numbered ***!><font size=+2 color=Black>
3.
<!*** Finish Numbered ***!></p></font>
</td>
<td valign=top>
<!*** Start Numbered ***!><font size=+2 color=Black>
All data passed through the interface will be in the form of integers, strings or a self describing
structure. Library calls will be provided to manipulate this structure.
<!*** Finish Numbered ***!></p></font>
</td></tr>
</table>
<!*** Start Heading1 ***!><font size=+3 color=Black><strong>
Comparison with C++ binding:
<!*** Finish Heading1 ***!></p></strong></font>
<table>
<tr><td valign=top>
<!*** Start Numbered1 ***!><font size=+2 color=Black>
1.
<!*** Finish Numbered1 ***!></p></font>
</td>
<td valign=top>
<!*** Start Numbered1 ***!><font size=+2 color=Black>
cdevData, cdevRequestObject, and cdevGroup objects will be accessed through object id's.
<!*** Finish Numbered1 ***!></p></font>
</td></tr>
<tr><td valign=top>
<!*** Start Numbered ***!><font size=+2 color=Black>
2.
<!*** Finish Numbered ***!></p></font>
</td>
<td valign=top>
<!*** Start Numbered ***!><font size=+2 color=Black>
cdevDevice will only be referenced by device name.
<!*** Finish Numbered ***!></p></font>
</td></tr>
<tr><td valign=top>
<!*** Start Numbered ***!><font size=+2 color=Black>
3.
<!*** Finish Numbered ***!></p></font>
</td>
<td valign=top>
<!*** Start Numbered ***!><font size=+2 color=Black>
Only a single, default, cdevSystem will be supported.
<!*** Finish Numbered ***!></p></font>
</td></tr>
<tr><td valign=top>
<!*** Start Numbered ***!><font size=+2 color=Black>
4.
<!*** Finish Numbered ***!></p></font>
</td>
<td valign=top>
<!*** Start Numbered ***!><font size=+2 color=Black>
Since no function overloading is available, I/O operations on a cdevData object will have to
pass a datatype argument, similar to EPICS channel access.
<!*** Finish Numbered ***!></p></font>
</td></tr>
<tr><td valign=top>
<!*** Start Numbered ***!><font size=+2 color=Black>
5.
<!*** Finish Numbered ***!></p></font>
</td>
<td valign=top>
<!*** Start Numbered ***!><font size=+2 color=Black>
Routines which return strings will malloc the string, and the caller must free it.
<!*** Finish Numbered ***!></p></font>
</td></tr>
<tr><td valign=top>
<!*** Start Numbered ***!><font size=+2 color=Black>
6.
<!*** Finish Numbered ***!></p></font>
</td>
<td valign=top>
<!*** Start Numbered ***!><font size=+2 color=Black>
Function names are generally constructed from the class name followed by the method name,
e.g. cdevGroupStart.
<!*** Finish Numbered ***!></p></font>
</td></tr>
<tr><td valign=top>
<!*** Start Numbered ***!><font size=+2 color=Black>
7.
<!*** Finish Numbered ***!></p></font>
</td>
<td valign=top>
<!*** Start Numbered ***!><font size=+2 color=Black>
Creating objects will be done by routines like cdevGroupAllocate, which will essentially
return a pointer to the created object.
<!*** Finish Numbered ***!></p></font>
</td></tr>
<tr><td valign=top>
<!*** Start Numbered ***!><font size=+2 color=Black>
8.
<!*** Finish Numbered ***!></p></font>
</td>
<td valign=top>
<!*** Start Numbered ***!><font size=+2 color=Black>
cdevSystem methods will drop &quot;System&quot; from the name, and the notion of &quot;system&quot; will be
invisible.
<!*** Finish Numbered ***!></p></font>
</td></tr>
<tr><td valign=top>
<!*** Start Numbered ***!><font size=+2 color=Black>
9.
<!*** Finish Numbered ***!></p></font>
</td>
<td valign=top>
<!*** Start Numbered ***!><font size=+2 color=Black>
cdevDevice methods will drop &quot;Device&quot;. cdevRequestObject methods will use the shorter
&quot;cdevRequest&quot;.
<!*** Finish Numbered ***!></p></font>
</td></tr>
</table>
</td></tr>
<tr><td>
<! ***** Empty Column ***** !>
</td>
<td valign=top align=center>
<!*** Start Title ***!><font size=+5 color=Black><strong>
C Binding User's Guide
<!*** Finish Title ***!></p></strong></font>
</td></tr>
<tr><td>
<! ***** Empty Column ***** !>
</td>
<td valign=top>
<!*** Start Heading1 ***!><font size=+3 color=Black><strong>
Simple message passing routines:
<!*** Finish Heading1 ***!></p></strong></font>
<!*** Start Body ***!><font size=+2 color=Black>
Devices are addressed by name, and operations are performed by sending a message string and an
additional optional data object identifier. This data object is self describing in the sense that it con
tains indicators of the data type (int, float, etc.) and size (array lengths). Data returned from the
control system will also be through a data object.
<!*** Finish Body ***!></p></font>
<table>
<tr><td width=5% valign=top>
</td>
<td valign=top>
<!*** Start IndentedBold ***!><font size=+2 color=Black><strong>
status = cdevSend (char* devName, char* message,
</p>
cdev_data_t out, cdev_data_t in);
<!*** Finish IndentedBold ***!></p></strong></font>
</td></tr>
</table>
<!*** Start Body ***!><font size=+2 color=Black>
The data objects act as small databases able to hold multiple tagged data items. Items are inserted
into or extracted from the database via access routines. These access routines are also responsible
for any necessary data type conversions. Tags are passed to the cdevData routines as integers, and
are looked up in the tag database by specifying an ascii tag name. The most common tags are
&quot;value&quot;, &quot;timeStamp&quot;, &quot;status&quot;, and &quot;severity&quot;.
</p>
Data object manipulation routines:
<!*** Finish Body ***!></p></font>
<table>
<tr><td width=5% valign=top>
</td>
<td valign=top>
<!*** Start IndentedBold ***!><font size=+2 color=Black><strong>
cdevDataAllocate (cdev_data_t* id);
</p>
cdevDataFree (cdev_data_t id);
</p>
cdevDataTagC2I (char* tag, int *tagid);
</p>
cdevDataTagI2C (int tagid, char** tag); /* caller must free string */
</p>
cdevDataInsertTag (int tag, char* ctag);
</p>
cdevDataInsert (cdev_data_t id, int tagid, int type, void * data);
</p>
int cdevDataInsertArray(cdev_data_t id, int tagid, int type, void *data, size_t len, size_t
ndim);
</p>
cdevDataGet (cdev_data_t id, int tagid, int type, void * data);
</p>
cdevDataFind (cdev_data_t id, int tagid, void ** data);
</p>
int cdevDataGetType (cdev_data_t id, int tagid);
</p>
int cdevDataGetDim (cdev_data_t id, int tagid);
</p>
int cdevDataGetElems (cdev_data_t id, int tagid);
</p>
cdevDataGetBounds (cdev_data_t id, int tagid, int *bounds, int bsize);
</p>
cdevDataSetBounds (cdev_data_t id, int tagid, int *bounds, int bsize);
</p>
void cdevDataRemoveAll(cdev_data_t id);
</p>
cdevDataRemove (cdev_data_t id, int tagid);
</p>
cdevDataChangeTag (cdev_data_t id, int tagid, int newtagid);
</p>
cdevDataAsciiDump (cdev_data_t id, FILE *fp);
</p>
void cdevDataCopy(cdev_data_t from, cdev_data_t *to);
<!*** Finish IndentedBold ***!></p></strong></font>
</td></tr>
</table>
<!*** Start Body ***!><font size=+2 color=Black>
For example, to read the current from a magnet named NLQ1:
<!*** Finish Body ***!></p></font>
<table>
<tr><td width=5% valign=top>
</td>
<td valign=top>
<!*** Start Indented ***!><font size=+2 color=Black>
cdev_data_t result;
</p>
float current;
</p>
int status, valtag;
</p>
status = cdevDataAllocate (&amp;result);
</p>
status = cdevDataTagC2I (&quot;value&quot;,&amp;valtag);
</p>
status = cdevSend(&quot;NLQ1&quot;,&quot;read current&quot;,NULL,result);
</p>
status = cdevDataGet(result, valtag, CDEV_FLOAT, current);
<!*** Finish Indented ***!></p></font>
</td></tr>
</table>
<!*** Start Body ***!><font size=+2 color=Black>
The first call to a device automatically connects to the requested service, initializing any underly
ing packages as needed. These routines are synchronous (operation completes before return);
asynchronous routines are discussed below.
</p>
The message (second) argument selects what operation and attribute to access. Many messages
are by convention of the form &quot;verb attribute&quot;, and typical verbs include get, set, monitorOn, and
monitorOff.
<!*** Finish Body ***!></p></font>
<!*** Start Heading1 ***!><font size=+3 color=Black><strong>
Binding a device and message
<!*** Finish Heading1 ***!></p></strong></font>
<!*** Start Body ***!><font size=+2 color=Black>
In order to avoid the overhead of parsing the device name and message on each call, it is possible
to get a handle which binds the device and message into a request.
<!*** Finish Body ***!></p></font>
<table>
<tr><td width=5% valign=top>
</td>
<td valign=top>
<!*** Start IndentedBold ***!><font size=+2 color=Black><strong>
status = cdevRequestAllocate(char* device, char*message, CDEVREQUESTID* reqid);
<!*** Finish IndentedBold ***!></p></strong></font>
</td></tr>
</table>
<!*** Start Body ***!><font size=+2 color=Black>
Operations may be performed on this request object without specifying device and message.
<!*** Finish Body ***!></p></font>
<table>
<tr><td width=5% valign=top>
</td>
<td valign=top>
<!*** Start IndentedBold ***!><font size=+2 color=Black><strong>
status = cdevRequestSend(reqid, out, result);
<!*** Finish IndentedBold ***!></p></strong></font>
</td></tr>
</table>
<!*** Start Body ***!><font size=+2 color=Black>
Request objects maintain a connection to a server, and the state of this connection may be
obtained:
<!*** Finish Body ***!></p></font>
<table>
<tr><td width=5% valign=top>
</td>
<td valign=top>
<!*** Start IndentedBold ***!><font size=+2 color=Black><strong>
state = cdevRequestState (reqid);
<!*** Finish IndentedBold ***!></p></strong></font>
</td></tr>
</table>
<!*** Start Body ***!><font size=+2 color=Black>
The current access rights (read, write, none) for this request object may be obtained:
<!*** Finish Body ***!></p></font>
<table>
<tr><td width=5% valign=top>
</td>
<td valign=top>
<!*** Start IndentedBold ***!><font size=+2 color=Black><strong>
access = cdevRequestAccess (reqid);
<!*** Finish IndentedBold ***!></p></strong></font>
</td></tr>
</table>
<!*** Start Body ***!><font size=+2 color=Black>
Given the request object, it is also possible to extract the device name and message:
<!*** Finish Body ***!></p></font>
<table>
<tr><td width=5% valign=top>
</td>
<td valign=top>
<!*** Start IndentedBold ***!><font size=+2 color=Black><strong>
cdevRequestDevice (reqid, char** name); /* caller must free string */
</p>
cdevRequestMessage (reqid, char** msg);
<!*** Finish IndentedBold ***!></p></strong></font>
</td></tr>
</table>
<!*** Start Heading1 ***!><font size=+3 color=Black><strong>
Monitoring and Asynchronous I/O
<!*** Finish Heading1 ***!></p></strong></font>
<!*** Start Body ***!><font size=+2 color=Black>
A message sent to a device may result in an asynchronous reply, or more than one reply. In addi
tion, abnormal conditions may occur in the device which are of interest to the application. Each of
these results in a message back to the client which is asynchronous with respect to program exe
cution. Several calls are provided to deal with asynchronous data.
<!*** Finish Body ***!></p></font>
<table>
<tr><td valign=top>
<!*** Start HeadingRunIn ***!><font size=+2 color=Black><strong>
Asynchronous Messages
<!*** Finish HeadingRunIn ***!></p></strong></font>
</td>
<td>
<! ***** Empty Column ***** !>
</td></tr>
</table>
<!*** Start Body ***!><font size=+2 color=Black>
An asynchronous version of the message send call will send the mes
sage, but not wait for the reply. Two async forms are supported: one returning data to a caller's
data object, and the other returning data to a callback function. The reply argument is replaced by
an additional structure which specified a user callback function.
<!*** Finish Body ***!></p></font>
<table>
<tr><td width=5% valign=top>
</td>
<td valign=top>
<!*** Start IndentedBold ***!><font size=+2 color=Black><strong>
status = cdevSendNoBlock(char* device, char* message,
</p>
cdev_data_t out, cdev_data_t result);
</p>
status = cdevSendCallback(char* device, char* message,
</p>
cdev_data_t out, CDEVCALLBACK* callback);
<!*** Finish IndentedBold ***!></p></strong></font>
</td></tr>
</table>
<!*** Start Body ***!><font size=+2 color=Black>
Similarly for request objects:
<!*** Finish Body ***!></p></font>
<table>
<tr><td width=5% valign=top>
</td>
<td valign=top>
<!*** Start IndentedBold ***!><font size=+2 color=Black><strong>
status = cdevRequestSendNoBlock(cdev_data_t out, cdev_data_t result);
</p>
status = cdevRequestSendCallback(cdev_data_t out, CDEVCALLBACK* callback);
<!*** Finish IndentedBold ***!></p></strong></font>
</td></tr>
<tr><td valign=top>
<!*** Start HeadingRunIn ***!><font size=+2 color=Black><strong>
Monitoring:
<!*** Finish HeadingRunIn ***!></p></strong></font>
</td>
<td>
<! ***** Empty Column ***** !>
</td></tr>
</table>
<!*** Start Body ***!><font size=+2 color=Black>
Monitoring is started and stopped by two using the message &quot;monitorOn xxx&quot; and
&quot;monitorOff xxx&quot;.
<!*** Finish Body ***!></p></font>
<table>
<tr><td width=5% valign=top>
</td>
<td valign=top>
<!*** Start Indented ***!><font size=+2 color=Black>
status = cdevSendCallback(&quot;deviceName&quot;, &quot;monitorOn attributeName&quot;,NULL, callback);
<!*** Finish Indented ***!></p></font>
</td></tr>
<tr><td valign=top>
<!*** Start HeadingRunIn ***!><font size=+2 color=Black><strong>
Synchronization
<!*** Finish HeadingRunIn ***!></p></strong></font>
</td>
<td>
<! ***** Empty Column ***** !>
</td></tr>
</table>
<!*** Start Body ***!><font size=+2 color=Black>
In order to synchronize with asynchronous messages, both a poll and a pend
call are available, as well as an explicit flush. A pend with 0.0 seconds waits forever.
<!*** Finish Body ***!></p></font>
<table>
<tr><td width=5% valign=top>
</td>
<td valign=top>
<!*** Start IndentedBold ***!><font size=+2 color=Black><strong>
cdevFlush ();
</p>
cdevPoll ();
</p>
cdevPend (float seconds);
<!*** Finish IndentedBold ***!></p></strong></font>
</td></tr>
</table>
<!*** Start Body ***!><font size=+2 color=Black>
If seconds==0.0, wait forever.
<!*** Finish Body ***!></p></font>
<table>
<tr><td valign=top>
<!*** Start HeadingRunIn ***!><font size=+2 color=Black><strong>
Grouping
<!*** Finish HeadingRunIn ***!></p></strong></font>
</td>
<td>
<! ***** Empty Column ***** !>
</td></tr>
</table>
<!*** Start Body ***!><font size=+2 color=Black>
Grouping of operations will be similar to that specified for EZCA, with slight varia
tions. The grouping calls are useful for synchronizing with a set of asynchronous calls.
<!*** Finish Body ***!></p></font>
<table>
<tr><td width=5% valign=top>
</td>
<td valign=top>
<!*** Start IndentedBold ***!><font size=+2 color=Black><strong>
cdevGroupAllocate(GROUPID* groupid);
</p>
cdevGroupStart(groupid);
</p>
cdevGroupEnd(groupid);
</p>
cdevGroupPoll(groupid);
</p>
cdevGroupPend(groupid);
</p>
cdevGroupAllFinished (groupid);
</p>
cdevGroupStatus (groupid, int *status, int *nstatus); /* initially nstatus = len of status */
<!*** Finish IndentedBold ***!></p></strong></font>
</td></tr>
<tr><td valign=top>
<!*** Start HeadingRunIn ***!><font size=+2 color=Black><strong>
File Descriptors
<!*** Finish HeadingRunIn ***!></p></strong></font>
</td>
<td>
<! ***** Empty Column ***** !>
</td></tr>
</table>
<!*** Start Body ***!><font size=+2 color=Black>
To integrate other asynchronous systems, such as X windows, it is often neces
sary to obtain file descriptors for select operations.
<!*** Finish Body ***!></p></font>
<table>
<tr><td width=5% valign=top>
</td>
<td valign=top>
<!*** Start IndentedBold ***!><font size=+2 color=Black><strong>
status = cdevGetFD(int fd[], int * numFD);
<!*** Finish IndentedBold ***!></p></strong></font>
</td></tr>
<tr><td valign=top>
<!*** Start HeadingRunIn ***!><font size=+2 color=Black><strong>
Context
<!*** Finish HeadingRunIn ***!></p></strong></font>
</td>
<td>
<! ***** Empty Column ***** !>
</td></tr>
</table>
<!*** Start Body ***!><font size=+2 color=Black>
Operations on a device take place within a context. The context is maintained by the
device as a cdev_data_t structure. The following routines are used to get and set the context; set
ting items within the context is done by the cdevData* routines.
<!*** Finish Body ***!></p></font>
<table>
<tr><td width=5% valign=top>
</td>
<td valign=top>
<!*** Start IndentedBold ***!><font size=+2 color=Black><strong>
cdevGetContext(char *devname, cdev_data_t *id);
</p>
cdevSetContext(char *devname, cdev_data_t id);
<!*** Finish IndentedBold ***!></p></strong></font>
</td></tr>
<tr><td valign=top>
<!*** Start HeadingRunIn ***!><font size=+2 color=Black><strong>
Private Data
<!*** Finish HeadingRunIn ***!></p></strong></font>
</td>
<td>
<! ***** Empty Column ***** !>
</td></tr>
</table>
<!*** Start Body ***!><font size=+2 color=Black>
Each device also maintains a private data pointer, to be used by the application
developer for any purpose desired.
<!*** Finish Body ***!></p></font>
<table>
<tr><td width=5% valign=top>
</td>
<td valign=top>
<!*** Start IndentedBold ***!><font size=+2 color=Black><strong>
cdevGetPrivate (char *devname, void **data);
</p>
cdevSetPrivate (char *devname, void *data);
<!*** Finish IndentedBold ***!></p></strong></font>
</td></tr>
</table>
<!*** Start Body ***!><font size=+2 color=Black>
These same four routines are available for request objects:
<!*** Finish Body ***!></p></font>
<table>
<tr><td width=5% valign=top>
</td>
<td valign=top>
<!*** Start IndentedBold ***!><font size=+2 color=Black><strong>
cdevRequestGetContext (reqid, cdev_data_t *id);
</p>
cdevRequestSetContext (reqid, cdev_data_t id);
</p>
cdevRequestGetPrivate (reqid, void **data);
</p>
cdevRequestSetPrivate (reqid, void *data);
<!*** Finish IndentedBold ***!></p></strong></font>
</td></tr>
</table>
<!*** Start Heading1 ***!><font size=+3 color=Black><strong>
Error Reporting and Handling
<!*** Finish Heading1 ***!></p></strong></font>
<!*** Start Body ***!><font size=+2 color=Black>
This group of routines is also modeled after EZCA (assume identical functionality).
</p>
Turn automatic error reporting on and off:
<!*** Finish Body ***!></p></font>
<table>
<tr><td width=5% valign=top>
</td>
<td valign=top>
<!*** Start IndentedBold ***!><font size=+2 color=Black><strong>
cdevAutoErrorOn ();
</p>
cdevAutoErrorOff ();
<!*** Finish IndentedBold ***!></p></strong></font>
</td></tr>
</table>
<!*** Start Body ***!><font size=+2 color=Black>
Set the severity threshold at which errors should be reported:
<!*** Finish Body ***!></p></font>
<table>
<tr><td width=5% valign=top>
</td>
<td valign=top>
<!*** Start IndentedBold ***!><font size=+2 color=Black><strong>
cdevSetThreshold (int new);
</p>
cdevReportError (int severity, char *name,
</p>
CDEVREQUESTID request, char* format, ...);
</p>
cdevGetErrorString ();
</p>
cdevSetErrorHandler (function);
<!*** Finish IndentedBold ***!></p></strong></font>
</td></tr>
</table>
<!*** Start Body ***!><font size=+2 color=Black>
Note: For simplicity of use, a very compact set of error codes is implemented in cdev. The follow
ing error codes are defined in the header file cdevErrCode.h.
</p>
CDEV_SUCCESS = 0 Success
</p>
CDEV_INVALIDOBJ = 1 Invalid cdev object used
</p>
CDEV_INVALIDARG = 2 Invalid argument passed to cdev method
</p>
CDEV_INVALIDSVC = 3 Wrong service during dynamic loading
</p>
CDEV_NOTCONNECTED = 4 Not connected to low-level network service
</p>
CDEV_IOFAILED = 5 Low-level network service IO failed
</p>
CDEV_CONFLICT = 6 Conflicting of data types or data tags
</p>
CDEV_NOTFOUND = 7 Cdev cannot find specified data or tag
</p>
CDEV_TIMEOUT = 8 Time out
</p>
CDEV_CONVERT = 9 cdevData conversion error
<!*** Finish Body ***!></p></font>
<!*** Start Heading1 ***!><font size=+3 color=Black><strong>
Name Services
<!*** Finish Heading1 ***!></p></strong></font>
<!*** Start Body ***!><font size=+2 color=Black>
There is a special device named cdevDirectory which provides a set of query capabilities:
<!*** Finish Body ***!></p></font>
<table>
<tr><td width=5% valign=top>
</td>
<td valign=top>
<!*** Start Indented ***!><font size=+2 color=Black>
status = cdevSend(&quot;cdevDirectory&quot;, &quot;query&quot;,
</p>
cdev_data_t selection, cdev_data_t result);
<!*** Finish Indented ***!></p></font>
</td></tr>
</table>
<!*** Start Body ***!><font size=+2 color=Black>
The selection data object specifies one or more tags used to select device names. The result con
tains a list of devices accessed through the &quot;value&quot; tag.
</p>
<!*** Finish Body ***!></p></font>
</td></tr>
</table>
</body>