#include #include #include #include #include #include #include #include #include #include #include "avm_event.h" #define AVM_EVENT_DEVICE "/dev/avm_event" /*------------------------------------------------------------------------------------------*\ \*------------------------------------------------------------------------------------------*/ #undef DEB_ERR #undef DEB_WARN #undef DEB_INFO #undef DEB_TRC #define DEB_ERR(args...) fprintf(stderr, args) #define DEB_WARN(args...) fprintf(stderr, args) #define DEB_INFO(args...) fprintf(stderr, args) #define DEB_TRC(args...) fprintf(stderr, args) /*-------------------------------------------------------------------------------------*\ \*-------------------------------------------------------------------------------------*/ int avm_event_register(char* name, unsigned long long mask) { int fd, len; struct _avm_event_cmd cmd; fd = open(AVM_EVENT_DEVICE, O_RDWR); if (fd < 0) { return AVM_EVENT_UNKNOWN_HANDLE; } cmd.cmd = avm_event_cmd_register; #define min(a, b) ((a) < (b) ? (a) : (b)) len = min(strlen(name), MAX_EVENT_CLIENT_NAME_LEN); strncpy(cmd.param.avm_event_cmd_param_register.Name, name, len); cmd.param.avm_event_cmd_param_register.Name[len] = '\0'; cmd.param.avm_event_cmd_param_register.mask = mask; if (write(fd, &cmd, sizeof(cmd)) < 0) { close(fd); switch (errno) { case EBADF: return AVM_EVENT_UNKNOWN_HANDLE; default: return AVM_EVENT_RESOURCE_ERROR; } } avm_event_set_blocking(fd + 1); return fd + 1; } /*------------------------------------------------------------------------------------------*\ \*------------------------------------------------------------------------------------------*/ int avm_event_source_register(int handle, char *name, unsigned long long mask) { struct _avm_event_cmd cmd; int fd, len; fd = handle - 1; cmd.cmd = avm_event_cmd_source_register; len = min(strlen(name), MAX_EVENT_CLIENT_NAME_LEN); strncpy(cmd.param.avm_event_cmd_param_source_register.Name, name, len); cmd.param.avm_event_cmd_param_source_register.Name[len] = '\0'; cmd.param.avm_event_cmd_param_source_register.mask = mask; if (write(fd, &cmd, sizeof(cmd)) < 0) { switch (errno) { case EBADF: return AVM_EVENT_UNKNOWN_HANDLE; default: return AVM_EVENT_RESOURCE_ERROR; } } return AVM_EVENT_OK; } /*------------------------------------------------------------------------------------------*\ \*------------------------------------------------------------------------------------------*/ int avm_event_source_release(int handle) { struct _avm_event_cmd cmd; int fd; fd = handle - 1; cmd.cmd = avm_event_cmd_source_release; if (write(fd, &cmd, sizeof(cmd)) < 0) { switch (errno) { case EBADF: return AVM_EVENT_UNKNOWN_HANDLE; default: return AVM_EVENT_RESOURCE_ERROR; } } return AVM_EVENT_OK; } /*------------------------------------------------------------------------------------------*\ \*------------------------------------------------------------------------------------------*/ int avm_event_source_trigger(int handle, unsigned int data_length, struct _avm_event_header *data) { struct _avm_event_cmd *cmd; int fd; int status = AVM_EVENT_OK; fd = handle - 1; cmd = malloc(sizeof(struct _avm_event_cmd) + data_length); if(cmd == NULL) { return AVM_EVENT_RESOURCE_ERROR; } cmd->cmd = avm_event_cmd_source_trigger; cmd->param.avm_event_cmd_param_source_trigger.id = data->id; cmd->param.avm_event_cmd_param_source_trigger.data_length = data_length; memcpy((unsigned char *)cmd + sizeof(struct _avm_event_cmd), data, data_length); if (write(fd, cmd, sizeof(struct _avm_event_cmd) + data_length) < 0) { switch (errno) { case EBADF: status = AVM_EVENT_UNKNOWN_HANDLE; break; default: status = AVM_EVENT_RESOURCE_ERROR; break; } } free(cmd); return status; } /*------------------------------------------------------------------------------------------*\ \*------------------------------------------------------------------------------------------*/ int avm_event_trigger(int handle, unsigned int id) { struct _avm_event_cmd cmd; int fd; int status = AVM_EVENT_OK; fd = handle - 1; cmd.cmd = avm_event_cmd_trigger; cmd.param.avm_event_cmd_param_trigger.id = id; if (write(fd, &cmd, sizeof(struct _avm_event_cmd)) < 0) { switch (errno) { case EBADF: status = AVM_EVENT_UNKNOWN_HANDLE; break; default: status = AVM_EVENT_RESOURCE_ERROR; break; } } return status; } /*-------------------------------------------------------------------------------------*\ \*-------------------------------------------------------------------------------------*/ int avm_event_get_fd(int handle) { return handle - 1; } /*-------------------------------------------------------------------------------------*\ \*-------------------------------------------------------------------------------------*/ int avm_event_dup(int handle) { return dup(handle - 1) + 1; } /*-------------------------------------------------------------------------------------*\ \*-------------------------------------------------------------------------------------*/ int avm_event_undup(int handle) { if(close(handle - 1)) return AVM_EVENT_UNKNOWN_HANDLE; return AVM_EVENT_OK; } /*-------------------------------------------------------------------------------------*\ \*-------------------------------------------------------------------------------------*/ int avm_event_release(int handle) { int fd; struct _avm_event_cmd cmd; fd = handle - 1; cmd.cmd = avm_event_cmd_release; cmd.param.avm_event_cmd_param_release.Name[0] = '\0'; if (write(fd, &cmd, sizeof(cmd)) < 0) { switch (errno) { case EBADF: return AVM_EVENT_UNKNOWN_HANDLE; default: return AVM_EVENT_RESOURCE_ERROR; } } close(fd); return AVM_EVENT_OK; } /*-------------------------------------------------------------------------------------*\ \*-------------------------------------------------------------------------------------*/ int avm_event_set_non_blocking(int handle) { int flags; int fd = handle - 1; flags = fcntl(fd, F_GETFL); if (flags == -1) { switch (errno) { case EBADF: return AVM_EVENT_UNKNOWN_HANDLE; default: return AVM_EVENT_RESOURCE_ERROR; } } if ((flags & O_NONBLOCK)) return AVM_EVENT_OK; flags |= O_NONBLOCK; if (fcntl(fd, F_SETFL, flags)) { switch (errno) { case EBADF: return AVM_EVENT_UNKNOWN_HANDLE; default: return AVM_EVENT_RESOURCE_ERROR; } } return AVM_EVENT_OK; } /*-------------------------------------------------------------------------------------*\ \*-------------------------------------------------------------------------------------*/ int avm_event_set_blocking(int handle) { int flags; int fd = handle - 1; flags = fcntl(fd, F_GETFL); if (flags == -1) { switch (errno) { case EBADF: return AVM_EVENT_UNKNOWN_HANDLE; default: return AVM_EVENT_RESOURCE_ERROR; } } if ((flags & O_NONBLOCK) == 0) return AVM_EVENT_OK; flags &= ~O_NONBLOCK; if (fcntl(fd, F_SETFL, flags)) { switch (errno) { case EBADF: return AVM_EVENT_UNKNOWN_HANDLE; default: return AVM_EVENT_RESOURCE_ERROR; } } return AVM_EVENT_OK; } /*------------------------------------------------------------------------------------------*\ * Paramter: * handle * data Buffer für daten * length input: maximal datenlaenge, output: gelesene Bytes \*------------------------------------------------------------------------------------------*/ int avm_event_read(int handle, void *data, unsigned int *length) { int fd = handle - 1; int ret; ret = read(fd, data, *length); if(ret >= 0) { *length = ret; return AVM_EVENT_OK; } *length = 0; return AVM_EVENT_UNKNOWN_HANDLE; }