clang-format: run clang-format on C/C++ code
[contrib/mraa.git] / src / mraa.c
index ee81559..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 "gpio.h"
 #include "version.h"
 
-//static mraa_pininfo_t* pindata;
-static mraa_board_t* plat = NULL;
+mraa_board_t* plat = NULL;
 static mraa_platform_t platform_type = MRAA_UNKNOWN_PLATFORM;
-static mraa_adv_func* advance = NULL;
+mraa_adv_func_t* advance_func;
 
-const char *
+const char*
 mraa_get_version()
 {
     return gVERSION;
 }
 
-#if 0
-const mraa_adv_func*
-mraa_get_advance()
+mraa_result_t
+mraa_set_log_level(int level)
 {
-    return (const mraa_adv_func*) advance;
+    if (level <= 7 && level >= 0) {
+        setlogmask(LOG_UPTO(level));
+        return MRAA_SUCCESS;
+    }
+    return MRAA_ERROR_INVALID_PARAMETER;
 }
-#endif
 
+#if (defined SWIGPYTHON) || (defined SWIG)
 mraa_result_t
+#else
+mraa_result_t __attribute__((constructor))
+#endif
 mraa_init()
 {
-    /** Once more board definitions have been added,
-     *  A method for detecting them will need to be devised.
-     */
     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
+    setlogmask(LOG_UPTO(LOG_NOTICE));
+#endif
+
+    openlog("libmraa", LOG_CONS | LOG_PID | LOG_NDELAY, LOG_LOCAL1);
+    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);
+
 #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 {
-                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));
+
+#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
 
-    advance = (mraa_adv_func*) malloc(sizeof(mraa_adv_func));
-    switch(platform_type) {
-        case MRAA_INTEL_GALILEO_GEN2:
-            plat = mraa_intel_galileo_gen2(advance);
-            break;
-        case MRAA_INTEL_GALILEO_GEN1:
-            plat = mraa_intel_galileo_rev_d(advance);
-            break;
-        default:
-            plat = mraa_intel_galileo_rev_d(advance);
-            fprintf(stderr, "Platform not found, initialising MRAA_INTEL_GALILEO_GEN1\n");
+    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 '%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();
 }
 
 int
@@ -116,211 +127,88 @@ 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;
-}
+        mraa_gpio_owner(mux_i, 0);
 
-unsigned int
-mraa_setup_gpio(int pin)
-{
-    if (plat == NULL)
-        return -1;
-
-    if (pin < 0 || pin > plat->phy_pin_count)
-        return -1;
-
-    if(plat->pins[pin].capabilites.gpio != 1)
-      return -1;
-
-    if (plat->pins[pin].gpio.mux_total > 0)
-       if (mraa_setup_mux_mapped(plat->pins[pin].gpio) != MRAA_SUCCESS)
-            return -1;
-    return plat->pins[pin].gpio.pinmap;
-}
-
-unsigned int
-mraa_setup_aio(int aio)
-{
-    if (plat == NULL)
-        return -3;
-
-    if (aio < 0 || aio > plat->aio_count)
-        return -1;
-
-    int pin = aio + plat->gpio_count;
-
-    if (plat->pins[pin].capabilites.aio != 1)
-      return -1;
-
-    if (plat->pins[pin].aio.mux_total > 0)
-       if (mraa_setup_mux_mapped(plat->pins[pin].aio) != MRAA_SUCCESS)
-            return -1;
-    return plat->pins[pin].aio.pinmap;
-}
-
-unsigned int
-mraa_setup_i2c(int bus)
-{
-    if (plat == NULL)
-        return -3;
-
-    if (plat->i2c_bus_count >! 0) {
-        fprintf(stderr, "No i2c buses defined in platform");
-        return -1;
-    }
-    if (bus >= plat->i2c_bus_count) {
-        fprintf(stderr, "Above i2c bus count");
-        return -1;
-    }
-
-    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 -2;
-
-    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 -2;
-
-    return plat->i2c_bus[bus].bus_id;
-}
-
-mraa_spi_bus_t*
-mraa_setup_spi(int bus)
-{
-    if (plat == NULL)
-        return NULL;
-
-    if (plat->spi_bus_count >! 0) {
-        fprintf(stderr, "No spi buses defined in platform");
-        return NULL;
-    }
-    if (bus >= plat->spi_bus_count) {
-        fprintf(stderr, "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;
-
-    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
 mraa_result_print(mraa_result_t result)
 {
     switch (result) {
-        case MRAA_SUCCESS: fprintf(stderr, "MRAA: SUCCESS\n");
-                          break;
+        case MRAA_SUCCESS:
+            fprintf(stdout, "MRAA: SUCCESS\n");
+            break;
         case MRAA_ERROR_FEATURE_NOT_IMPLEMENTED:
-                          fprintf(stderr, "MRAA: Feature not implemented.\n");
-                          break;
+            fprintf(stdout, "MRAA: Feature not implemented.\n");
+            break;
         case MRAA_ERROR_FEATURE_NOT_SUPPORTED:
-                          fprintf(stderr, "MRAA: Feature not supported by Hardware.\n");
-                          break;
+            fprintf(stdout, "MRAA: Feature not supported by Hardware.\n");
+            break;
         case MRAA_ERROR_INVALID_VERBOSITY_LEVEL:
-                          fprintf(stderr, "MRAA: Invalid verbosity level.\n");
-                          break;
+            fprintf(stdout, "MRAA: Invalid verbosity level.\n");
+            break;
         case MRAA_ERROR_INVALID_PARAMETER:
-                          fprintf(stderr, "MRAA: Invalid parameter.\n");
-                          break;
+            fprintf(stdout, "MRAA: Invalid parameter.\n");
+            break;
         case MRAA_ERROR_INVALID_HANDLE:
-                          fprintf(stderr, "MRAA: Invalid Handle.\n");
-                          break;
+            fprintf(stdout, "MRAA: Invalid Handle.\n");
+            break;
         case MRAA_ERROR_NO_RESOURCES:
-                          fprintf(stderr, "MRAA: No resources.\n");
-                          break;
+            fprintf(stdout, "MRAA: No resources.\n");
+            break;
         case MRAA_ERROR_INVALID_RESOURCE:
-                          fprintf(stderr, "MRAA: Invalid resource.\n");
-                          break;
+            fprintf(stdout, "MRAA: Invalid resource.\n");
+            break;
         case MRAA_ERROR_INVALID_QUEUE_TYPE:
-                          fprintf(stderr, "MRAA: Invalid Queue Type.\n");
-                          break;
+            fprintf(stdout, "MRAA: Invalid Queue Type.\n");
+            break;
         case MRAA_ERROR_NO_DATA_AVAILABLE:
-                          fprintf(stderr, "MRAA: No Data available.\n");
-                          break;
+            fprintf(stdout, "MRAA: No Data available.\n");
+            break;
         case MRAA_ERROR_INVALID_PLATFORM:
-                          fprintf(stderr, "MRAA: Platform not recognised.\n");
-                          break;
+            fprintf(stdout, "MRAA: Platform not recognised.\n");
+            break;
         case MRAA_ERROR_PLATFORM_NOT_INITIALISED:
-                          fprintf(stderr, "MRAA: Platform not initialised.\n");
-                          break;
+            fprintf(stdout, "MRAA: Platform not initialised.\n");
+            break;
         case MRAA_ERROR_PLATFORM_ALREADY_INITIALISED:
-                          fprintf(stderr, "MRAA: Platform already initialised.\n");
-                          break;
+            fprintf(stdout, "MRAA: Platform already initialised.\n");
+            break;
         case MRAA_ERROR_UNSPECIFIED:
-                          fprintf(stderr, "MRAA: Unspecified Error.\n");
-                          break;
-        default:     fprintf(stderr, "MRAA: Unrecognised error.\n");
-                          break;
+            fprintf(stdout, "MRAA: Unspecified Error.\n");
+            break;
+        default:
+            fprintf(stdout, "MRAA: Unrecognised error.\n");
+            break;
     }
 }
 
@@ -332,102 +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;
-    }
-    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_result_t
-mraa_swap_complex_gpio(int pin, int out)
-{
-    if (plat == NULL)
-        return MRAA_ERROR_INVALID_PLATFORM;
-
-    switch (platform_type) {
-        case MRAA_INTEL_GALILEO_GEN2:
-            if (plat->pins[pin].gpio.complex_cap.complex_pin != 1)
-                return MRAA_SUCCESS;
-            if (plat->pins[pin].gpio.complex_cap.output_en == 1) {
-                mraa_gpio_context output_e;
-                output_e = mraa_gpio_init_raw(plat->pins[pin].gpio.output_enable);
-                if (mraa_gpio_dir(output_e, MRAA_GPIO_OUT) != MRAA_SUCCESS)
-                    return MRAA_ERROR_INVALID_RESOURCE;
-                int output_val;
-                if (plat->pins[pin].gpio.complex_cap.output_en_high == 1)
-                    output_val = out;
-                else
-                    if (out == 1)
-                        output_val = 0;
-                    else
-                        output_val = 1;
-                if (mraa_gpio_write(output_e, output_val) != MRAA_SUCCESS)
-                    return MRAA_ERROR_INVALID_RESOURCE;
-            }
-            //if (plat->pins[pin].gpio.complex_cap.pullup_en == 1) {
-            //    mraa_gpio_context pullup_e;
-            //    pullup_e = mraa_gpio_init_raw(plat->pins[pin].gpio.pullup_enable);
-            //    if (mraa_gpio_mode(pullup_e, MRAA_GPIO_HIZ) != MRAA_SUCCESS)
-            //        return MRAA_ERROR_INVALID_RESOURCE;
-            //}
+        case MRAA_PIN_UART:
+            if (plat->pins[pin].capabilites.uart == 1)
+                return 1;
+            break;
+        default:
+            syslog(LOG_NOTICE, "requested pinmode invalid");
             break;
-        default: return MRAA_SUCCESS;
     }
+    return 0;
 }
 
-mraa_platform_t mraa_get_platform_type()
+mraa_platform_t
+mraa_get_platform_type()
 {
     return platform_type;
 }
@@ -456,7 +293,84 @@ mraa_adc_supported_bits()
     return plat->adc_supported;
 }
 
-mraa_adv_func*
-mraa_get_advance() {
-    return advance;
+char*
+mraa_get_platform_name()
+{
+    if (plat == NULL) {
+        return NULL;
+    }
+    return (char*) plat->platform_name;
+}
+
+unsigned int
+mraa_get_pin_count()
+{
+    if (plat == NULL) {
+        return 0;
+    }
+    return plat->phy_pin_count;
+}
+
+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_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;
+}
+
+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;
+    }
 }