*/
maa_result_t maa_gpio_unexport(maa_gpio_context dev);
+/** Unexport the GPIO context (maa_gpio_close() will call this function)
+ * Forces regardless to to ownership.
+ *
+ * @param dev The GPIO context.
+ *
+ * @return maa result type.
+ */
+maa_result_t maa_gpio_unexport_force(maa_gpio_context dev);
+
/** Read the GPIO value.
*
* @param dev The GPIO context.
*/
maa_result_t maa_gpio_write(maa_gpio_context dev, int value);
+/** Change ownership of the context.
+ *
+ * @param dev gpio context
+ * @param owner does this context own the pin.
+ */
+maa_result_t maa_gpio_owner(maa_gpio_context dev, maa_boolean_t owner);
+
#ifdef __cplusplus
}
#endif
#include <poll.h>
#include <pthread.h>
#include <signal.h>
+#include <sys/stat.h>
#define SYSFS_CLASS_GPIO "/sys/class/gpio"
#define MAX_SIZE 64
#define POLL_TIMEOUT
/**
- * A strucutre representing a gpio pin.
+ * A structure representing a gpio pin.
*/
struct _gpio {
void (* isr)(); /**< the interupt service request */
pthread_t thread_id; /**< the isr handler thread id */
int isr_value_fp; /**< the isr file pointer on the value */
+ maa_boolean_t owner; /**< If this context originally exported the pin */
/*@}*/
};
{
char bu[MAX_SIZE];
sprintf(bu, SYSFS_CLASS_GPIO "/gpio%d/value", dev->pin);
-
dev->value_fp = open(bu, O_RDWR);
if (dev->value_fp == -1) {
return MAA_ERROR_INVALID_RESOURCE;
dev->isr_value_fp = -1;
dev->pin = pin;
- int export = open(SYSFS_CLASS_GPIO "/export", O_WRONLY);
- if (export == -1) {
- fprintf(stderr, "Failed to open export for writing!\n");
- return NULL;
- }
- length = snprintf(bu, sizeof(bu), "%d", dev->pin);
- if (write(export, bu, length*sizeof(char)) == -1) {
- fprintf(stderr, "Failed to write to export\n");
+ char directory[MAX_SIZE];
+ snprintf(directory, MAX_SIZE, SYSFS_CLASS_GPIO "/gpio%d/", dev->pin);
+ struct stat dir;
+ if (stat(directory, &dir) == 0 && S_ISDIR(dir.st_mode)) {
+ fprintf(stderr, "GPIO Pin already exporting, continuing.\n");
+ dev->owner = 0; // Not Owner
+ } else {
+ int export = open(SYSFS_CLASS_GPIO "/export", O_WRONLY);
+ if (export == -1) {
+ fprintf(stderr, "Failed to open export for writing!\n");
+ return NULL;
+ }
+ length = snprintf(bu, sizeof(bu), "%d", dev->pin);
+ if (write(export, bu, length*sizeof(char)) == -1) {
+ fprintf(stderr, "Failed to write to export\n");
+ close(export);
+ return NULL;
+ }
+ dev->owner = 1;
+ close(export);
}
-
- close(export);
return dev;
}
#endif
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
} else {
- // we must have got an error code so die nicely
+ // we must have got an error code so die nicely
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
close(dev->isr_value_fp);
dev->isr_value_fp = -1;
- return NULL;
+ return NULL;
}
}
}
maa_result_t
maa_gpio_unexport(maa_gpio_context dev)
{
+ if(dev->owner) {
+ return maa_gpio_unexport_force(dev);
+ }
+ return MAA_ERROR_INVALID_RESOURCE;
+}
+
+maa_result_t
+maa_gpio_unexport_force(maa_gpio_context dev)
+{
int unexport = open(SYSFS_CLASS_GPIO "/unexport", O_WRONLY);
if (unexport == -1) {
fprintf(stderr, "Failed to open unexport for writing!\n");
free(dev);
return MAA_SUCCESS;
}
+
+maa_result_t
+maa_gpio_owner(maa_gpio_context dev, maa_boolean_t own)
+{
+ if (dev == NULL)
+ return MAA_ERROR_INVALID_RESOURCE;
+ dev->owner = own;
+ return MAA_SUCCESS;
+}
+