1
#define _POSIX_C_SOURCE 199309L
10
#include <sys/ioctl.h>
12
#include <arpa/inet.h>
22
#ifndef __timespec_defined
27
#endif /* __timespec_defined */
30
pcilib_event_t pcilib_find_event(pcilib_t *ctx, const char *event) {
33
pcilib_model_description_t *model_info = pcilib_get_model_description(ctx);
34
pcilib_event_description_t *events = model_info->events;
36
for (i = 0; events[i].name; i++) {
37
if (!strcasecmp(events[i].name, event)) return events[i].evid;
40
return (pcilib_event_t)-1;
43
pcilib_event_data_type_t pcilib_find_event_data_type(pcilib_t *ctx, pcilib_event_t event, const char *data_type) {
46
pcilib_model_description_t *model_info = pcilib_get_model_description(ctx);
47
pcilib_event_data_type_description_t *data_types = model_info->data_types;
49
for (i = 0; data_types[i].name; i++) {
50
if ((data_types[i].evid&event)&&(!strcasecmp(data_types[i].name, data_type))) return data_types[i].data_type;
53
return (pcilib_event_data_type_t)-1;
56
int pcilib_init_event_engine(pcilib_t *ctx) {
57
pcilib_event_api_description_t *api;
58
pcilib_model_description_t *model_info = pcilib_get_model_description(ctx);
60
api = model_info->event_api;
62
// api = pcilib_model[model].event_api;
63
if ((api)&&(api->init)) {
64
ctx->event_ctx = api->init(ctx);
66
ctx->event_ctx->pcilib = ctx;
73
int pcilib_reset(pcilib_t *ctx) {
74
pcilib_event_api_description_t *api;
76
pcilib_model_description_t *model_info = pcilib_get_model_description(ctx);
78
api = model_info->event_api;
80
pcilib_error("Event API is not supported by the selected model");
81
return PCILIB_ERROR_NOTSUPPORTED;
85
return api->reset(ctx->event_ctx);
90
int pcilib_configure_rawdata_callback(pcilib_t *ctx, pcilib_event_rawdata_callback_t callback, void *user) {
91
pcilib_event_api_description_t *api;
93
pcilib_model_description_t *model_info = pcilib_get_model_description(ctx);
95
api = model_info->event_api;
97
pcilib_error("Event API is not supported by the selected model");
98
return PCILIB_ERROR_NOTSUPPORTED;
101
ctx->event_ctx->params.rawdata.callback = callback;
102
ctx->event_ctx->params.rawdata.user = user;
107
int pcilib_configure_autostop(pcilib_t *ctx, size_t max_events, pcilib_timeout_t duration) {
108
pcilib_event_api_description_t *api;
110
pcilib_model_description_t *model_info = pcilib_get_model_description(ctx);
112
api = model_info->event_api;
114
pcilib_error("Event API is not supported by the selected model");
115
return PCILIB_ERROR_NOTSUPPORTED;
118
ctx->event_ctx->params.autostop.max_events = max_events;
119
ctx->event_ctx->params.autostop.duration = duration;
124
int pcilib_configure_autotrigger(pcilib_t *ctx, pcilib_timeout_t interval, pcilib_event_t event, size_t trigger_size, void *trigger_data) {
125
/* To support hardware without autotriggering, we need to provide in event.c a code
126
to generate multiple triggers in a thread (available in cli). The function should
127
be re-enabled afterwards: just set parameters and let implementation decide if it
128
can make triggering in hardware or will use our emulation */
130
return PCILIB_ERROR_NOTSUPPORTED;
133
int pcilib_configure_preprocessing_threads(pcilib_t *ctx, size_t max_threads) {
134
pcilib_event_api_description_t *api;
136
pcilib_model_description_t *model_info = pcilib_get_model_description(ctx);
138
api = model_info->event_api;
140
pcilib_error("Event API is not supported by the selected model");
141
return PCILIB_ERROR_NOTSUPPORTED;
144
ctx->event_ctx->params.parallel.max_threads = max_threads;
149
int pcilib_start(pcilib_t *ctx, pcilib_event_t event_mask, pcilib_event_flags_t flags) {
150
pcilib_event_api_description_t *api;
152
pcilib_model_description_t *model_info = pcilib_get_model_description(ctx);
154
api = model_info->event_api;
156
pcilib_error("Event API is not supported by the selected model");
157
return PCILIB_ERROR_NOTSUPPORTED;
161
return api->start(ctx->event_ctx, event_mask, flags);
166
int pcilib_stop(pcilib_t *ctx, pcilib_event_flags_t flags) {
167
pcilib_event_api_description_t *api;
169
pcilib_model_description_t *model_info = pcilib_get_model_description(ctx);
171
api = model_info->event_api;
173
pcilib_error("Event API is not supported by the selected model");
174
return PCILIB_ERROR_NOTSUPPORTED;
178
return api->stop(ctx->event_ctx, flags);
183
int pcilib_stream(pcilib_t *ctx, pcilib_event_callback_t callback, void *user) {
184
pcilib_event_api_description_t *api;
186
pcilib_model_description_t *model_info = pcilib_get_model_description(ctx);
188
api = model_info->event_api;
190
pcilib_error("Event API is not supported by the selected model");
191
return PCILIB_ERROR_NOTSUPPORTED;
195
return api->stream(ctx->event_ctx, callback, user);
197
if (api->next_event) {
198
pcilib_error("Streaming using next_event API is not implemented yet");
201
pcilib_error("Event enumeration is not suppored by API");
202
return PCILIB_ERROR_NOTSUPPORTED;
206
pcilib_event_id_t event_id;
207
pcilib_event_info_t *info;
208
} pcilib_return_event_callback_context_t;
210
static int pcilib_return_event_callback(pcilib_event_id_t event_id, pcilib_event_info_t *info, void *user) {
211
pcilib_return_event_callback_context_t *ctx = (pcilib_return_event_callback_context_t*)user;
212
ctx->event_id = event_id;
217
int pcilib_get_next_event(pcilib_t *ctx, pcilib_timeout_t timeout, pcilib_event_id_t *evid, size_t info_size, pcilib_event_info_t *info) {
218
pcilib_event_api_description_t *api;
219
// pcilib_return_event_callback_context_t user;
221
pcilib_model_description_t *model_info = pcilib_get_model_description(ctx);
223
api = model_info->event_api;
225
pcilib_error("Event API is not supported by the selected model");
226
return PCILIB_ERROR_NOTSUPPORTED;
230
return api->next_event(ctx->event_ctx, timeout, evid, info_size, info);
234
err = api->stream(ctx->event_ctx, 1, timeout, pcilib_return_event_callback, &user);
237
if (evid) *evid = user->event_id;
238
if (info) *info = user->info;
244
pcilib_error("Event enumeration is not suppored by API");
245
return PCILIB_ERROR_NOTSUPPORTED;
248
int pcilib_trigger(pcilib_t *ctx, pcilib_event_t event, size_t trigger_size, void *trigger_data) {
249
pcilib_event_api_description_t *api;
251
pcilib_model_description_t *model_info = pcilib_get_model_description(ctx);
253
api = model_info->event_api;
255
pcilib_error("Event API is not supported by the selected model");
256
return PCILIB_ERROR_NOTSUPPORTED;
260
return api->trigger(ctx->event_ctx, event, trigger_size, trigger_data);
262
pcilib_error("Self triggering is not supported by the selected model");
263
return PCILIB_ERROR_NOTSUPPORTED;
267
void *pcilib_get_data_with_argument(pcilib_t *ctx, pcilib_event_id_t event_id, pcilib_event_data_type_t data_type, size_t arg_size, void *arg, size_t *size) {
270
pcilib_model_description_t *model_info = pcilib_get_model_description(ctx);
272
pcilib_event_api_description_t *api = model_info->event_api;
274
if (size) *size = (size_t)PCILIB_ERROR_NOTSUPPORTED;
275
pcilib_error("Event API is not supported by the selected model");
280
err = api->get_data(ctx->event_ctx, event_id, data_type, arg_size, arg, size, &res);
282
if (size) *size = (size_t)err;
288
if (size) *size = (size_t)PCILIB_ERROR_NOTSUPPORTED;
292
int pcilib_copy_data_with_argument(pcilib_t *ctx, pcilib_event_id_t event_id, pcilib_event_data_type_t data_type, size_t arg_size, void *arg, size_t size, void *buf, size_t *retsize) {
295
pcilib_model_description_t *model_info = pcilib_get_model_description(ctx);
297
pcilib_event_api_description_t *api = model_info->event_api;
299
pcilib_error("Event API is not supported by the selected model");
300
return PCILIB_ERROR_NOTSUPPORTED;
304
err = api->get_data(ctx->event_ctx, event_id, data_type, arg_size, arg, &size, &res);
307
if (buf != res) memcpy(buf, res, size);
309
if (retsize) *retsize = size;
313
return PCILIB_ERROR_NOTSUPPORTED;
317
void *pcilib_get_data(pcilib_t *ctx, pcilib_event_id_t event_id, pcilib_event_data_type_t data_type, size_t *size) {
320
pcilib_model_description_t *model_info = pcilib_get_model_description(ctx);
322
pcilib_event_api_description_t *api = model_info->event_api;
324
pcilib_error("Event API is not supported by the selected model");
325
if (size) *size = (size_t)PCILIB_ERROR_NOTSUPPORTED;
330
err = api->get_data(ctx->event_ctx, event_id, data_type, 0, NULL, size, &res);
332
if (size) *size = (size_t)err;
338
if (size) *size = (size_t)PCILIB_ERROR_NOTSUPPORTED;
342
int pcilib_copy_data(pcilib_t *ctx, pcilib_event_id_t event_id, pcilib_event_data_type_t data_type, size_t size, void *buf, size_t *ret_size) {
345
pcilib_model_description_t *model_info = pcilib_get_model_description(ctx);
347
pcilib_event_api_description_t *api = model_info->event_api;
349
pcilib_error("Event API is not supported by the selected model");
350
return PCILIB_ERROR_NOTSUPPORTED;
354
err = api->get_data(ctx->event_ctx, event_id, data_type, 0, NULL, &size, &res);
357
if (buf != res) memcpy(buf, res, size);
359
if (ret_size) *ret_size = size;
363
return PCILIB_ERROR_NOTSUPPORTED;
366
int pcilib_return_data(pcilib_t *ctx, pcilib_event_id_t event_id, pcilib_event_data_type_t data_type, void *data) {
367
pcilib_model_description_t *model_info = pcilib_get_model_description(ctx);
369
pcilib_event_api_description_t *api = model_info->event_api;
371
pcilib_error("Event API is not supported by the selected model");
372
return PCILIB_ERROR_NOTSUPPORTED;
375
if (api->return_data)
376
return api->return_data(ctx->event_ctx, event_id, data_type, data);
387
} pcilib_grab_callback_user_data_t;
390
static int pcilib_grab_callback(pcilib_event_t event, pcilib_event_id_t event_id, void *vuser) {
396
pcilib_grab_callback_user_data_t *user = (pcilib_grab_callback_user_data_t*)vuser;
398
data = pcilib_get_data(user->ctx, event_id, PCILIB_EVENT_DATA, &size);
400
pcilib_error("Error getting event data");
405
if ((user->size)&&(*(user->size) < size)) {
406
pcilib_error("The supplied buffer does not have enough space to hold the event data. Buffer size is %z, but %z is required", user->size, size);
407
return -PCILIB_ERROR_MEMORY;
410
*(user->size) = size;
412
*(user->data) = malloc(size);
413
if (!*(user->data)) {
414
pcilib_error("Memory allocation (%i bytes) for event data is failed");
415
return -PCILIB_ERROR_MEMORY;
417
if (*(user->size)) *(user->size) = size;
421
memcpy(*(user->data), data, size);
423
err = pcilib_return_data(user->ctx, event_id, PCILIB_EVENT_DATA, data);
427
*(user->data) = NULL;
429
pcilib_error("The event data had been overwritten before it was returned, data corruption may occur");
433
return PCILIB_STREAMING_CONTINUE;
436
int pcilib_grab(pcilib_t *ctx, pcilib_event_t event_mask, size_t *size, void **data, pcilib_timeout_t timeout) {
438
pcilib_event_id_t eid;
440
pcilib_grab_callback_user_data_t user = {ctx, size, data};
442
err = pcilib_start(ctx, event_mask, PCILIB_EVENT_FLAGS_DEFAULT);
443
if (!err) err = pcilib_trigger(ctx, event_mask, 0, NULL);
445
err = pcilib_get_next_event(ctx, timeout, &eid, 0, NULL);
446
if (!err) pcilib_grab_callback(event_mask, eid, &user);
448
pcilib_stop(ctx, PCILIB_EVENT_FLAGS_DEFAULT);