clang-format: run clang-format on C/C++ code
[contrib/mraa.git] / src / mraa.c
index 11c21ac..890d711 100644 (file)
 #include <stdlib.h>
 #include <sched.h>
 #include <string.h>
+#include <pwd.h>
+#include <glob.h>
+
 
 #include "mraa_internal.h"
-#include "intel_galileo_rev_d.h"
-#include "intel_galileo_rev_g.h"
-#include "intel_edison_fab_c.h"
-#include "intel_de3815.h"
 #include "gpio.h"
 #include "version.h"
 
@@ -40,7 +39,7 @@ mraa_board_t* plat = NULL;
 static mraa_platform_t platform_type = MRAA_UNKNOWN_PLATFORM;
 mraa_adv_func_t* advance_func;
 
-const char *
+const char*
 mraa_get_version()
 {
     return gVERSION;
@@ -56,9 +55,20 @@ mraa_set_log_level(int level)
     return MRAA_ERROR_INVALID_PARAMETER;
 }
 
+#if (defined SWIGPYTHON) || (defined SWIG)
+mraa_result_t
+#else
 mraa_result_t __attribute__((constructor))
+#endif
 mraa_init()
 {
+    if (plat != NULL) {
+        return MRAA_ERROR_PLATFORM_ALREADY_INITIALISED;
+    }
+
+    uid_t proc_euid = geteuid();
+    struct passwd* proc_user = getpwuid(proc_euid);
+
 #ifdef DEBUG
     setlogmask(LOG_UPTO(LOG_DEBUG));
 #else
@@ -66,70 +76,46 @@ mraa_init()
 #endif
 
     openlog("libmraa", LOG_CONS | LOG_PID | LOG_NDELAY, LOG_LOCAL1);
-    syslog(LOG_DEBUG, "libmraa initialised by user %d", getuid());
+    syslog(LOG_NOTICE, "libmraa version %s initialised by user '%s' with EUID %d",
+           mraa_get_version(), (proc_user != NULL) ? proc_user->pw_name : "<unknown>", proc_euid);
 
-    if (plat != NULL) {
-        return MRAA_ERROR_PLATFORM_ALREADY_INITIALISED;
-    }
 #ifdef SWIGPYTHON
     // Initialise python threads, this allows use to grab the GIL when we are
     // required to do so
     Py_InitializeEx(0);
     PyEval_InitThreads();
 #endif
-    // detect a galileo gen2 board
-    char *line = NULL;
-    // let getline allocate memory for *line
-    size_t len = 0;
-    FILE *fh = fopen("/sys/devices/virtual/dmi/id/board_name", "r");
-    if (fh != NULL) {
-        if (getline(&line, &len, fh) != -1) {
-            if (strncmp(line, "GalileoGen2", 10) == 0) {
-                platform_type = MRAA_INTEL_GALILEO_GEN2;
-            } else if (strncmp(line, "BODEGA BAY", 10) == 0) {
-                platform_type = MRAA_INTEL_EDISON_FAB_C;
-            } else if (strncmp(line, "SALT BAY", 7) == 0) {
-                platform_type = MRAA_INTEL_EDISON_FAB_C;
-            } else if (strncmp(line, "DE3815", 6) == 0) {
-                platform_type = MRAA_INTEL_DE3815;
-            } else {
-                platform_type = MRAA_INTEL_GALILEO_GEN1;
-            }
-            free(line);
-        }
-        fclose(fh);
-    }
-
     advance_func = (mraa_adv_func_t*) malloc(sizeof(mraa_adv_func_t));
     memset(advance_func, 0, sizeof(mraa_adv_func_t));
 
-    switch(platform_type) {
-        case MRAA_INTEL_GALILEO_GEN2:
-            plat = mraa_intel_galileo_gen2();
-            break;
-        case MRAA_INTEL_GALILEO_GEN1:
-            plat = mraa_intel_galileo_rev_d();
-            break;
-        case MRAA_INTEL_EDISON_FAB_C:
-            plat = mraa_intel_edison_fab_c();
-            break;
-        case MRAA_INTEL_DE3815:
-            plat = mraa_intel_de3815();
-            break;
-        default:
-            plat = mraa_intel_galileo_rev_d();
-            syslog(LOG_ERR, "Platform not found, initialising MRAA_INTEL_GALILEO_GEN1");
+#ifdef X86PLAT
+    // Use runtime x86 platform detection
+    platform_type = mraa_x86_platform();
+#elif ARMPLAT
+    // Use runtime ARM platform detection
+    platform_type = mraa_arm_platform();
+#else
+#error mraa_ARCH NOTHING
+#endif
+
+    if (plat == NULL) {
+        printf("mraa: FATAL error, failed to initialise platform\n");
+        return MRAA_ERROR_PLATFORM_NOT_INITIALISED;
     }
 
-    syslog(LOG_NOTICE, "libmraa initialised for platform %d", platform_type);
+    syslog(LOG_INFO, "libmraa initialised for platform '%s' of type %d", mraa_get_platform_name(), platform_type);
     return MRAA_SUCCESS;
 }
 
 void
 mraa_deinit()
 {
-    free(plat->pins);
-    free(plat);
+    if (plat != NULL) {
+        if (plat->pins != NULL) {
+            free(plat->pins);
+        }
+        free(plat);
+    }
     closelog();
 }
 
@@ -141,175 +127,37 @@ mraa_set_priority(const unsigned int priority)
     memset(&sched_s, 0, sizeof(struct sched_param));
     if (priority > sched_get_priority_max(SCHED_RR)) {
         sched_s.sched_priority = sched_get_priority_max(SCHED_RR);
-    }
-    else {
+    } else {
         sched_s.sched_priority = priority;
     }
 
     return sched_setscheduler(0, SCHED_RR, &sched_s);
 }
 
-static mraa_result_t
+mraa_result_t
 mraa_setup_mux_mapped(mraa_pin_t meta)
 {
     int mi;
+
     for (mi = 0; mi < meta.mux_total; mi++) {
         mraa_gpio_context mux_i;
         mux_i = mraa_gpio_init_raw(meta.mux[mi].pin);
-        if (mux_i == NULL)
+        if (mux_i == NULL) {
             return MRAA_ERROR_INVALID_HANDLE;
+        }
+        // this function will sometimes fail, however this is not critical as
+        // long as the write succeeds - Test case galileo gen2 pin2
         mraa_gpio_dir(mux_i, MRAA_GPIO_OUT);
-        if (mraa_gpio_write(mux_i, meta.mux[mi].value) != MRAA_SUCCESS)
-            return MRAA_ERROR_INVALID_RESOURCE;
-    }
-    return MRAA_SUCCESS;
-}
-
-unsigned int
-mraa_setup_gpio(int pin)
-{
-    if (plat == NULL)
-        return MRAA_PLATFORM_NO_INIT;
-
-    if (pin < 0 || pin > plat->phy_pin_count)
-        return MRAA_NO_SUCH_IO;
-
-    if(plat->pins[pin].capabilites.gpio != 1)
-      return MRAA_NO_SUCH_IO;
-
-    if (plat->pins[pin].gpio.mux_total > 0)
-       if (mraa_setup_mux_mapped(plat->pins[pin].gpio) != MRAA_SUCCESS)
-            return MRAA_NO_SUCH_IO;
-    return plat->pins[pin].gpio.pinmap;
-}
-
-unsigned int
-mraa_setup_aio(int aio)
-{
-    if (plat == NULL)
-        return MRAA_PLATFORM_NO_INIT;
-
-    if (aio < 0 || aio > plat->aio_count)
-        return MRAA_NO_SUCH_IO;
-
-    int pin = aio + plat->gpio_count;
-
-    if (plat->pins[pin].capabilites.aio != 1)
-      return MRAA_NO_SUCH_IO;
-
-    if (plat->pins[pin].aio.mux_total > 0)
-       if (mraa_setup_mux_mapped(plat->pins[pin].aio) != MRAA_SUCCESS)
-            return MRAA_NO_SUCH_IO;
-    return plat->pins[pin].aio.pinmap;
-}
-
-unsigned int
-mraa_setup_i2c(int* bus)
-{
-    if (plat == NULL)
-        return MRAA_PLATFORM_NO_INIT;
-
-    if (plat->i2c_bus_count == 0) {
-        syslog(LOG_ERR, "No i2c buses defined in platform");
-        return MRAA_NO_SUCH_IO;
-    }
-    if (*bus >= plat->i2c_bus_count) {
-        syslog(LOG_ERR, "Above i2c bus count");
-        return MRAA_NO_SUCH_IO;
-    }
-
-    if (plat->i2c_bus[*bus].bus_id == -1) {
-        syslog(LOG_ERR, "Invalid i2c bus, moving to default i2c bus");
-        *bus = plat->def_i2c_bus;
-    }
-
-    int pos = plat->i2c_bus[*bus].sda;
-    if (plat->pins[pos].i2c.mux_total > 0)
-        if (mraa_setup_mux_mapped(plat->pins[pos].i2c) != MRAA_SUCCESS)
-             return MRAA_IO_SETUP_FAILURE;
-
-    pos = plat->i2c_bus[*bus].scl;
-    if (plat->pins[pos].i2c.mux_total > 0)
-        if (mraa_setup_mux_mapped(plat->pins[pos].i2c) != MRAA_SUCCESS)
-             return MRAA_IO_SETUP_FAILURE;
-
-    return plat->i2c_bus[*bus].bus_id;
-}
-
-mraa_spi_bus_t*
-mraa_setup_spi(int bus)
-{
-    if (plat == NULL)
-        return NULL;
+        mraa_gpio_owner(mux_i, 0);
 
-    if (plat->spi_bus_count >! 0) {
-        syslog(LOG_ERR, "No spi buses defined in platform");
-        return NULL;
-    }
-    if (plat->spi_bus_count == 1) {
-        bus = plat->def_spi_bus;
-    }
-    if (bus >= plat->spi_bus_count) {
-        syslog(LOG_ERR, "Above spi bus count");
-        return NULL;
-    }
-
-    int pos = plat->spi_bus[bus].sclk;
-    if (plat->pins[pos].spi.mux_total > 0)
-        if (mraa_setup_mux_mapped(plat->pins[pos].spi) != MRAA_SUCCESS)
-             return NULL;
-
-    pos = plat->spi_bus[bus].mosi;
-    if (plat->pins[pos].spi.mux_total > 0)
-        if (mraa_setup_mux_mapped(plat->pins[pos].spi) != MRAA_SUCCESS)
-             return NULL;
-
-    pos = plat->spi_bus[bus].miso;
-    if (plat->pins[pos].spi.mux_total > 0)
-        if (mraa_setup_mux_mapped(plat->pins[pos].spi) != MRAA_SUCCESS)
-             return NULL;
-
-    pos = plat->spi_bus[bus].cs;
-    if (plat->pins[pos].spi.mux_total > 0)
-        if (mraa_setup_mux_mapped(plat->pins[pos].spi) != MRAA_SUCCESS)
-             return NULL;
-
-    mraa_spi_bus_t *spi = &(plat->spi_bus[bus]);
-    return spi;
-}
-
-mraa_pin_t*
-mraa_setup_pwm(int pin)
-{
-    if (plat == NULL)
-        return NULL;
-
-    if (plat->pins[pin].capabilites.pwm != 1)
-        return NULL;
-
-    if (plat->pins[pin].capabilites.gpio == 1) {
-        mraa_gpio_context mux_i;
-        mux_i = mraa_gpio_init_raw(plat->pins[pin].gpio.pinmap);
-        if (mux_i == NULL)
-            return NULL;
-        if (mraa_gpio_dir(mux_i, MRAA_GPIO_OUT) != MRAA_SUCCESS)
-            return NULL;
-        // Current REV D quirk. //TODO GEN 2
-        if (mraa_gpio_write(mux_i, 1) != MRAA_SUCCESS)
-            return NULL;
-        if (mraa_gpio_close(mux_i) != MRAA_SUCCESS)
-            return NULL;
+        if (mraa_gpio_write(mux_i, meta.mux[mi].value) != MRAA_SUCCESS) {
+            mraa_gpio_close(mux_i);
+            return MRAA_ERROR_INVALID_RESOURCE;
+        }
+        mraa_gpio_close(mux_i);
     }
 
-    if (plat->pins[pin].pwm.mux_total > 0)
-       if (mraa_setup_mux_mapped(plat->pins[pin].pwm) != MRAA_SUCCESS)
-            return NULL;
-
-    mraa_pin_t *ret;
-    ret = (mraa_pin_t*) malloc(sizeof(mraa_pin_t));
-    ret->pinmap = plat->pins[pin].pwm.pinmap;
-    ret->parent_id = plat->pins[pin].pwm.parent_id;
-    return ret;
+    return MRAA_SUCCESS;
 }
 
 void
@@ -372,65 +220,51 @@ mraa_pin_mode_test(int pin, mraa_pinmodes_t mode)
         if (plat == NULL)
             return 0;
     }
-    if (pin > plat->phy_pin_count || pin < 0)
+    if (pin > (plat->phy_pin_count - 1) || pin < 0)
         return 0;
 
-    switch(mode) {
+    switch (mode) {
         case MRAA_PIN_VALID:
             if (plat->pins[pin].capabilites.valid == 1)
                 return 1;
             break;
         case MRAA_PIN_GPIO:
-            if (plat->pins[pin].capabilites.gpio ==1)
+            if (plat->pins[pin].capabilites.gpio == 1)
                 return 1;
             break;
         case MRAA_PIN_PWM:
-            if (plat->pins[pin].capabilites.pwm ==1)
+            if (plat->pins[pin].capabilites.pwm == 1)
                 return 1;
             break;
         case MRAA_PIN_FAST_GPIO:
-            if (plat->pins[pin].capabilites.fast_gpio ==1)
+            if (plat->pins[pin].capabilites.fast_gpio == 1)
                 return 1;
             break;
         case MRAA_PIN_SPI:
-            if (plat->pins[pin].capabilites.spi ==1)
+            if (plat->pins[pin].capabilites.spi == 1)
                 return 1;
             break;
         case MRAA_PIN_I2C:
-            if (plat->pins[pin].capabilites.i2c ==1)
+            if (plat->pins[pin].capabilites.i2c == 1)
                 return 1;
             break;
         case MRAA_PIN_AIO:
-            if (pin < plat->aio_count)
-                pin = pin + plat->gpio_count;
-            if (plat->pins[pin].capabilites.aio ==1)
+            if (plat->pins[pin].capabilites.aio == 1)
                 return 1;
             break;
-        default: break;
+        case MRAA_PIN_UART:
+            if (plat->pins[pin].capabilites.uart == 1)
+                return 1;
+            break;
+        default:
+            syslog(LOG_NOTICE, "requested pinmode invalid");
+            break;
     }
     return 0;
 }
 
-mraa_mmap_pin_t*
-mraa_setup_mmap_gpio(int pin)
-{
-    if (plat == NULL)
-        return NULL;
-
-    if (plat->pins[pin].capabilites.fast_gpio != 1)
-        return NULL;
-
-    if (plat->pins[pin].mmap.gpio.mux_total > 0)
-       if (mraa_setup_mux_mapped(plat->pins[pin].mmap.gpio) != MRAA_SUCCESS)
-            return NULL;
-
-    if (mraa_setup_mux_mapped(plat->pins[pin].mmap.gpio) != MRAA_SUCCESS)
-            return NULL;
-    mraa_mmap_pin_t *ret = &(plat->pins[pin].mmap);
-    return ret;
-}
-
-mraa_platform_t mraa_get_platform_type()
+mraa_platform_t
+mraa_get_platform_type()
 {
     return platform_type;
 }
@@ -459,31 +293,84 @@ mraa_adc_supported_bits()
     return plat->adc_supported;
 }
 
-mraa_result_t
-mraa_setup_uart(int index)
+char*
+mraa_get_platform_name()
 {
-    if (plat == NULL)
-        return MRAA_ERROR_PLATFORM_NOT_INITIALISED;
+    if (plat == NULL) {
+        return NULL;
+    }
+    return (char*) plat->platform_name;
+}
 
-    if (plat->uart_dev_count == 0)
-        return MRAA_ERROR_FEATURE_NOT_SUPPORTED;
+unsigned int
+mraa_get_pin_count()
+{
+    if (plat == NULL) {
+        return 0;
+    }
+    return plat->phy_pin_count;
+}
 
-    if (plat->uart_dev_count <= index)
-        return MRAA_ERROR_NO_RESOURCES;
+mraa_boolean_t
+mraa_file_exist(char* filename)
+{
+    glob_t results;
+    results.gl_pathc = 0;
+    glob(filename, 0, NULL, &results);
+    int file_found = results.gl_pathc == 1;
+    globfree(&results);
+    return file_found;
+}
 
-    int pos = plat->uart_dev[index].rx;
-    if (pos >= 0) {
-        if (plat->pins[pos].uart.mux_total > 0)
-            if (mraa_setup_mux_mapped(plat->pins[pos].uart) != MRAA_SUCCESS)
-                return MRAA_ERROR_INVALID_RESOURCE;
+char*
+mraa_get_pin_name(int pin)
+{
+    if (plat == NULL) {
+        return NULL;
     }
+    if (pin > (plat->phy_pin_count - 1) || pin < 0)
+        return NULL;
+    return (char*) plat->pins[pin].name;
+}
 
-    if (pos >= 0) {
-        pos = plat->uart_dev[index].tx;
-        if (plat->pins[pos].uart.mux_total > 0)
-            if (mraa_setup_mux_mapped(plat->pins[pos].uart) != MRAA_SUCCESS)
-                return MRAA_ERROR_INVALID_RESOURCE;
-    }
+char*
+mraa_file_unglob(char* filename)
+{
+    glob_t results;
+    char* res = NULL;
+    results.gl_pathc = 0;
+    glob(filename, 0, NULL, &results);
+    if (results.gl_pathc == 1)
+        res = strdup(results.gl_pathv[0]);
+    globfree(&results);
+    return res;
+}
 
-    return MRAA_SUCCESS;
+mraa_boolean_t
+mraa_link_targets(char* filename, char* targetname)
+{
+    int size = 100;
+    int nchars = 0;
+    char* buffer = NULL;
+    while (nchars == 0) {
+        buffer = (char*) realloc(buffer, size);
+        if (buffer == NULL)
+            return 0;
+        nchars = readlink(filename, buffer, size);
+        if (nchars < 0) {
+            free(buffer);
+            return 0;
+        }
+        if (nchars >= size) {
+            size *= 2;
+            nchars = 0;
+        }
+    }
+    if (strstr(buffer, targetname)) {
+        free(buffer);
+        return 1;
+    } else {
+        free(buffer);
+        return 0;
+    }
 }