Accelerator Independent Data Access / PVAccess 2.0
AIDA-PVA is the latest version of the AIDA framework. Built on top of EPICS 7 it enables client applications to programmatically access and manage any device or database on the SLAC Network using simple channel names.
Loading...
Searching...
No Matches
AIDASLCMAGNET_SERVER.c
Go to the documentation of this file.
1/** @file
2 * @brief SLC Magnet Native Provider implementation.
3 * **MEMBER**=SLCLIBS:AIDA_PVALIB
4 * **ATTRIBUTES**=JNI,LIBR_NOGLOBAL
5 *
6 * Magnet Server implementation
7 */
8#include "aida_pva.h"
9#include "AIDASLCMAGNET_SERVER.h"
10
11static int getBaseMagnetArguments(JNIEnv* env, const char* uri, Arguments arguments, Value value,
12 int* count, char** prim_list,
13 char** micr_list, int** unit_list, int4u* secn, float** set_values, char** name_validity);
14static int getMagnetArguments(JNIEnv* env, const char* uri, Arguments arguments, Value value,
15 int* count, char** prim_list,
16 char** micr_list, int** unit_list, int4u* secn, float** set_values, char** magFunc, char** limitCheck,
17 char** name_validity);
18static bool isAllValid(int count, const char* name_validity);
19static void getInvalidNames(char* dst, int count, char* names[], const char* name_validity);
20
21// API Stubs
22VERSION("1.0.0")
39
40/**
41 * Initialise the service
42 * @param env to be used to throw exceptions using aidaThrow() and aidaThrowNonOsException()
43 * @throws ServerInitialisationException if the service fails to initialise
44 */
45void aidaServiceInit(JNIEnv* env)
46{
47 vmsstat_t status;
48 if (!$VMS_STATUS_SUCCESS(status = init("AIDA_SLCMAGNET", false))) {
49 aidaThrow(env, status, SERVER_INITIALISATION_EXCEPTION, "initialising SLC Magnet Service");
50 } else {
51 printf("AIDA-PVA Magnet Provider\n");
52 }
53}
54
55/**
56 * Get a table of data
57 *
58 * @param env to be used to throw exceptions using aidaThrow() and aidaThrowNonOsException()
59 * @param uri the uri
60 * @param arguments the arguments
61 * @return the table
62 */
63Table aidaRequestTable(JNIEnv* env, const char* uri, Arguments arguments)
64{
66
67 // Get arguments
68 char* micrPattern = NULL, * unitPattern = NULL;
69 if (ascanf(env, &arguments, "%os %os",
70 "micros", &micrPattern,
71 "units", &unitPattern
72 )) {
74 }
75 TRACK_MEMORY(micrPattern)
76 TRACK_MEMORY(unitPattern)
77
78 // Acquire Magnet values
79 int numMagnetPvs;
80 TO_LEGACY_NAME(uri, legacyName)
81 vmsstat_t status = DPSLCMAGNET_GET((char*)legacyName, (micrPattern ? micrPattern : "ALL*"),
82 (unitPattern ? unitPattern : "ALL*"),
83 &numMagnetPvs);
85 if (!SUCCESS(status)) {
86 aidaThrow(env, status, UNABLE_TO_GET_DATA_EXCEPTION, "while reading magnet values");
87 DPSLCMAGNET_GETCLEANUP();
89 }
90
91 // To hold the data
92 char namesData[(numMagnetPvs * MAX_PMU_STRING_LEN) + 1];
93 float secondaryValues[numMagnetPvs];
94
95 // Get Names
96 DPSLCMAGNET_GETNAMES(namesData);
97
98 // Get Secondary values
99 DPSLCMAGNET_GETSECNVALUES(secondaryValues);
100
101 // Cleanup
102 DPSLCMAGNET_GETCLEANUP();
103
104 // Make table and return results
105 Table table = tableCreate(env, numMagnetPvs, 2);
107 tableAddFixedWidthStringColumn(env, &table, namesData, MAX_PMU_STRING_LEN);
109 tableAddColumn(env, &table, AIDA_FLOAT_TYPE, secondaryValues, false);
110
111 // All read successfully
112 return table;
113}
114
115/**
116 * Sets specified `BCON` secondary values for specified array of
117 * magnet names to an array of corresponding values.
118 *
119 * The `VALUE` argument given in @p value will contain a structure containing two elements:
120 * - `names`: an array of magnet names
121 * - `values`: an array of corresponding values
122 *
123 * e.g. `{ "names": [... ], "values": [... ] }`
124 *
125 * @param env: to be used to throw exceptions using aidaThrow() and aidaThrowNonOsException()
126 * @param uri: the uri
127 * @param arguments: the arguments of type ::Arguments
128 * @param value: to set. Contains a structure containing two elements:
129 * - `names`: an array of magnet names
130 * - `values`: an array of corresponding values.
131 */
132void aidaSetValue(JNIEnv* env, const char* uri, Arguments arguments, Value value)
133{
134 if (!DPSLCMAGNET_ACCESSENABLED()) {
136 "Aida magnet set operations are not currently enabled");
137 return;
138 }
139
140 // Get the arguments
141 int count;
142
144 char* primaryList = NULL, * microList = NULL, * name_validity = NULL;
145 int* unitList = NULL;
146
147 int4u secn;
148 float* setValues = NULL;
149
150 if (getBaseMagnetArguments(env, uri,
151 arguments, value, &count, &primaryList, &microList, &unitList, &secn, &setValues, &name_validity)) {
152 return;
153 }
154 TRACK_MEMORY(primaryList)
155 TRACK_MEMORY(microList)
156 TRACK_MEMORY(name_validity)
157 TRACK_MEMORY(unitList)
158 TRACK_MEMORY(setValues)
159
160 // Get convert values to VMS floats
161 CONVERT_TO_VMS_FLOAT(setValues, count);
162
163 // set the PVs specified by the lists of primary, micros, and units
164 vmsstat_t status;
165 status = DPSLCMAGNET_SETCONFIG(count, primaryList, microList, unitList, secn, setValues);
167
168 // Clean up
169 DPSLCMAGNET_SETCLEANUP();
170 if (!SUCCESS(status)) {
171 aidaThrow(env, status, UNABLE_TO_SET_DATA_EXCEPTION, "while setting magnet values");
172 return;
173 }
174}
175
176/**
177 * Sets specified `BDES` or `VDES` secondary values for specified array
178 * of magnet names to an array of corresponding set values.
179 * Then optionally performs a specified trim or perturb operation.
180 *
181 * The `VALUE` argument will contain a structure containing two elements:
182 * - `names`: an array of magnet names
183 * - `values`: an array of corresponding values
184 *
185 * @param env to be used to throw exceptions using aidaThrow() and aidaThrowNonOsException(env, exception, message)
186 * @param uri the uri - `MAGNETSET:BDES` or `MAGNETSET:BCON`
187 * @param arguments the arguments.
188 * - `MAGFUNC`: required: argument specifies whether a trim or perturb operation will be performed.
189 * If `NOFUNC`, neither a trim nor a perturb operation will be performed
190 * - `TRIM`,
191 * - `PTRB`, or
192 * - `NOFUNC`
193 * - `LIMITCHECK`: optional: Used to determine behavior when the set value for one or
194 * more devices is outside of its low/high limits.
195 * - `ALL` The entire request will fail resulting in an exception being
196 * thrown and no `BDES` / `VDES` values being set for any of the requested devices.
197 * - `SOME` the set value action will succeed for
198 * those set values that are within limits and will not be performed for those
199 * set values outside their limits (the state string return values for these
200 * devices will be set to the string "Outside Limits").
201 * The default setting of this parameter is `ALL`.
202 * @param value to set. Contains a structure containing two elements:
203 * - `names`: an array of magnet names
204 * - `values`: an array of corresponding values.
205 * @return a table
206 */
207Table aidaSetValueWithResponse(JNIEnv* env, const char* uri, Arguments arguments, Value value)
208{
209 // Keep track of stuff to free
211
212 if (!DPSLCMAGNET_ACCESSENABLED()) {
214 "Aida magnet set operations are not currently enabled");
216 }
217
218 // Get arguments
219 int count;
220 int4u secn;
221 char* primaryList, * microList, * magnetFunction, * limitCheck, * name_validity;
222 int* unitList;
223 float* setValues;
224 int limitCheckAll = true;
225 if (getMagnetArguments(env, uri, arguments, value, &count,
226 &primaryList, &microList, &unitList, &secn, &setValues,
227 &magnetFunction, &limitCheck,
228 &name_validity)) {
230 }
231 TRACK_MEMORY(primaryList)
232 TRACK_MEMORY(microList)
233 TRACK_MEMORY(unitList)
234 TRACK_MEMORY(setValues)
235 TRACK_MEMORY(name_validity)
236 TRACK_MEMORY(magnetFunction)
237 TRACK_MEMORY(limitCheck)
238
239 if (strcasecmp(magnetFunction, "TRIM") != 0 && strcasecmp(magnetFunction, "PTRB") != 0
240 && strcasecmp(magnetFunction, "NOFUNC") != 0) {
241 aidaThrowNonOsException(env, UNABLE_TO_SET_DATA_EXCEPTION, "MAGFUNC parameter must be TRIM, PTRB or NOFUNC");
244 }
245
246 if (limitCheck && strcasecmp(limitCheck, "ALL") != 0 && strcasecmp(limitCheck, "SOME") != 0) {
247 aidaThrowNonOsException(env, UNABLE_TO_SET_DATA_EXCEPTION, "LIMITCHECK parameter must be ALL or SOME");
250 }
251
252 if (limitCheck) {
253 limitCheckAll = false;
254 }
255
256 // Check limits
257 bool withinLimits[count], allSetValuesWithinLimits = true; // true if within limits
258 int numPairsWithinLimits = 0;
259 float magnetLimits[count * 2];
260 DPSLCMAGNET_RET_MAGLIMITS(count, &magnetLimits[0]);
261 CONVERT_FROM_VMS_FLOAT(&magnetLimits[0], count * 2)
262 for (int i = 0; i < count; i++) {
263 float lowerLimit = magnetLimits[i * 2];
264 float upperLimit = magnetLimits[i * 2 + 1];
265 if ((setValues[i] < lowerLimit) || (setValues[i] > upperLimit)) {
266 withinLimits[i] = false;
267 allSetValuesWithinLimits = false;
268 } else {
269 withinLimits[i] = true;
270 numPairsWithinLimits++;
271 }
272 }
273 if (!allSetValuesWithinLimits && limitCheckAll || !numPairsWithinLimits) {
275 "Some or all of the set values are outside of the limits");
278 }
279
280 // Use only the values that are within limits
281 char limitedPrimList[(numPairsWithinLimits * PRIM_LEN) + 1];
282 char limitedMicrList[(numPairsWithinLimits * MICRO_LEN) + 1];
283 int limitedUnitList[numPairsWithinLimits];
284 float limitedValuesList[numPairsWithinLimits];
285
286 int limitedCounter = 0;
287 for (int i = 0; i < count; i++) {
288 if (withinLimits[i]) {
289 memcpy(limitedPrimList + limitedCounter * PRIM_LEN, primaryList + i * PRIM_LEN, PRIM_LEN);
290 memcpy(limitedMicrList + limitedCounter * MICRO_LEN, microList + i * MICRO_LEN, MICRO_LEN);
291 limitedUnitList[limitedCounter] = unitList[i];
292 limitedValuesList[limitedCounter] = setValues[i];
293 limitedCounter++;
294 }
295 }
296 limitedPrimList[(numPairsWithinLimits * PRIM_LEN)] = 0x0;
297 limitedMicrList[(numPairsWithinLimits * PRIM_LEN)] = 0x0;
298
299 // Convert values to VMS floats
300 CONVERT_TO_VMS_FLOAT(limitedValuesList, numPairsWithinLimits);
301
302 // Set the PVs specified by the lists of primary, micros, and units
303 vmsstat_t status;
304 status = DPSLCMAGNET_SET(numPairsWithinLimits, limitedPrimList, limitedMicrList, limitedUnitList, secn,
305 limitedValuesList, magnetFunction);
307 if (!SUCCESS(status)) {
308 aidaThrow(env, status, UNABLE_TO_SET_DATA_EXCEPTION, "while setting magnet values");
310 }
311
312 // To hold data
313 int rows = DPSLCMAGNET_RET_SETNUMPVS();
314 char namesData[(rows * MAX_STATE_NAME_LEN) + 1];
315 float bactData[rows];
316
317 // Get data
318 DPSLCMAGNET_RET_STATENAMES(namesData);
319 DPSLCMAGNET_RET_BACTVALUES(bactData);
320
321 // Clean up
322 DPSLCMAGNET_SETCLEANUP();
323
324 Table table = tableCreate(env, rows, 2);
326 tableAddFixedWidthStringColumn(env, &table, namesData, MAX_STATE_NAME_LEN);
328 tableAddColumn(env, &table, AIDA_FLOAT_TYPE, bactData, false);
329
330 return table;
331}
332
333/**
334 * Get basic magnet arguments
335 *
336 * @param env to be used to throw exceptions using {link aidaThrow} and {link aidaThrowNonOsException}
337 * @param uri
338 * @param value
339 * @param count
340 * @param prim_list
341 * @param micr_list
342 * @param unit_list
343 * @param secn
344 * @param set_values
345 * @return
346 */
347static int
348getBaseMagnetArguments(JNIEnv* env, const char* uri, Arguments arguments, Value value, int* count, char** prim_list,
349 char** micr_list, int** unit_list, int4u* secn, float** set_values, char** name_validity)
350{
352 *prim_list = NULL;
353 *micr_list = NULL;
354 *unit_list = NULL;
355 *set_values = NULL;
356 *name_validity = NULL;
357
358 unsigned int nNames, nValues;
359 char** names = NULL;
360
361 // Get congruent list of values to set, name and value pairs
362 // value contains an object with two congruent arrays
363 if (avscanf(env, &arguments, &value, "%sa %fa",
364 "value.names", &names, &nNames,
365 "value.values", set_values, &nValues
366 )) {
367 return EXIT_FAILURE;
368 }
369 TRACK_MEMORY(names)
370 TRACK_MEMORY(set_values)
371
372 // Find out how many values were supplied and check that both lists are the same length
373 *count = (int)nNames;
374 if (nNames != nValues) {
376 aidaThrowNonOsException(env, UNABLE_TO_SET_DATA_EXCEPTION, "supplied lists are not the same length");
377 return EXIT_FAILURE;
378 }
379
380 // Get names array - and break up names into their components for other lists
381 ALLOCATE_AND_TRACK_MEMORY_AND_ON_ERROR_RETURN_(env, *prim_list, (*count * PRIM_LEN) + 1, "primary list", EXIT_FAILURE)
382 ALLOCATE_AND_TRACK_MEMORY_AND_ON_ERROR_RETURN_(env, *micr_list, (*count * MICRO_LEN) + 1, "micro list", EXIT_FAILURE)
383 ALLOCATE_AND_TRACK_MEMORY_AND_ON_ERROR_RETURN_(env, *unit_list, *count * sizeof(unsigned long), "unit list", EXIT_FAILURE)
384 unsigned long longUnitList[*count];
385 for (int i = 0; i < nNames; i++) {
386 if (pmuFromDeviceName(env, names[i], *prim_list + i * PRIM_LEN, *micr_list + i * MICRO_LEN, &longUnitList[i])) {
388 return EXIT_FAILURE;
389 }
390 *((char*)(*prim_list + PRIM_LEN + i * PRIM_LEN)) = 0x0; // null terminate last one
391 *((char*)(*micr_list + MICRO_LEN + i * MICRO_LEN)) = 0x0; // null terminate last one
392 ((int*)*unit_list)[i] = (int)longUnitList[i];
393 }
394 // Secondary name
395 secnFromUri(uri, secn);
396
397 // Call names validate to see which names are valid
398 ALLOCATE_AND_TRACK_MEMORY_AND_ON_ERROR_RETURN_(env, *name_validity, (*count * MAX_VALIDITY_STRING_LEN) + 1, "name validity list",
399 EXIT_FAILURE)
400 DPSLCMAGNET_SETNAMESVALIDATE(*count, *prim_list, *micr_list, *unit_list, *secn, *name_validity);
401
402 // Check if all names are valid
403 if (!isAllValid(*count, *name_validity)) {
404 char invalidNames[MAX_URI_LEN * nNames + 1];
405 getInvalidNames(invalidNames, *count, names, *name_validity);
406 SPRINTF_ERROR_FREE_MEMORY_AND_RETURN_(UNABLE_TO_SET_DATA_EXCEPTION, "Some of the names were not valid: %s",
407 invalidNames,
408 EXIT_FAILURE)
409 }
410
411 // Free up the names as we don't need them anymore as they have been validated
413
414 return EXIT_SUCCESS;
415}
416
417/**
418 * Get full set of arguments
419 *
420 * @param env to be used to throw exceptions using {link aidaThrow} and {link aidaThrowNonOsException}
421 * @param uri
422 * @param arguments
423 * @param value
424 * @param count
425 * @param prim_list
426 * @param micr_list
427 * @param unit_list
428 * @param secn
429 * @param set_values
430 * @param magFunc
431 * @param limitCheck
432 * @return
433 */
434static int
435getMagnetArguments(JNIEnv* env, const char* uri, Arguments arguments, Value value, int* count, char** prim_list,
436 char** micr_list, int** unit_list, int4u* secn, float** set_values, char** magFunc, char** limitCheck,
437 char** name_validity)
438{
439 *magFunc = NULL;
440 *limitCheck = NULL;
441
443 if (getBaseMagnetArguments(env, uri, arguments, value, count, prim_list, micr_list, unit_list, secn, set_values,
444 name_validity)) {
445 return EXIT_FAILURE;
446 }
447 TRACK_MEMORY(prim_list)
448 TRACK_MEMORY(micr_list)
449 TRACK_MEMORY(unit_list)
450 TRACK_MEMORY(set_values)
451 TRACK_MEMORY(name_validity)
452
453 if (ascanf(env, &arguments, "%s %os",
454 "magfunc", magFunc,
455 "limitcheck", limitCheck
456 )) {
458 return EXIT_FAILURE;
459 }
460
461 return EXIT_SUCCESS;
462}
463
464/**
465 * Check if all the names are valid. String will be Success if valid
466 *
467 * @param count
468 * @param name_validity
469 * @return true if all are valid
470 */
471bool isAllValid(int count, const char* name_validity)
472{
473 if (!name_validity) {
474 return false;
475 }
476
477 for (int i = 0; i < count; i++) {
478 if (strncasecmp(name_validity + (i * MAX_VALIDITY_STRING_LEN), "Success", sizeof("Success") - 1) != 0) {
479 return false;
480 }
481 }
482
483 return true;
484}
485
486/**
487 * Get a string listing the invalid names into a pre allocated buffer
488 * @param dst pre-allocated buffer
489 * @param count the number if names in the provided array
490 * @param names the array of pointers to names
491 * @param name_validity the name validity structure returned from the back end
492 */
493static void getInvalidNames(char* dst, int count, char* names[], const char* name_validity)
494{
495 if (!name_validity || !names) {
496 return;
497 }
498
499 *dst = 0x0; // null terminate initial string
500 for (int i = 0; i < count; i++) {
501 if (strncasecmp(name_validity + (i * MAX_VALIDITY_STRING_LEN), "Success", sizeof("Success") - 1) != 0) {
502 strcat(dst, names[i]);
503 if (i != count - 1) {
504 strcat(dst, ", ");
505 }
506 }
507 }
508}
509
Table aidaSetValueWithResponse(JNIEnv *env, const char *uri, Arguments arguments, Value value)
Sets specified BDES or VDES secondary values for specified array of magnet names to an array of corre...
void aidaSetValue(JNIEnv *env, const char *uri, Arguments arguments, Value value)
Sets specified BCON secondary values for specified array of magnet names to an array of corresponding...
REQUEST_STUB_BOOLEAN REQUEST_STUB_BYTE REQUEST_STUB_SHORT REQUEST_STUB_INTEGER REQUEST_STUB_LONG REQUEST_STUB_FLOAT REQUEST_STUB_DOUBLE REQUEST_STUB_STRING REQUEST_STUB_BOOLEAN_ARRAY REQUEST_STUB_BYTE_ARRAY REQUEST_STUB_SHORT_ARRAY REQUEST_STUB_INTEGER_ARRAY REQUEST_STUB_LONG_ARRAY REQUEST_STUB_FLOAT_ARRAY REQUEST_STUB_DOUBLE_ARRAY REQUEST_STUB_STRING_ARRAY void aidaServiceInit(JNIEnv *env)
Initialise the service.
Table aidaRequestTable(JNIEnv *env, const char *uri, Arguments arguments)
Get a table of data.
The Header File for the AIDA-PVA Module functions.
#define REQUEST_STUB_BYTE
aidaRequestByte API Stub
Definition: aida_pva_api.h:259
#define VERSION(_version)
Use this macro to define the version of the provider.
Definition: aida_pva_api.h:40
#define REQUEST_STUB_INTEGER
aidaRequestInteger API Stub
Definition: aida_pva_api.h:269
#define REQUEST_STUB_LONG_ARRAY
aidaRequestLongArray API Stub
Definition: aida_pva_api.h:326
#define REQUEST_STUB_SHORT
aidaRequestShort API Stub
Definition: aida_pva_api.h:264
#define REQUEST_STUB_INTEGER_ARRAY
aidaRequestIntegerArray API Stub
Definition: aida_pva_api.h:321
#define REQUEST_STUB_LONG
aidaRequestLong API Stub
Definition: aida_pva_api.h:274
#define REQUEST_STUB_STRING
aidaRequestString API Stub
Definition: aida_pva_api.h:289
#define REQUEST_STUB_DOUBLE
aidaRequestDouble API Stub
Definition: aida_pva_api.h:284
#define REQUEST_STUB_SHORT_ARRAY
aidaRequestShortArray API Stub
Definition: aida_pva_api.h:316
#define REQUEST_STUB_BYTE_ARRAY
aidaRequestByteArray API Stub
Definition: aida_pva_api.h:311
#define RETURN_NULL_TABLE
Return an empty table response.
Definition: aida_pva_api.h:380
#define REQUEST_STUB_BOOLEAN
aidaRequestBoolean API Stub
Definition: aida_pva_api.h:253
#define REQUEST_STUB_FLOAT_ARRAY
aidaRequestFloatArray API Stub
Definition: aida_pva_api.h:331
#define REQUEST_STUB_DOUBLE_ARRAY
aidaRequestDoubleArray API Stub
Definition: aida_pva_api.h:336
#define REQUEST_STUB_BOOLEAN_ARRAY
aidaRequestBooleanArray API Stub
Definition: aida_pva_api.h:306
#define REQUEST_STUB_FLOAT
aidaRequestFloat API Stub
Definition: aida_pva_api.h:279
#define REQUEST_STUB_STRING_ARRAY
aidaRequestStringArray API stub
Definition: aida_pva_api.h:342
#define CONVERT_FROM_VMS_FLOAT(_float, _count)
Convert in-place, floating point numbers from VMS to ieee format.
#define CONVERT_TO_VMS_FLOAT(_float, _count)
Convert in-place, floating point numbers from ieee to VMS format.
#define SERVER_INITIALISATION_EXCEPTION
Use this string to signal Server Initialisation Exceptions in aidaThrow()
#define UNABLE_TO_SET_DATA_EXCEPTION
Use this string to signal Exceptions when trying to Set Data in aidaThrow()
#define ON_EXCEPTION_RETURN_(_r)
Check to see if an exception has been raised, and return the given return value.
#define SPRINTF_ERROR_FREE_MEMORY_AND_RETURN_(_exception, _errorText, _ref, _r)
Format an error message, throw it in an exception, free any allocated memory and return the error cod...
#define UNABLE_TO_GET_DATA_EXCEPTION
Use this string to signal Exceptions when trying to Get Data in aidaThrow()
#define TRACK_ALLOCATED_MEMORY
Create tracking variables so that memory can be freed with FREE_MEMORY macro.
#define FREE_MEMORY
Free any allocated memory.
#define ALLOCATE_AND_TRACK_MEMORY_AND_ON_ERROR_RETURN_(_env, _var, _size, _purpose, _r)
Allocate memory and add it to the tracked memory list so that it can be freed automatically later.
#define FREE_TRACKED_MEMORY(_ptr)
Free a single tracked memory allocation and remove from list.
#define TRACK_MEMORY(_ptr)
Register this newly allocated memory so that it will be freed by FREE_MEMORY.
void secnFromUri(const char *uri, int4u *secn)
Get secondary from pseudo secondary (containing a colon) number from URI e.g.
void aidaThrow(JNIEnv *env, vmsstat_t status, char *exception, const char *message)
To log any exceptions and throw back to java.
vmsstat_t init(const char *processName, bool initMessageServices)
Call standalone_init()
void aidaThrowNonOsException(JNIEnv *env, char *exception, const char *message)
To log any non-OS exceptions and throw back to java.
int pmuFromDeviceName(JNIEnv *env, char *device, char *primary, char *micro, int4u *unit)
Get primary, micro and unit from a device name.
@ AIDA_FLOAT_TYPE
Represents a float.
void tableAddFixedWidthStringColumn(JNIEnv *env, Table *table, char *data, int width)
This reads data from an allocated space that is rows * width with each string occupying width charact...
int ascanf(JNIEnv *env, Arguments *arguments, const char *formatString,...)
ascanf(), avscanf()
Table tableCreate(JNIEnv *env, int rows, int columns)
Make a Table for return to client.
void tableAddColumn(JNIEnv *env, Table *table, Type type, void *data, bool ieeeFormat)
Add a column of arbitrary type to a Table.
int avscanf(JNIEnv *env, Arguments *arguments, Value *value, const char *formatString,...)
ascanf(), avscanf()
#define TO_LEGACY_NAME(_uri, _var)
Get a legacy AIDA name from the provided uri and store it in the given variable name.
Definition: aida_pva_uri.h:57
#define PRIM_LEN
The length of the primary part of a PMU string.
Definition: aida_pva_uri.h:24
#define MAX_URI_LEN
The maximum length of a URI.
Definition: aida_pva_uri.h:20
#define MICRO_LEN
The length of the micro part of a PMU string.
Definition: aida_pva_uri.h:28
An Arguments structure stores all of the arguments passed from the request to the Native Channel Prov...
Table structure.
This special type represents a Value.