123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169 |
- /*****************************************************************
- ******************************************************************
- *** ***
- *** (C)Copyright 2012, American Megatrends Inc. ***
- *** ***
- *** All Rights Reserved ***
- *** ***
- *** 5555 Oakbrook Parkway, Norcross, GA 30093, USA ***
- *** ***
- *** Phone 770.246.8600 ***
- *** ***
- ******************************************************************
- ******************************************************************
- ******************************************************************
- *
- * Filename: aes.c
- *
- * Descriptions: Code that connects to AES engine and sends any
- * new SEL event generated
- *
- *
- * Author: Manish Tomar (manisht@ami.com)
- *
- ******************************************************************/
- #include <sys/types.h>
- #include <sys/un.h>
- #include <sys/socket.h>
- #include <errno.h>
- #include <unistd.h>
- #include <fcntl.h>
- #include <poll.h>
- #include <string.h>
- #include <stdio.h>
- #include "aes.h"
- #include "featuredef.h"
- #define AES_PATH "/tmp/aesevents"
- #define MAX_TRIES 3
- static int _g_tries = 0;
- static int _connect()
- {
- int sock = -1, ret;
- int flags;
- int optval = -1;
- socklen_t optlen = sizeof(optval);
- char *errstr, errbuf[128];
- struct sockaddr_un addr;
- struct pollfd pfd = { 0 };
-
- //errno = 0;
-
- // create socket
- addr.sun_family = AF_UNIX;
- strncpy(addr.sun_path, AES_PATH, sizeof(addr.sun_path));
- sock = socket(AF_UNIX, SOCK_STREAM, 0);
- if (sock == -1) {
- errstr = "error creating Unix Socket";
- goto error;
- }
-
- // set non-block
- flags = fcntl(sock, F_GETFL, 0);
- fcntl(sock, F_SETFL, flags | O_NONBLOCK);
-
- // connect it
- if (0 == connect(sock, (struct sockaddr *)&addr, sizeof(addr))) {
- return sock;
- }
-
- // connection failed. wait if in progress
- if (errno != EINPROGRESS) {
- errstr = "Connect failed";
- goto error;
- }
-
- // Wait for max of 5 milliseconds
- pfd.fd = sock;
- pfd.events = POLLOUT;
- if (-1 == (ret = poll(&pfd, 1, 5))) {
- errstr = "Error polling";
- goto error;
- }
- if (ret == 0) {
- errstr = "poll timed out";
- goto error;
- }
- if (ret != 1) {
- errstr = "unexpected poll return";
- goto error;
- }
- if (!(pfd.revents & POLLOUT)) {
- errstr = "unexected event on fd";
- goto error;
- }
- if (-1 == getsockopt(sock, SOL_SOCKET, SO_ERROR, &optval, &optlen)) {
- errstr = "error from getsockopt";
- goto error;
- }
- if (optval != 0) {
- errstr = "error connecting to aes";
- goto error;
- }
-
- return sock;
-
- error:
- memset(errbuf, 0, sizeof(errbuf));
- strerror_r(errno, errbuf, sizeof(errbuf));
- fprintf(stderr, "%s: %s\n", errstr, errbuf);
- if (sock != -1)
- close(sock);
- return -1;
- }
- int AES_SendEvent(SELEventRecord_T *event)
- {
- static int sock = -1; // UDS connected socket
- static int enabled = -1;
- ssize_t sent;
-
- // check if AES is enabled in stack
- if (enabled == -1) {
- enabled = IsFeatureEnabled("CONFIG_SPX_FEATURE_AUTOMATION_ENGINE");
- }
- if (!enabled)
- return 0;
- resend:
- if (sock == -1) {
- // First time called. Make UDS connection with small timeout
- if (_g_tries > MAX_TRIES) {
- fprintf(stderr, "AES connection attempts exceeded max tries\n");
- return -1;
- }
- sock = _connect();
- if (sock == -1) {
- _g_tries++;
- return -1;
- }
- }
-
- // Send the event using existing socket connection
- if (sizeof(*event) != (sent = send(sock, event, sizeof(*event), MSG_NOSIGNAL))) {
- if (sent == -1) {
- if (errno == ECONNRESET || errno == EPIPE) {
- // Could happen if aes engine is restarted
- sock = -1;
- _g_tries = 0;
- goto resend;
- }
- char buf[128];
- strerror_r(errno, buf, sizeof(buf));
- fprintf(stderr, "AES: Error sending data: %s\n", buf);
- }
- else {
- fprintf(stderr, "AES: Partial data sent. UNHANDLED AND UNEXPECTED\n");
- }
- // setting sock to -1 to reconnect next time
- // TODO: But this event will not be sent. May need to change to reconnect and send this event
- return (sock = -1);
- }
-
- return 0;
- }
|