static int checkValues(struct JsonNode *jvalues) { double readonly = 0.0; char *platform = GPIO_PLATFORM; if(config_setting_get_string("gpio-platform", 0, &platform) != 0) { logprintf(LOG_ERR, "no gpio-platform configured"); return -1; } if(strcmp(platform, "none") == 0) { FREE(platform); logprintf(LOG_ERR, "no gpio-platform configured"); return -1; } if(wiringXSetup(platform, logprintf1) < 0) { FREE(platform); return -1; } FREE(platform); struct JsonNode *jid = NULL; if((jid = json_find_member(jvalues, "id"))) { struct JsonNode *jchild = NULL; struct JsonNode *jchild1 = NULL; jchild = json_first_child(jid); while(jchild) { jchild1 = json_first_child(jchild); while(jchild1) { if(strcmp(jchild1->key, "gpio") == 0) { if(wiringXValidGPIO((int)round(jchild1->number_)) != 0) { return -1; } } jchild1 = jchild1->next; } jchild = jchild->next; } } if(json_find_number(jvalues, "readonly", &readonly) == 0) { if((int)readonly != 1) { return -1; } } return 0; }
static int createCode(JsonNode *code) { int free_def = 0; int gpio = -1; int state = -1; double itmp = -1; char *def = NULL; int have_error = 0; relay->rawlen = 0; if(json_find_string(code, "default-state", &def) != 0) { if((def = MALLOC(4)) == NULL) { fprintf(stderr, "out of memory\n"); exit(EXIT_FAILURE); } strcpy(def, "off"); free_def = 1; } if(json_find_number(code, "gpio", &itmp) == 0) gpio = (int)round(itmp); if(json_find_number(code, "off", &itmp) == 0) state=0; else if(json_find_number(code, "on", &itmp) == 0) state=1; if(gpio == -1 || state == -1) { logprintf(LOG_ERR, "relay: insufficient number of arguments"); have_error = 1; goto clear; } else if(wiringXSupported() == 0) { if(wiringXSetup() < 0) { logprintf(LOG_ERR, "unable to setup wiringX") ; return EXIT_FAILURE; } else { if(wiringXValidGPIO(gpio) != 0) { logprintf(LOG_ERR, "relay: invalid gpio range"); have_error = 1; goto clear; } else { if(strstr(progname, "daemon") != NULL) { pinMode(gpio, OUTPUT); if(strcmp(def, "off") == 0) { if(state == 1) { digitalWrite(gpio, LOW); } else if(state == 0) { digitalWrite(gpio, HIGH); } } else { if(state == 0) { digitalWrite(gpio, LOW); } else if(state == 1) { digitalWrite(gpio, HIGH); } } } else { wiringXGC(); } createMessage(gpio, state); goto clear; } } } clear: if(free_def == 1) { FREE(def); } if(have_error) { return EXIT_FAILURE; } else { return EXIT_SUCCESS; } }
int main(int argc, char *argv[]) { pthread_t pth; char *str = NULL, *platform = NULL; char usagestr[190]; int gpio_out = 0, gpio_in = 0; int i = 0, err = 0, invalid = 0; memset(usagestr, '\0', 190); // expect 2 arguments => argc must be 3 if(argc != 4) { snprintf(usagestr, 189, usage, argv[0], argv[0]); puts(usagestr); return -1; } // check for valid, numeric arguments for(i=2; i<argc; i++) { str = argv[i]; while(*str != '\0') { if(!isdigit(*str)) { invalid = 1; } str++; } if(invalid == 1) { printf("%s: Invalid GPIO %s\n", argv[0], argv[i]); return -1; } } platform = argv[1]; gpio_out = atoi(argv[2]); gpio_in = atoi(argv[3]); if(gpio_out == gpio_in) { printf("%s: GPIO for output and input (interrupt) should not be the same\n", argv[0]); return -1; } if(wiringXSetup(platform, NULL) == -1) { wiringXGC(); return -1; } if(wiringXValidGPIO(gpio_out) != 0) { printf("%s: Invalid GPIO %d for output\n", argv[0], gpio_out); wiringXGC(); return -1; } if(wiringXValidGPIO(gpio_in) != 0) { printf("%s: Invalid GPIO %d for input (interrupt)\n", argv[0], gpio_in); wiringXGC(); return -1; } pinMode(gpio_out, PINMODE_OUTPUT); if((wiringXISR(gpio_in, ISR_MODE_BOTH)) != 0) { printf("%s: Cannot set GPIO %d to interrupt BOTH\n", argv[0], gpio_in); wiringXGC(); return -1; } err = pthread_create(&pth, NULL, interrupt, &gpio_in); if(err != 0) { printf("Can't create thread: [%s]\n", strerror(err)); wiringXGC(); return -1; } else { printf("Thread created succesfully\n"); } for(i=0; i<5; i++) { printf(" Writing to GPIO %d: High\n", gpio_out); digitalWrite(gpio_out, HIGH); sleep(1); printf(" Writing to GPIO %d: Low\n", gpio_out); digitalWrite(gpio_out, LOW); sleep(2); } printf("Main finished, waiting for thread ...\n"); pthread_join(pth, NULL); wiringXGC(); return 0; }
static int checkValues(JsonNode *code) { char *def = NULL; struct JsonNode *jid = NULL; struct JsonNode *jchild = NULL; int free_def = 0; double itmp = -1; if(json_find_string(code, "default-state", &def) != 0) { if((def = MALLOC(4)) == NULL) { fprintf(stderr, "out of memory\n"); exit(EXIT_FAILURE); } strcpy(def, "off"); free_def = 1; } if(strcmp(def, "on") != 0 && strcmp(def, "off") != 0) { if(free_def == 1) { FREE(def); } return 1; } /* Get current relay state and validate GPIO number */ if((jid = json_find_member(code, "id")) != NULL) { if((jchild = json_find_element(jid, 0)) != NULL) { if(json_find_number(jchild, "gpio", &itmp) == 0) { if(wiringXSupported() == 0) { int gpio = (int)itmp; int state = -1; if(wiringXSetup() < 0) { logprintf(LOG_ERR, "unable to setup wiringX") ; return -1; } else if(wiringXValidGPIO(gpio) != 0) { logprintf(LOG_ERR, "relay: invalid gpio range"); return -1; } else { pinMode(gpio, INPUT); state = digitalRead(gpio); if(strcmp(def, "on") == 0) { state ^= 1; } relay->message = json_mkobject(); JsonNode *code = json_mkobject(); json_append_member(code, "gpio", json_mknumber(gpio, 0)); if(state == 1) { json_append_member(code, "state", json_mkstring("on")); } else { json_append_member(code, "state", json_mkstring("off")); } json_append_member(relay->message, "message", code); json_append_member(relay->message, "origin", json_mkstring("sender")); json_append_member(relay->message, "protocol", json_mkstring(relay->id)); if(pilight.broadcast != NULL) { pilight.broadcast(relay->id, relay->message, PROTOCOL); } json_delete(relay->message); relay->message = NULL; } } } } } if(free_def == 1) { FREE(def); } return 0; }