summaryrefslogtreecommitdiffstats
path: root/meta-facebook/meta-wedge/recipes-wedge/sms-kcsd/sms-kcsd/sms-kcsd.c
diff options
context:
space:
mode:
Diffstat (limited to 'meta-facebook/meta-wedge/recipes-wedge/sms-kcsd/sms-kcsd/sms-kcsd.c')
-rw-r--r--meta-facebook/meta-wedge/recipes-wedge/sms-kcsd/sms-kcsd/sms-kcsd.c144
1 files changed, 144 insertions, 0 deletions
diff --git a/meta-facebook/meta-wedge/recipes-wedge/sms-kcsd/sms-kcsd/sms-kcsd.c b/meta-facebook/meta-wedge/recipes-wedge/sms-kcsd/sms-kcsd/sms-kcsd.c
new file mode 100644
index 0000000..a264fb7
--- /dev/null
+++ b/meta-facebook/meta-wedge/recipes-wedge/sms-kcsd/sms-kcsd/sms-kcsd.c
@@ -0,0 +1,144 @@
+/*
+ * sms-kcsd
+ *
+ * Copyright 2014-present Facebook. All Rights Reserved.
+ *
+ * Daemon to monitor traffic coming from sms-kcs interface
+ * and respond to the command using IPMI stack
+ *
+ * TODO: Determine if the daemon is already started.
+ * TODO: Cache the file descriptors instead of fopen/fclose everytime
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <syslog.h>
+#include <facebook/alert_control.h>
+#include <facebook/ipmi.h>
+
+
+#define PATH_SMS_KCS "/sys/bus/i2c/drivers/panther_plus/4-0040/sms_kcs"
+#define MAX_ALERT_CONTROL_RETRIES 3
+
+typedef struct {
+ unsigned char fbid;
+ unsigned char length;
+ unsigned char buf[];
+} kcs_msg_t;
+
+/*
+ * Function to check if there is any new KCS message available
+ * TODO: Will be replaced by interrupt-driven approach
+ */
+static bool
+is_new_kcs_msg(void) {
+ return is_alert_present(FBID_SMS_KCS);
+}
+
+/*
+ * KCS Message Handler:
+ * - Reads the incoming request on KCS channel
+ * - Invokes IPMI handler to provide response
+ * - Writes reply back to KCS channel
+ */
+static int
+handle_kcs_msg(void) {
+ FILE *fp;
+ kcs_msg_t *msg;
+ unsigned char rbuf[256] = {0};
+ unsigned char tbuf[256] = {0};
+ unsigned char tlen = 0;
+ int count = 0;
+ int i = 0;
+
+ // Reads incoming request
+ fp = fopen(PATH_SMS_KCS, "r");
+ if (!fp) {
+ syslog(LOG_ALERT, "failed to open file %s\n", PATH_SMS_KCS);
+ return -1;
+ }
+
+ count = fread(rbuf, sizeof(unsigned char), sizeof(rbuf), fp);
+ if (count == 0) {
+ syslog(LOG_INFO, "fread returns zero bytes\n");
+ fclose(fp);
+ return -1;
+ }
+
+ fclose(fp);
+
+ msg = (kcs_msg_t*)rbuf;
+
+ // Invoke IPMI handler
+ ipmi_handle(msg->buf, msg->length, &tbuf[1], &tlen);
+
+ // Fill the length as returned by IPMI stack
+ tbuf[0] = tlen;
+
+ //Write Reply back to KCS channel
+ fp = fopen(PATH_SMS_KCS, "w");
+ if (!fp) {
+ syslog(LOG_ALERT, "failed to open file %s\n", PATH_SMS_KCS);
+ return -1;
+ }
+
+ count = fwrite(tbuf, sizeof(unsigned char), tlen+1, fp);
+ if (count != tlen+1) {
+ syslog(LOG_ALERT, "fwrite returns: %d, expected: %d\n", count, tlen+1);
+ fclose(fp);
+ return -1;
+ }
+
+ fclose(fp);
+
+ return 0;
+}
+
+/*
+ * Daemon Main loop
+ */
+int main(int argc, char **argv) {
+ int i;
+ int ret;
+ daemon(1, 0);
+ openlog("sms-kcs", LOG_CONS, LOG_DAEMON);
+
+ // Enable alert for SMS KCS Function Block
+ for (i = 0; i < MAX_ALERT_CONTROL_RETRIES; i++) {
+ ret = alert_control(FBID_SMS_KCS, FLAG_ENABLE);
+ if (!ret) {
+ break;
+ }
+ sleep(2);
+ }
+
+ // Exit with error in case we can not set the Alert
+ if(ret) {
+ syslog(LOG_ALERT, "Can not enable SMS KCS Alert\n");
+ exit(-1);
+ }
+
+ // Forever loop to poll and process KCS messages
+ while (1) {
+ if (is_new_kcs_msg()) {
+ handle_kcs_msg();
+ }
+ sleep(1);
+ }
+}
OpenPOWER on IntegriCloud