clang-format: run clang-format on C/C++ code
[contrib/mraa.git] / src / mraa.c
index 321e165..890d711 100644 (file)
@@ -27,8 +27,9 @@
 #include <stdlib.h>
 #include <sched.h>
 #include <string.h>
+#include <pwd.h>
+#include <glob.h>
 
-#define DEBUG
 
 #include "mraa_internal.h"
 #include "gpio.h"
@@ -38,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;
@@ -54,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
@@ -64,11 +76,9 @@ 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
@@ -81,21 +91,31 @@ mraa_init()
 #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_INFO, "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();
 }
 
@@ -107,8 +127,7 @@ 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;
     }
 
@@ -119,15 +138,25 @@ 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)
+        mraa_gpio_owner(mux_i, 0);
+
+        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);
     }
+
     return MRAA_SUCCESS;
 }
 
@@ -191,46 +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_platform_t mraa_get_platform_type()
+mraa_platform_t
+mraa_get_platform_type()
 {
     return platform_type;
 }
@@ -259,39 +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->uart_dev_count == 0)
-        return MRAA_ERROR_FEATURE_NOT_SUPPORTED;
-
-    if (plat->uart_dev_count <= index)
-        return MRAA_ERROR_NO_RESOURCES;
-
-    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;
+    if (plat == NULL) {
+        return NULL;
     }
+    return (char*) plat->platform_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;
+unsigned int
+mraa_get_pin_count()
+{
+    if (plat == NULL) {
+        return 0;
     }
+    return plat->phy_pin_count;
+}
 
-    return MRAA_SUCCESS;
+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;
 }
 
 char*
-mraa_get_platform_name()
+mraa_get_pin_name(int pin)
 {
-    if (plat == NULL)
-        return "Unknown";
-    return plat->platform_name;
+    if (plat == NULL) {
+        return NULL;
+    }
+    if (pin > (plat->phy_pin_count - 1) || pin < 0)
+        return NULL;
+    return (char*) plat->pins[pin].name;
+}
+
+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;
+}
+
+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;
+    }
 }