int sartanoCreateCode(JsonNode *code) { int id = -1; int unit = -1; int state = -1; char *tmp; if(json_find_string(code, "id", &tmp) == 0) id=atoi(tmp); if(json_find_string(code, "off", &tmp) == 0) state=0; else if(json_find_string(code, "on", &tmp) == 0) state=1; if(json_find_string(code, "unit", &tmp) == 0) unit = atoi(tmp); if(id == -1 || unit == -1 || state == -1) { logprintf(LOG_ERR, "sartano: insufficient number of arguments"); return EXIT_FAILURE; } else if(id > 31 || id < 0) { logprintf(LOG_ERR, "sartano: invalid id range"); return EXIT_FAILURE; } else if(unit > 31 || unit < 0) { logprintf(LOG_ERR, "sartano: invalid unit range"); return EXIT_FAILURE; } else { sartanoCreateMessage(id, unit, state); sartanoClearCode(); sartanoCreateUnit(unit); sartanoCreateId(id); sartanoCreateState(state); sartanoCreateFooter(); } return EXIT_SUCCESS; }
int xbmcCheckValues(JsonNode *code) { char *action = NULL; char *media = NULL; if(json_find_string(code, "action", &action) == 0 && json_find_string(code, "media", &media) == 0) { if(strcmp(media, "none") == 0) { if(!(strcmp(action, "shutdown") == 0 || strcmp(action, "home") == 0)) { return 1; } else { return 0; } } else if(strcmp(media, "episode") == 0 || strcmp(media, "movie") == 0 || strcmp(media, "song") == 0) { if(!(strcmp(action, "play") == 0 || strcmp(action, "pause") == 0)) { return 1; } else { return 0; } } else if(strcmp(media, "screensaver") == 0) { if(!(strcmp(action, "active") == 0 || strcmp(action, "inactive") == 0)) { return 1; } else { return 0; } } else { return 1; } } else { return 1; } return 0; }
static int x10CreateCode(JsonNode *code) { char id[4] = {'\0'}; int state = -1; double itmp = -1; char *stmp = NULL; strcpy(id, "-1"); if(json_find_string(code, "id", &stmp) == 0) strcpy(id, stmp); if(json_find_number(code, "off", &itmp) == 0) state=1; else if(json_find_number(code, "on", &itmp) == 0) state=0; if(strcmp(id, "-1") == 0 || state == -1) { logprintf(LOG_ERR, "x10: insufficient number of arguments"); return EXIT_FAILURE; } else if((int)(id[0]) < 65 || (int)(id[0]) > 80) { logprintf(LOG_ERR, "x10: invalid id range"); return EXIT_FAILURE; } else if(atoi(&id[1]) < 0 || atoi(&id[1]) > 16) { logprintf(LOG_ERR, "x10: invalid id range"); return EXIT_FAILURE; } else { x10CreateMessage(id, state); x10ClearCode(); x10CreateLetter((int)id[0]); x10CreateNumber(atoi(&id[1])); x10CreateState(state); x10CreateFooter(); } return EXIT_SUCCESS; }
int arctechSwCreateCode(JsonNode *code) { int id = -1; int unit = -1; int state = -1; int all = 0; char *tmp; if(json_find_string(code, "id", &tmp) == 0) id=atoi(tmp); if(json_find_string(code, "off", &tmp) == 0) state=0; else if(json_find_string(code, "on", &tmp) == 0) state=1; if(json_find_string(code, "unit", &tmp) == 0) unit = atoi(tmp); if(json_find_string(code, "all", &tmp) == 0) all = 1; if(id == -1 || (unit == -1 && all == 0) || state == -1) { logprintf(LOG_ERR, "arctech_switch: insufficient number of arguments"); return EXIT_FAILURE; } else if(id > 67108863 || id < 1) { logprintf(LOG_ERR, "arctech_switch: invalid id range"); return EXIT_FAILURE; } else if((unit > 15 || unit < 0) && all == 0) { logprintf(LOG_ERR, "arctech_switch: invalid unit range"); return EXIT_FAILURE; } else { if(unit == -1 && all == 1) { unit = 0; } arctechSwCreateMessage(id, unit, state, all); arctechSwCreateStart(); arctechSwClearCode(); arctechSwCreateId(id); arctechSwCreateAll(all); arctechSwCreateState(state); arctechSwCreateUnit(unit); arctechSwCreateFooter(); } return EXIT_SUCCESS; }
int genWeatherCreateCode(JsonNode *code) { int id = -999; int temp = -999; int humi = -999; char *tmp; if(json_find_string(code, "id", &tmp) == 0) id=atoi(tmp); if(json_find_string(code, "temperature", &tmp) == 0) temp = atoi(tmp); if(json_find_string(code, "humidity", &tmp) == 0) humi = atoi(tmp); if(id == -999 || (temp == -999 && humi == -999)) { logprintf(LOG_ERR, "generic_weather: insufficient number of arguments"); return EXIT_FAILURE; } else { genWeatherCreateMessage(id, temp, humi); } return EXIT_SUCCESS; }
int arctechDimCreateCode(JsonNode *code) { int id = -1; int unit = -1; int state = -1; int all = 0; int dimlevel = -1; char *tmp; if(json_find_string(code, "id", &tmp) == 0) id=atoi(tmp); if(json_find_string(code, "off", &tmp) == 0) state=0; else if(json_find_string(code, "on", &tmp) == 0) state=1; if(json_find_string(code, "unit", &tmp) == 0) unit = atoi(tmp); if(json_find_string(code, "dimlevel", &tmp) == 0) dimlevel = atoi(tmp); if(json_find_string(code, "all", &tmp) == 0) all = 1; if(id == -1 || (unit == -1 && all == 0) || (dimlevel == -1 && state == -1)) { logprintf(LOG_ERR, "arctech_dimmer: insufficient number of arguments"); return EXIT_FAILURE; } else if(id > 67108863 || id < 1) { logprintf(LOG_ERR, "arctech_dimmer: invalid id range"); return EXIT_FAILURE; } else if((unit > 15 || unit < 0) && all == 0) { logprintf(LOG_ERR, "arctech_dimmer: invalid unit range"); return EXIT_FAILURE; } else if(state == -1 && (dimlevel > 16 || dimlevel < 0)) { logprintf(LOG_ERR, "arctech_dimmer: invalid dimlevel range"); return EXIT_FAILURE; } else if(dimlevel >= 0 && state == 0) { logprintf(LOG_ERR, "arctech_dimmer: dimlevel and state cannot be combined"); return EXIT_FAILURE; } else { if(unit == -1 && all == 1) { unit = 0; } if(dimlevel >= 0) { state = -1; } arctechDimCreateMessage(id, unit, state, all, dimlevel); arctechDimCreateStart(); arctechDimClearCode(); arctechDimCreateId(id); arctechDimCreateAll(all); arctechDimCreateState(state); arctechDimCreateUnit(unit); if(dimlevel > -1) { arctechDimCreateDimlevel(dimlevel); } arctechDimCreateFooter(); } return EXIT_SUCCESS; }
int impulsCreateCode(JsonNode *code) { int systemcode = -1; int programcode = -1; int state = -1; char *tmp; if(json_find_string(code, "systemcode", &tmp) == 0) { systemcode=atoi(tmp); } if(json_find_string(code, "programcode", &tmp) == 0) { programcode=atoi(tmp); } if(json_find_string(code, "off", &tmp) == 0) { state=0; } else if(json_find_string(code, "on", &tmp) == 0) { state=1; } if(systemcode == -1 || programcode == -1 || state == -1) { logprintf(LOG_ERR, "impuls: insufficient number of arguments"); return EXIT_FAILURE; } else if(systemcode > 31 || systemcode < 0) { logprintf(LOG_ERR, "impuls: invalid systemcode range"); return EXIT_FAILURE; } else if(programcode > 31 || programcode < 0) { logprintf(LOG_ERR, "impuls: invalid programcode range"); return EXIT_FAILURE; } else { impulsCreateMessage(systemcode, programcode, state); impulsClearCode(); impulsCreateSystemCode(systemcode); impulsCreateProgramCode(programcode); impulsCreateState(state); impulsCreateFooter(); } return EXIT_SUCCESS; }
static int rawCreateCode(JsonNode *code) { char *rcode = NULL; char **array = NULL; unsigned int i = 0, n = 0; if(json_find_string(code, "code", &rcode) != 0) { logprintf(LOG_ERR, "raw: insufficient number of arguments"); return EXIT_FAILURE; } n = explode(rcode, " ", &array); for(i=0;i<n;i++) { raw->raw[i]=atoi(array[i]); FREE(array[i]); } if(n > 0) { FREE(array); } raw->rawlen=(int)i; return EXIT_SUCCESS; }
int clarusSwCreateCode(JsonNode *code) { char id[3] = {'\0'}; int unit = -1; int state = -1; double itmp; char *stmp; strcpy(id, "-1"); if(json_find_string(code, "id", &stmp) == 0) strcpy(id, stmp); if(json_find_number(code, "off", &itmp) == 0) state=0; else if(json_find_number(code, "on", &itmp) == 0) state=1; if(json_find_number(code, "unit", &itmp) == 0) unit = (int)round(itmp); if(strcmp(id, "-1") == 0 || unit == -1 || state == -1) { logprintf(LOG_ERR, "clarus_switch: insufficient number of arguments"); return EXIT_FAILURE; } else if((int)(id[0]) < 65 || (int)(id[0]) > 70) { logprintf(LOG_ERR, "clarus_switch: invalid id range"); return EXIT_FAILURE; } else if(atoi(&id[1]) < 0 || atoi(&id[1]) > 31) { logprintf(LOG_ERR, "clarus_switch: invalid id range"); return EXIT_FAILURE; } else if(unit > 63 || unit < 0) { logprintf(LOG_ERR, "clarus_switch: invalid unit range"); return EXIT_FAILURE; } else { clarusSwCreateMessage(id, unit, ((state == 2 || state == 1) ? 2 : 0)); clarusSwClearCode(); clarusSwCreateUnit(unit); clarusSwCreateId(id); clarusSwCreateState(state); clarusSwCreateFooter();; } return EXIT_SUCCESS; }
int rawCreateCode(JsonNode *code) { char *rcode = NULL; char *ncode = NULL; char *pch = NULL; int i=0; if(json_find_string(code, "code", &rcode) != 0) { logprintf(LOG_ERR, "raw: insufficient number of arguments"); return EXIT_FAILURE; } ncode = malloc(strlen(rcode)+1); strcpy(ncode, rcode); pch = strtok(ncode, " "); while(pch != NULL) { raw->raw[i]=atoi(pch); pch = strtok(NULL, " "); i++; } sfree((void *)&ncode); raw->rawlen=i; return EXIT_SUCCESS; }
int main(int argc, char **argv) { log_shell_enable(); log_file_disable(); log_level_set(LOG_NOTICE); progname = malloc(16); strcpy(progname, "pilight-receive"); struct options_t *options = NULL; JsonNode *json = NULL; char *server = malloc(17); strcpy(server, "127.0.0.1"); unsigned short port = PORT; int sockfd = 0; char *recvBuff = NULL; char *message = NULL; char *args = NULL; steps_t steps = WELCOME; options_add(&options, 'H', "help", no_value, 0, NULL); options_add(&options, 'V', "version", no_value, 0, NULL); options_add(&options, 'S', "server", has_value, 0, "^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]).){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$"); options_add(&options, 'P', "port", has_value, 0, "[0-9]{1,4}"); /* Store all CLI arguments for later usage and also check if the CLI arguments where used correctly by the user. This will also fill all necessary values in the options struct */ while(1) { int c; c = options_parse(&options, argc, argv, 1, &args); if(c == -1 || c == -2) break; switch(c) { case 'H': printf("\t -H --help\t\t\tdisplay this message\n"); printf("\t -V --version\t\t\tdisplay version\n"); printf("\t -S --server=%s\t\tconnect to server address\n", server); printf("\t -P --port=%d\t\t\tconnect to server port\n", port); exit(EXIT_SUCCESS); break; case 'V': printf("%s %s\n", progname, VERSION); exit(EXIT_SUCCESS); break; case 'S': server = realloc(server, strlen(args)+1); strcpy(server, args); break; case 'P': port = (unsigned short)atoi(args); break; default: printf("Usage: %s -l location -d device\n", progname); exit(EXIT_SUCCESS); break; } } options_delete(options); if((sockfd = socket_connect(server, port)) == -1) { logprintf(LOG_ERR, "could not connect to pilight-daemon"); return EXIT_FAILURE; } sfree((void *)&server); while(1) { if(steps > WELCOME) { /* Clear the receive buffer again and read the welcome message */ recvBuff = socket_read(sockfd); if(recvBuff == NULL) { goto close; } } switch(steps) { case WELCOME: socket_write(sockfd, "{\"message\":\"client receiver\"}"); steps=IDENTIFY; break; case IDENTIFY: //extract the message json = json_decode(recvBuff); json_find_string(json, "message", &message); assert(message != NULL); if(strcmp(message, "accept client") == 0) { steps=RECEIVE; } else if(strcmp(message, "reject client") == 0) { steps=REJECT; } else { assert(false); } //cleanup json_delete(json); json = NULL; message = NULL; break; case RECEIVE: { char *line = strtok(recvBuff, "\n"); //for each line while(line) { json = json_decode(recvBuff); assert(json != NULL); char *output = json_stringify(json, "\t"); printf("%s\n", output); sfree((void *)&output); json_delete(json); line = strtok(NULL,"\n"); } } break; case REJECT: default: goto close; break; } } close: socket_close(sockfd); protocol_gc(); options_gc(); sfree((void *)&progname); sfree((void *)&server); sfree((void *)&message); return EXIT_SUCCESS; }
int main(int argc, char **argv) { disable_file_log(); enable_shell_log(); set_loglevel(LOG_NOTICE); progname = malloc((10*sizeof(char))+1); progname = strdup("433-send"); options = malloc(255*sizeof(struct options_t)); int sockfd = 0; char *recvBuff = NULL; char *message; steps_t steps = WELCOME; /* Hold the name of the protocol */ char protobuffer[25] = "\0"; int i; /* Does this protocol exists */ int match = 0; /* Do we need to print the help */ int help = 0; /* Do we need to print the version */ int version = 0; /* Do we need to print the protocol help */ int protohelp = 0; char server[16] = "127.0.0.1"; unsigned short port = PORT; /* Hold the final protocol struct */ protocol_t *protocol = NULL; JsonNode *json = json_mkobject(); JsonNode *code = json_mkobject(); /* Define all CLI arguments of this program */ addOption(&options, 'H', "help", no_value, 0, NULL); addOption(&options, 'V', "version", no_value, 0, NULL); addOption(&options, 'p', "protocol", has_value, 0, NULL); addOption(&options, 'S', "server", has_value, 0, "^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]).){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$"); addOption(&options, 'P', "port", has_value, 0, "[0-9]{1,4}"); /* Initialize peripheral modules */ hw_init(); /* Get the protocol to be used */ while (1) { int c; c = getOptions(&options, argc, argv, 0); if (c == -1) break; switch(c) { case 'p': if(strlen(optarg) == 0) { logprintf(LOG_ERR, "options '-p' and '--protocol' require an argument"); exit(EXIT_FAILURE); } else { strcpy(protobuffer, optarg); } break; case 'V': version = 1; break; case 'H': help = 1; break; case 'S': strcpy(server, optarg); break; case 'P': port = (unsigned short)atoi(optarg); break; default:; } } /* Check if a protocol was given */ if(strlen(protobuffer) > 0 && strcmp(protobuffer,"-v") != 0) { if(strlen(protobuffer) > 0 && version) { printf("-p and -V cannot be combined\n"); } else { for(i=0; i<protocols.nr; ++i) { protocol = protocols.listeners[i]; /* Check if the protocol exists */ if(protocol_has_device(&protocol, protobuffer) == 0 && match == 0 && protocol->createCode != NULL) { match=1; /* Check if the protocol requires specific CLI arguments and merge them with the main CLI arguments */ if(protocol->options != NULL && help == 0) { mergeOptions(&options, &protocol->options); } else if(help == 1) { protohelp=1; } break; } } /* If no protocols matches the requested protocol */ if(!match) { logprintf(LOG_ERR, "this protocol is not supported"); } } } /* Display help or version information */ if(version == 1) { printf("%s %s\n", progname, "1.0"); return (EXIT_SUCCESS); } else if(help == 1 || protohelp == 1 || match == 0) { if(protohelp == 1 && match == 1 && protocol->printHelp != NULL) printf("Usage: %s -p %s [options]\n", progname, protobuffer); else printf("Usage: %s -p protocol [options]\n", progname); if(help == 1) { printf("\t -H --help\t\t\tdisplay this message\n"); printf("\t -V --version\t\t\tdisplay version\n"); printf("\t -S --server=%s\t\tconnect to server address\n", server); printf("\t -P --port=%d\t\t\tconnect to server port\n", port); printf("\t -p --protocol=protocol\t\tthe protocol that you want to control\n"); } if(protohelp == 1 && match == 1 && protocol->printHelp != NULL) { printf("\n\t[%s]\n", protobuffer); protocol->printHelp(); } else { printf("\nThe supported protocols are:\n"); for(i=0; i<protocols.nr; ++i) { protocol = protocols.listeners[i]; if(protocol->createCode != NULL) { while(protocol->devices != NULL) { printf("\t %s\t\t\t",protocol->devices->id); if(strlen(protocol->devices->id)<6) printf("\t"); printf("%s\n", protocol->devices->desc); protocol->devices = protocol->devices->next; } } } } return (EXIT_SUCCESS); } /* Store all CLI arguments for later usage and also check if the CLI arguments where used correctly by the user. This will also fill all necessary values in the options struct */ while(1) { int c; c = getOptions(&options, argc, argv, 1); if(c == -1) break; } int itmp; /* Check if we got sufficient arguments from this protocol */ while(options != NULL && strlen(options->name) > 0) { /* Only send the CLI arguments that belong to this protocol, the protocol name and those that are called by the user */ if((getOptionIdByName(&protocol->options, options->name, &itmp) == 0 || strcmp(options->name, "protocol") == 0) && strlen(options->value) > 0) { json_append_member(code, options->name, json_mkstring(options->value)); } options = options->next; } if(protocol->createCode(code) == 0) { if((sockfd = connect_to_server(strdup(server), port)) == -1) { logprintf(LOG_ERR, "could not connect to 433-daemon"); goto close; } while(1) { /* Clear the receive buffer again and read the welcome message */ if((recvBuff = socket_read(sockfd)) != NULL) { json = json_decode(recvBuff); json_find_string(json, "message", &message); } else { goto close; } usleep(100); switch(steps) { case WELCOME: if(strcmp(message, "accept connection") == 0) { socket_write(sockfd, "{\"message\":\"client sender\"}"); steps=IDENTIFY; } case IDENTIFY: if(strcmp(message, "accept client") == 0) { steps=SEND; } if(strcmp(message, "reject client") == 0) { steps=REJECT; } case SEND: json_delete(json); json = json_mkobject(); json_append_member(json, "message", json_mkstring("send")); json_append_member(json, "code", code); socket_write(sockfd, json_stringify(json, NULL)); goto close; break; case REJECT: default: goto close; break; } } } close: json_delete(json); socket_close(sockfd); return EXIT_SUCCESS; }
static int rules_parse(JsonNode *root) { int have_error = 0, match = 0, x = 0; unsigned int i = 0; struct JsonNode *jrules = NULL; char *rule = NULL; double active = 1.0; if(root->tag == JSON_OBJECT) { jrules = json_first_child(root); while(jrules) { i++; if(jrules->tag == JSON_OBJECT) { if(json_find_string(jrules, "rule", &rule) != 0) { logprintf(LOG_ERR, "config rule #%d \"%s\", missing \"rule\"", i, jrules->key); have_error = 1; break; } else { active = 1.0; json_find_number(jrules, "active", &active); struct rules_t *tmp = rules; match = 0; while(tmp) { if(strcmp(tmp->name, jrules->key) == 0) { match = 1; break; } tmp = tmp->next; } if(match == 1) { logprintf(LOG_ERR, "config rule #%d \"%s\" already exists", i, jrules->key); have_error = 1; break; } for(x=0;x<strlen(jrules->key);x++) { if(!isalnum(jrules->key[x]) && jrules->key[x] != '-' && jrules->key[x] != '_') { logprintf(LOG_ERR, "config rule #%d \"%s\", not alphanumeric", i, jrules->key); have_error = 1; break; } } struct rules_t *node = MALLOC(sizeof(struct rules_t)); if(node == NULL) { fprintf(stderr, "out of memory\n"); exit(EXIT_FAILURE); } node->next = NULL; node->values = NULL; node->nrdevices = 0; node->status = 0; node->devices = NULL; node->actions = NULL; node->nr = i; if((node->name = MALLOC(strlen(jrules->key)+1)) == NULL) { fprintf(stderr, "out of memory\n"); exit(EXIT_FAILURE); } strcpy(node->name, jrules->key); clock_gettime(CLOCK_MONOTONIC, &node->timestamp.first); if(event_parse_rule(rule, node, 0, 1) == -1) { have_error = 1; } clock_gettime(CLOCK_MONOTONIC, &node->timestamp.second); logprintf(LOG_INFO, "rule #%d %s was parsed in %.6f seconds", node->nr, node->name, ((double)node->timestamp.second.tv_sec + 1.0e-9*node->timestamp.second.tv_nsec) - ((double)node->timestamp.first.tv_sec + 1.0e-9*node->timestamp.first.tv_nsec)); node->status = 0; if((node->rule = MALLOC(strlen(rule)+1)) == NULL) { fprintf(stderr, "out of memory\n"); exit(EXIT_FAILURE); } strcpy(node->rule, rule); node->active = (unsigned short)active; tmp = rules; if(tmp) { while(tmp->next != NULL) { tmp = tmp->next; } tmp->next = node; } else { node->next = rules; rules = node; } /* * In case of an error, we do want to * save a pointer to our faulty rule * so it can be properly garbage collected. */ if(have_error == 1) { break; } } } jrules = jrules->next; } } else { logprintf(LOG_ERR, "config rules should be placed in an object"); have_error = 1; } return have_error; }
int main(int argc, char **argv) { unsigned short port = 0; char* server = NULL; unsigned short stats = 0; struct ssdp_list_t *ssdp_list = NULL; atomicinit(); gc_attach(main_gc); gc_catch(); if(server != NULL && port > 0) { if((sockfd = socket_connect(server, port)) == -1){ printf("error: could not connect to pilight-daemon\n"); return EXIT_FAILURE; } } else if(ssdp_seek(&ssdp_list) == -1){ printf("error: no pilight ssdp connections found\n"); goto close; } else{ if((sockfd = socket_connect(ssdp_list->ip, ssdp_list->port)) == -1){ printf("error: could not connect to pilight-daemon\n"); goto close; } } if(ssdp_list != NULL) ssdp_free(ssdp_list); if(server != NULL) FREE(server); struct JsonNode *jclient = json_mkobject(); struct JsonNode *joptions = json_mkobject(); json_append_member(jclient, "action", json_mkstring("identify")); json_append_member(joptions, "receiver", json_mknumber(1, 0)); json_append_member(joptions, "stats", json_mknumber(stats, 0)); json_append_member(jclient, "options", joptions); char *out = json_stringify(jclient, NULL); socket_write(sockfd, out); json_free(out); json_delete(jclient); if(socket_read(sockfd, &recvBuff, 0)!=0 || strcmp(recvBuff, "{\"status\":\"success\"}")!=0) goto close; if(iniInit("config.ini")) // get values from config.ini goto close; display(0, 0, 0); // init display unsigned short filteropt = 1; int lastmin = -1, firstrx = 0; while(main_loop){ if(socket_read(sockfd, &recvBuff, 0) != 0) goto close; char **array = NULL; unsigned int n = explode(recvBuff, "\n", &array), i = 0; for(i=0; i<n; i++){ struct JsonNode *jcontent = json_decode(array[i]); struct JsonNode *jtype = json_find_member(jcontent, "type"); if(jtype != NULL){ json_remove_from_parent(jtype); json_delete(jtype); } if(filteropt == 1){ char *pr = NULL; double id = 0.0; double ch = 0.0; struct JsonNode *jmessage = json_find_member(jcontent, "message"); json_find_string(jcontent, "protocol", &pr); json_find_number(jmessage, "id", &id); json_find_number(jmessage, "channel", &ch); int j = 0; for(j=0; j<stations; j++){ // step through protocol filters if(strcmp(station[j].pr, "-")==0 || strcmp(station[j].pr, pr)==0){ // protocol not specified or found if(j == 0){ // datetime protocol is the first if(firstrx){ double min = 0.0; json_find_number(jmessage, "minute", &min); if((int)min != lastmin){ display(-1, 0.0, 0.0); lastmin = (int)min; } } } else if(strcmp(station[j].id, "-")==0 || (int)id==atoi(station[j].id)){ // id not specified or found if(strcmp(station[j].ch, "-")==0 || (int)ch==atoi(station[j].ch)){ // channel not specified or found double temp = 0.0, humi = 0.0; json_find_number(jmessage, "temperature", &temp); json_find_number(jmessage, "humidity", &humi); display(j-1, temp, humi); firstrx = 1; break; } } } } } else{ char *content = json_stringify(jcontent, "\t"); printf("%s\n", content); json_free(content); } json_delete(jcontent); } array_free(&array, n); } close: if(sockfd > 0) socket_close(sockfd); if(recvBuff != NULL){ FREE(recvBuff); recvBuff = NULL; } iniClean(); return EXIT_SUCCESS; }
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; } }
static int rules_parse(JsonNode *root) { int have_error = 0, match = 0; unsigned int i = 0; struct JsonNode *jrules = NULL; char *rule = NULL; double active = 1.0; if(root->tag == JSON_OBJECT) { jrules = json_first_child(root); while(jrules) { i++; if(jrules->tag == JSON_OBJECT) { if(json_find_string(jrules, "rule", &rule) != 0) { logprintf(LOG_ERR, "config rules #%d \"%s\", missing \"rule\"", i, jrules->key); have_error = 1; break; } else { active = 1.0; json_find_number(jrules, "active", &active); struct rules_t *tmp = rules; match = 0; while(tmp) { if(strcmp(tmp->name, jrules->key) == 0) { match = 1; break; } tmp = tmp->next; } if(match == 1) { logprintf(LOG_ERR, "config rules #%d \"%s\" already exists", i, jrules->key); have_error = 1; break; } struct rules_t *node = MALLOC(sizeof(struct rules_t)); if(node == NULL) { logprintf(LOG_ERR, "out of memory"); exit(EXIT_FAILURE); } node->next = NULL; node->values = NULL; node->nrdevices = 0; node->status = 0; node->devices = NULL; node->action = NULL; node->arguments = NULL; if(event_parse_rule(rule, node, 0, i, 1) == -1) { for(i=0;i<node->nrdevices;i++) { FREE(node->devices[i]); } if(node->devices != NULL) { FREE(node->devices); } FREE(node); have_error = 1; break; } node->status = 0; node->rule = MALLOC(strlen(rule)+1); if(node->rule == NULL) { logprintf(LOG_ERR, "out of memory"); exit(EXIT_FAILURE); } strcpy(node->rule, rule); node->name = MALLOC(strlen(jrules->key)+1); if(node->name == NULL) { logprintf(LOG_ERR, "out of memory"); exit(EXIT_FAILURE); } strcpy(node->name, jrules->key); node->active = (unsigned short)active; tmp = rules; if(tmp) { while(tmp->next != NULL) { tmp = tmp->next; } tmp->next = node; } else { node->next = rules; rules = node; } } } jrules = jrules->next; } } else { logprintf(LOG_ERR, "config rules should be placed in an object"); have_error = 1; } return have_error; }
void *lm76Parse(void *param) { struct JsonNode *json = (struct JsonNode *)param; struct JsonNode *jsettings = NULL; struct JsonNode *jid = NULL; struct JsonNode *jchild = NULL; struct timeval tp; struct timespec ts; struct lm76data_t *lm76data = malloc(sizeof(struct lm76data_t)); int y = 0, interval = 10, rc = 0; int temp_corr = 0; char *stmp = NULL; int firstrun = 1; lm76data->nrid = 0; lm76data->id = NULL; lm76data->fd = 0; #ifndef __FreeBSD__ pthread_mutex_t mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP; pthread_cond_t cond = PTHREAD_COND_INITIALIZER; #else pthread_mutex_t mutex; pthread_cond_t cond; pthread_mutexattr_t attr; pthread_mutexattr_init(&attr); pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); pthread_mutex_init(&mutex, &attr); #endif if((jid = json_find_member(json, "id"))) { jchild = json_first_child(jid); while(jchild) { if(json_find_string(jchild, "id", &stmp) == 0) { lm76data->id = realloc(lm76data->id, (sizeof(char *)*(size_t)(lm76data->nrid+1))); lm76data->id[lm76data->nrid] = malloc(strlen(stmp)+1); strcpy(lm76data->id[lm76data->nrid], stmp); lm76data->nrid++; } jchild = jchild->next; } } if((jsettings = json_find_member(json, "settings"))) { json_find_number(jsettings, "interval", &interval); json_find_number(jsettings, "temp-corr", &temp_corr); } json_delete(json); #ifndef __FreeBSD__ lm76data->fd = realloc(lm76data->fd, (sizeof(int)*(size_t)(lm76data->nrid+1))); for(y=0;y<lm76data->nrid;y++) { lm76data->fd[y] = wiringPiI2CSetup((int)strtol(lm76data->id[y], NULL, 16)); } #endif pthread_cleanup_push(lm76ParseCleanUp, (void *)lm76data); while(lm76_loop) { rc = gettimeofday(&tp, NULL); ts.tv_sec = tp.tv_sec; ts.tv_nsec = tp.tv_usec * 1000; if(firstrun) { ts.tv_sec += 1; firstrun = 0; } else { ts.tv_sec += interval; } pthread_mutex_lock(&mutex); rc = pthread_cond_timedwait(&cond, &mutex, &ts); if(rc == ETIMEDOUT) { #ifndef __FreeBSD__ for(y=0;y<lm76data->nrid;y++) { if(lm76data->fd[y] > 0) { int raw = wiringPiI2CReadReg16(lm76data->fd[y], 0x00); float temp = ((float)((raw&0x00ff)+((raw>>12)*0.0625))*1000); lm76->message = json_mkobject(); JsonNode *code = json_mkobject(); json_append_member(code, "id", json_mkstring(lm76data->id[y])); json_append_member(code, "temperature", json_mknumber((int)temp+temp_corr)); json_append_member(lm76->message, "code", code); json_append_member(lm76->message, "origin", json_mkstring("receiver")); json_append_member(lm76->message, "protocol", json_mkstring(lm76->id)); pilight.broadcast(lm76->id, lm76->message); json_delete(lm76->message); lm76->message = NULL; } else { logprintf(LOG_DEBUG, "error connecting to lm76"); logprintf(LOG_DEBUG, "(probably i2c bus error from wiringPiI2CSetup)"); logprintf(LOG_DEBUG, "(maybe wrong id? use i2cdetect to find out)"); sleep(1); } } #endif }
void *ds18b20Parse(void *param) { struct protocol_threads_t *node = (struct protocol_threads_t *)param; struct JsonNode *json = (struct JsonNode *)node->param; struct JsonNode *jid = NULL; struct JsonNode *jchild = NULL; struct dirent *file = NULL; struct stat st; DIR *d = NULL; FILE *fp = NULL; char *ds18b20_sensor = NULL; char *stmp = NULL; char **id = NULL; char *content = NULL; int w1valid = 0, w1temp = 0, interval = 10, x = 0; int temp_offset = 0, nrid = 0, y = 0, nrloops = 0; double itmp = 0; size_t bytes = 0; ds18b20_threads++; if((jid = json_find_member(json, "id"))) { jchild = json_first_child(jid); while(jchild) { if(json_find_string(jchild, "id", &stmp) == 0) { id = realloc(id, (sizeof(char *)*(size_t)(nrid+1))); if(!id) { logprintf(LOG_ERR, "out of memory"); exit(EXIT_FAILURE); } id[nrid] = malloc(strlen(stmp)+1); if(!id[nrid]) { logprintf(LOG_ERR, "out of memory"); exit(EXIT_FAILURE); } strcpy(id[nrid], stmp); nrid++; } jchild = jchild->next; } } if(json_find_number(json, "poll-interval", &itmp) == 0) interval = (int)round(itmp); if(json_find_number(json, "device-temperature-offset", &itmp) == 0) temp_offset = (int)round(itmp); while(ds18b20_loop) { if(protocol_thread_wait(node, interval, &nrloops) == ETIMEDOUT) { for(y=0;y<nrid;y++) { ds18b20_sensor = realloc(ds18b20_sensor, strlen(ds18b20_path)+strlen(id[y])+5); if(!ds18b20_sensor) { logprintf(LOG_ERR, "out of memory"); exit(EXIT_FAILURE); } sprintf(ds18b20_sensor, "%s28-%s/", ds18b20_path, id[y]); if((d = opendir(ds18b20_sensor))) { while((file = readdir(d)) != NULL) { if(file->d_type == DT_REG) { if(strcmp(file->d_name, "w1_slave") == 0) { size_t w1slavelen = strlen(ds18b20_sensor)+10; char ds18b20_w1slave[w1slavelen]; memset(ds18b20_w1slave, '\0', w1slavelen); strncpy(ds18b20_w1slave, ds18b20_sensor, strlen(ds18b20_sensor)); strcat(ds18b20_w1slave, "w1_slave"); if(!(fp = fopen(ds18b20_w1slave, "rb"))) { logprintf(LOG_ERR, "cannot read w1 file: %s", ds18b20_w1slave); break; } fstat(fileno(fp), &st); bytes = (size_t)st.st_size; if(!(content = realloc(content, bytes+1))) { logprintf(LOG_ERR, "out of memory"); fclose(fp); break; } memset(content, '\0', bytes+1); if(fread(content, sizeof(char), bytes, fp) == -1) { logprintf(LOG_ERR, "cannot read config file: %s", ds18b20_w1slave); fclose(fp); break; } fclose(fp); w1valid = 0; char *pch = strtok(content, "\n=: "); x = 0; while(pch) { if(strlen(pch) > 2) { if(x == 1 && strstr(pch, "YES")) { w1valid = 1; } if(x == 2) { w1temp = atoi(pch)+temp_offset; } x++; } pch = strtok(NULL, "\n=: "); } if(w1valid) { ds18b20->message = json_mkobject(); JsonNode *code = json_mkobject(); json_append_member(code, "id", json_mkstring(id[y])); json_append_member(code, "temperature", json_mknumber(w1temp)); json_append_member(ds18b20->message, "message", code); json_append_member(ds18b20->message, "origin", json_mkstring("receiver")); json_append_member(ds18b20->message, "protocol", json_mkstring(ds18b20->id)); pilight.broadcast(ds18b20->id, ds18b20->message); json_delete(ds18b20->message); ds18b20->message = NULL; } } } } closedir(d); } else { logprintf(LOG_ERR, "1-wire device %s does not exists", ds18b20_sensor); } } } } if(ds18b20_sensor) { sfree((void *)&ds18b20_sensor); } if(content) { sfree((void *)&content); } for(y=0;y<nrid;y++) { sfree((void *)&id[y]); } sfree((void *)&id); ds18b20_threads--; return (void *)NULL; }
int main(int argc, char **argv) { log_file_disable(); log_shell_enable(); log_level_set(LOG_NOTICE); progname = malloc(16); strcpy(progname, "pilight-control"); struct options_t *options = NULL; struct ssdp_list_t *ssdp_list = NULL; int sockfd = 0; char *recvBuff = NULL; char *message = NULL; char *pch = NULL; steps_t steps = WELCOME; char device[50]; char location[50]; char state[10] = {'\0'}; char values[255] = {'\0'}; struct conf_locations_t *slocation = NULL; struct conf_devices_t *sdevice = NULL; int has_values = 0; char *server = NULL; unsigned short port = 0; JsonNode *json = NULL; JsonNode *jconfig = NULL; JsonNode *jcode = NULL; JsonNode *jvalues = NULL; /* Define all CLI arguments of this program */ options_add(&options, 'H', "help", no_value, 0, NULL); options_add(&options, 'V', "version", no_value, 0, NULL); options_add(&options, 'l', "location", has_value, 0, NULL); options_add(&options, 'd', "device", has_value, 0, NULL); options_add(&options, 's', "state", has_value, 0, NULL); options_add(&options, 'v', "values", has_value, 0, NULL); options_add(&options, 'S', "server", has_value, 0, "^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]).){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$"); options_add(&options, 'P', "port", has_value, 0, "[0-9]{1,4}"); /* Store all CLI arguments for later usage and also check if the CLI arguments where used correctly by the user. This will also fill all necessary values in the options struct */ while(1) { int c; c = options_parse(&options, argc, argv, 1, &optarg); if(c == -1) break; if(c == -2) c = 'H'; switch(c) { case 'H': printf("\t -H --help\t\t\tdisplay this message\n"); printf("\t -V --version\t\t\tdisplay version\n"); printf("\t -S --server=x.x.x.x\t\tconnect to server address\n"); printf("\t -P --port=xxxx\t\t\tconnect to server port\n"); printf("\t -l --location=location\t\tthe location in which the device resides\n"); printf("\t -d --device=device\t\tthe device that you want to control\n"); printf("\t -s --state=state\t\tthe new state of the device\n"); printf("\t -v --values=values\t\tspecific comma separated values, e.g.:\n"); printf("\t\t\t\t\t-v dimlevel=10\n"); exit(EXIT_SUCCESS); break; case 'V': printf("%s %s\n", progname, VERSION); exit(EXIT_SUCCESS); break; case 'l': strcpy(location, optarg); break; case 'd': strcpy(device, optarg); break; case 's': strcpy(state, optarg); break; case 'v': strcpy(values, optarg); break; case 'S': server = realloc(server, strlen(optarg)+1); strcpy(server, optarg); break; case 'P': port = (unsigned short)atoi(optarg); break; default: printf("Usage: %s -l location -d device -s state\n", progname); exit(EXIT_SUCCESS); break; } } options_delete(options); if(strlen(location) == 0 || strlen(device) == 0 || strlen(state) == 0) { printf("Usage: %s -l location -d device -s state\n", progname); exit(EXIT_SUCCESS); } if(server && port > 0) { if((sockfd = socket_connect(server, port)) == -1) { logprintf(LOG_ERR, "could not connect to pilight-daemon"); exit(EXIT_FAILURE); } } else if(ssdp_seek(&ssdp_list) == -1) { logprintf(LOG_ERR, "no pilight ssdp connections found"); goto close; } else { if((sockfd = socket_connect(ssdp_list->ip, ssdp_list->port)) == -1) { logprintf(LOG_ERR, "could not connect to pilight-daemon"); goto close; } sfree((void *)&ssdp_list); } protocol_init(); while(1) { if(steps > WELCOME) { /* Clear the receive buffer again and read the welcome message */ if(steps == CONFIG) { if((recvBuff = socket_read_big(sockfd)) != NULL) { json = json_decode(recvBuff); json_find_string(json, "message", &message); } else { goto close; } } else { if((recvBuff = socket_read(sockfd)) != NULL) { json = json_decode(recvBuff); json_find_string(json, "message", &message); } else { goto close; } } usleep(100); } switch(steps) { case WELCOME: socket_write(sockfd, "{\"message\":\"client controller\"}"); steps=IDENTIFY; break; case IDENTIFY: if(strcmp(message, "accept client") == 0) { steps=REQUEST; } if(strcmp(message, "reject client") == 0) { steps=REJECT; } case REQUEST: socket_write(sockfd, "{\"message\":\"request config\"}"); steps=CONFIG; json_delete(json); break; case CONFIG: if((jconfig = json_find_member(json, "config")) != NULL) { config_parse(jconfig); if(config_get_location(location, &slocation) == 0) { if(config_get_device(location, device, &sdevice) == 0) { JsonNode *joutput = json_mkobject(); jcode = json_mkobject(); jvalues = json_mkobject(); json_append_member(jcode, "location", json_mkstring(location)); json_append_member(jcode, "device", json_mkstring(device)); pch = strtok(values, ",="); while(pch != NULL) { char *name = strdup(pch); pch = strtok(NULL, ",="); if(pch == NULL) { break; } else { char *val = strdup(pch); if(pch != NULL) { if(config_valid_value(location, device, name, val) == 0) { if(isNumeric(val) == EXIT_SUCCESS) { json_append_member(jvalues, name, json_mknumber(atoi(val))); } else { json_append_member(jvalues, name, json_mkstring(val)); } has_values = 1; } else { logprintf(LOG_ERR, "\"%s\" is an invalid value for device \"%s\"", name, device); goto close; } } else { logprintf(LOG_ERR, "\"%s\" is an invalid value for device \"%s\"", name, device); goto close; } pch = strtok(NULL, ",="); if(pch == NULL) { break; } } } if(config_valid_state(location, device, state) == 0) { json_append_member(jcode, "state", json_mkstring(state)); } else { logprintf(LOG_ERR, "\"%s\" is an invalid state for device \"%s\"", state, device); goto close; } if(has_values == 1) { json_append_member(jcode, "values", jvalues); } else { json_delete(jvalues); } json_append_member(joutput, "message", json_mkstring("send")); json_append_member(joutput, "code", jcode); char *output = json_stringify(joutput, NULL); socket_write(sockfd, output); sfree((void *)&output); json_delete(joutput); } else { logprintf(LOG_ERR, "the device \"%s\" does not exist", device); goto close; } } else { logprintf(LOG_ERR, "the location \"%s\" does not exist", location); goto close; } } json_delete(json); goto close; break; case REJECT: default: json_delete(json); goto close; break; } } close: if(sockfd > 0) { socket_close(sockfd); } if(server) { sfree((void *)&server); } log_shell_disable(); config_gc(); protocol_gc(); socket_gc(); options_gc(); log_gc(); sfree((void *)&progname); return EXIT_SUCCESS; }
/* Parse the incoming buffer from the client */ void socket_parse_data(int i, char buffer[BUFFER_SIZE]) { int sd = socket_clients[i]; struct sockaddr_in address; int addrlen = sizeof(address); char *message = NULL; JsonNode *json = json_decode(buffer); getpeername(sd, (struct sockaddr*)&address, (socklen_t*)&addrlen); if(json_find_string(json, "black", &message) == 0) { if(black == 0) { black = 1; draw_loop = 0; usleep((__useconds_t)speed); main_draw_black(); } else { main_draw(); black = 0; } } else { if(json_find_string(json, "percentage", &message) == 0) { if(black == 1) { progress_active = 0; main_draw(); black = 0; } draw_loop = 0; infinite = 0; pthread_mutex_lock(&progress_lock); percentage = atoi(message); draw_loop = 1; pthread_mutex_unlock(&progress_lock); pthread_cond_signal(&progress_signal); } else if(json_find_string(json, "infinite", &message) == 0) { if(black == 1) { progress_active = 0; main_draw(); black = 0; } draw_loop = 0; infinite = 1; pthread_mutex_lock(&progress_lock); draw_loop = 1; percentage = -1; pthread_mutex_unlock(&progress_lock); pthread_cond_signal(&progress_signal); } if(json_find_string(json, "message", &message) == 0) { struct template_t *tmp_tpl = template; while(tmp_tpl) { if(tmp_tpl->type == TEXT) { break; } tmp_tpl = tmp_tpl->next; } if(black == 1) { main_draw(); black = 0; } if(strlen(prevMessage) > 0) { main_clear_text(tmp_tpl); } main_draw_text(tmp_tpl, message); } } json_delete(json); }
void *xbmcParse(void *param) { struct protocol_threads_t *node = (struct protocol_threads_t *)param; struct JsonNode *json = (struct JsonNode *)node->param; struct JsonNode *jid = NULL; struct JsonNode *jchild = NULL; struct JsonNode *jchild1 = NULL; struct sockaddr_in serv_addr; struct xbmc_data_t *xnode = malloc(sizeof(struct xbmc_data_t)); char recvBuff[BUFFER_SIZE], action[10], media[15]; char *m = NULL, *t = NULL; char shut[] = "shutdown"; char home[] = "home"; char none[] = "none"; int nrloops = 0, bytes = 0, n = 0, has_server = 0; int has_port = 0, reset = 1, maxfd = 0; fd_set fdsread; struct timeval timeout; timeout.tv_sec = 1; timeout.tv_usec = 0; if(!xnode) { logprintf(LOG_ERR, "out of memory"); exit(EXIT_FAILURE); } /* Clear the server address */ memset(&serv_addr, '\0', sizeof(serv_addr)); memset(&recvBuff, '\0', BUFFER_SIZE); memset(&action, '\0', 10); memset(&media, '\0', 15); xbmc_threads++; if((jid = json_find_member(json, "id"))) { jchild = json_first_child(jid); while(jchild) { jchild1 = json_first_child(jchild); while(jchild1) { if(strcmp(jchild1->key, "server") == 0) { if(!(xnode->server = malloc(strlen(jchild1->string_)+1))) { logprintf(LOG_ERR, "out of memory"); exit(EXIT_FAILURE); } strcpy(xnode->server, jchild1->string_); has_server = 1; } if(strcmp(jchild1->key, "port") == 0) { xnode->port = (int)round(jchild1->number_); has_port = 1; } jchild1 = jchild1->next; } if(has_server == 1 && has_port == 1) { xnode->sockfd = -1; xnode->next = xbmc_data; xbmc_data = xnode; } else { if(has_server == 1) { sfree((void *)&xnode->server); } sfree((void *)&xnode); xnode = NULL; } jchild = jchild->next; } } if(!xnode) { return 0; } while(xbmc_loop) { if(reset == 1) { xbmcCreateMessage(xnode->server, xnode->port, shut, none); reset = 0; } if(xnode->sockfd > -1) { close(xnode->sockfd); xnode->sockfd = -1; } /* Try to open a new socket */ if((xnode->sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { logprintf(LOG_DEBUG, "could not create XBMC socket"); break; } serv_addr.sin_family = AF_INET; serv_addr.sin_port = htons((unsigned short)xnode->port); inet_pton(AF_INET, xnode->server, &serv_addr.sin_addr); /* Connect to the server */ if(connect(xnode->sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) { protocol_thread_wait(node, 3, &nrloops); continue; } else { xbmcCreateMessage(xnode->server, xnode->port, home, none); reset = 1; } struct xbmc_data_t *xtmp = xbmc_data; while(xtmp) { if(xtmp->sockfd > -1) { if(maxfd < xtmp->sockfd) { maxfd = xtmp->sockfd; } } xtmp = xtmp->next; } while(xbmc_loop) { FD_ZERO(&fdsread); FD_SET((unsigned long)xnode->sockfd, &fdsread); do { n = select(maxfd+1, &fdsread, NULL, NULL, &timeout); } while(n == -1 && errno == EINTR && xbmc_loop); if(xbmc_loop == 0) { break; } if(n == -1) { break; } else if(n == 0) { usleep(10000); } else if(n > 0) { if(FD_ISSET((unsigned long)xnode->sockfd, &fdsread)) { bytes = (int)recv(xnode->sockfd, recvBuff, BUFFER_SIZE, 0); if(bytes <= 0) { break; } else { if(json_validate(recvBuff) == true) { JsonNode *joutput = json_decode(recvBuff); JsonNode *params = NULL; JsonNode *data = NULL; JsonNode *item = NULL; if(json_find_string(joutput, "method", &m) == 0) { if(strcmp(m, "GUI.OnScreensaverActivated") == 0) { strcpy(media, "screensaver"); strcpy(action, "active"); } else if(strcmp(m, "GUI.OnScreensaverDeactivated") == 0) { strcpy(media, "screensaver"); strcpy(action, "inactive"); } else { if((params = json_find_member(joutput, "params")) != NULL) { if((data = json_find_member(params, "data")) != NULL) { if((item = json_find_member(data, "item")) != NULL) { if(json_find_string(item, "type", &t) == 0) { xbmc->message = json_mkobject(); strcpy(media, t); if(strcmp(m, "Player.OnPlay") == 0) { strcpy(action, "play"); } else if(strcmp(m, "Player.OnStop") == 0) { strcpy(action, home); strcpy(media, none); } else if(strcmp(m, "Player.OnPause") == 0) { strcpy(action, "pause"); } } } } } } if(strlen(media) > 0 && strlen(action) > 0) { xbmcCreateMessage(xnode->server, xnode->port, action, media); reset = 1; } } json_delete(joutput); } memset(recvBuff, '\0', BUFFER_SIZE); memset(&action, '\0', 10); memset(&media, '\0', 15); } } } } } xbmc_threads--; return (void *)NULL; }
int main(int argc, char **argv) { // memtrack(); struct options_t *options = NULL; struct ssdp_list_t *ssdp_list = NULL; struct devices_t *dev = NULL; struct JsonNode *json = NULL; struct JsonNode *tmp = NULL; char *recvBuff = NULL, *message = NULL, *output = NULL; char *device = NULL, *state = NULL, *values = NULL; char *server = NULL; int has_values = 0, sockfd = 0, hasconfarg = 0; unsigned short port = 0, showhelp = 0, showversion = 0; log_file_disable(); log_shell_enable(); log_level_set(LOG_NOTICE); if(!(progname = MALLOC(16))) { logprintf(LOG_ERR, "out of memory"); exit(EXIT_FAILURE); } strcpy(progname, "pilight-control"); /* Define all CLI arguments of this program */ options_add(&options, 'H', "help", OPTION_NO_VALUE, 0, JSON_NULL, NULL, NULL); options_add(&options, 'V', "version", OPTION_NO_VALUE, 0, JSON_NULL, NULL, NULL); options_add(&options, 'd', "device", OPTION_HAS_VALUE, 0, JSON_NULL, NULL, NULL); options_add(&options, 's', "state", OPTION_HAS_VALUE, 0, JSON_NULL, NULL, NULL); options_add(&options, 'v', "values", OPTION_HAS_VALUE, 0, JSON_NULL, NULL, NULL); options_add(&options, 'S', "server", OPTION_HAS_VALUE, 0, JSON_NULL, NULL, "^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]).){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$"); options_add(&options, 'P', "port", OPTION_HAS_VALUE, 0, JSON_NULL, NULL, "[0-9]{1,4}"); options_add(&options, 'C', "config", OPTION_HAS_VALUE, 0, JSON_NULL, NULL, NULL); /* Store all CLI arguments for later usage and also check if the CLI arguments where used correctly by the user. This will also fill all necessary values in the options struct */ while(1) { int c; c = options_parse(&options, argc, argv, 1, &optarg); if(c == -1) break; if(c == -2) { showhelp = 1; break; } switch(c) { case 'H': showhelp = 1; break; case 'V': showversion = 1; break; case 'd': if((device = REALLOC(device, strlen(optarg)+1)) == NULL) { logprintf(LOG_ERR, "out of memory"); exit(EXIT_FAILURE); } strcpy(device, optarg); break; case 's': if((state = REALLOC(state, strlen(optarg)+1)) == NULL) { logprintf(LOG_ERR, "out of memory"); exit(EXIT_FAILURE); } strcpy(state, optarg); break; case 'v': if((values = REALLOC(values, strlen(optarg)+1)) == NULL) { logprintf(LOG_ERR, "out of memory"); exit(EXIT_FAILURE); } strcpy(values, optarg); break; case 'C': if(config_set_file(optarg) == EXIT_FAILURE) { return EXIT_FAILURE; } hasconfarg = 1; break; case 'S': if(!(server = REALLOC(server, strlen(optarg)+1))) { logprintf(LOG_ERR, "out of memory"); exit(EXIT_FAILURE); } strcpy(server, optarg); break; case 'P': port = (unsigned short)atoi(optarg); break; default: printf("Usage: %s -l location -d device -s state\n", progname); goto close; break; } } options_delete(options); if(showversion == 1) { printf("%s %s\n", progname, PILIGHT_VERSION); goto close; } if(showhelp == 1) { printf("\t -H --help\t\t\tdisplay this message\n"); printf("\t -V --version\t\t\tdisplay version\n"); printf("\t -S --server=x.x.x.x\t\tconnect to server address\n"); printf("\t -C --config\t\t\tconfig file\n"); printf("\t -P --port=xxxx\t\t\tconnect to server port\n"); printf("\t -d --device=device\t\tthe device that you want to control\n"); printf("\t -s --state=state\t\tthe new state of the device\n"); printf("\t -v --values=values\t\tspecific comma separated values, e.g.:\n"); printf("\t\t\t\t\t-v dimlevel=10\n"); goto close; } if(device == NULL || state == NULL || strlen(device) == 0 || strlen(state) == 0) { printf("Usage: %s -d device -s state\n", progname); goto close; } if(server && port > 0) { if((sockfd = socket_connect(server, port)) == -1) { logprintf(LOG_ERR, "could not connect to pilight-daemon"); goto close; } } else if(ssdp_seek(&ssdp_list) == -1) { logprintf(LOG_ERR, "no pilight ssdp connections found"); goto close; } else { if((sockfd = socket_connect(ssdp_list->ip, ssdp_list->port)) == -1) { logprintf(LOG_ERR, "could not connect to pilight-daemon"); goto close; } } if(ssdp_list) { ssdp_free(ssdp_list); } protocol_init(); config_init(); if(hasconfarg == 1) { if(config_read() != EXIT_SUCCESS) { goto close; } } socket_write(sockfd, "{\"action\":\"identify\"}"); if(socket_read(sockfd, &recvBuff, 0) != 0 || strcmp(recvBuff, "{\"status\":\"success\"}") != 0) { goto close; } json = json_mkobject(); json_append_member(json, "action", json_mkstring("request config")); output = json_stringify(json, NULL); socket_write(sockfd, output); json_free(output); json_delete(json); if(socket_read(sockfd, &recvBuff, 0) == 0) { if(json_validate(recvBuff) == true) { json = json_decode(recvBuff); if(json_find_string(json, "message", &message) == 0) { if(strcmp(message, "config") == 0) { struct JsonNode *jconfig = NULL; if((jconfig = json_find_member(json, "config")) != NULL) { int match = 1; while(match) { struct JsonNode *jchilds = json_first_child(jconfig); match = 0; while(jchilds) { if(strcmp(jchilds->key, "devices") != 0) { json_remove_from_parent(jchilds); tmp = jchilds; match = 1; } jchilds = jchilds->next; if(tmp != NULL) { json_delete(tmp); } tmp = NULL; } } config_parse(jconfig); if(devices_get(device, &dev) == 0) { JsonNode *joutput = json_mkobject(); JsonNode *jcode = json_mkobject(); JsonNode *jvalues = json_mkobject(); json_append_member(jcode, "device", json_mkstring(device)); if(values != NULL) { char **array = NULL; unsigned int n = explode(values, ",=", &array), q = 0; for(q=0;q<n;q+=2) { char *name = MALLOC(strlen(array[q])+1); if(name == NULL) { logprintf(LOG_ERR, "out of memory\n"); exit(EXIT_FAILURE); } strcpy(name, array[q]); if(q+1 == n) { for(q=0;q<n;q++) { FREE(array[q]); } FREE(array); logprintf(LOG_ERR, "\"%s\" is missing a value for device \"%s\"", name, device); FREE(name); break; } else { char *val = MALLOC(strlen(array[q+1])+1); if(val == NULL) { logprintf(LOG_ERR, "out of memory\n"); exit(EXIT_FAILURE); } strcpy(val, array[q+1]); if(devices_valid_value(device, name, val) == 0) { if(isNumeric(val) == EXIT_SUCCESS) { char *ptr = strstr(array[q+1], "."); int decimals = 0; if(ptr != NULL) { decimals = (int)(strlen(array[q+1])-((size_t)(ptr-array[q+1])+1)); } json_append_member(jvalues, name, json_mknumber(atof(val), decimals)); } else { json_append_member(jvalues, name, json_mkstring(val)); } has_values = 1; } else { logprintf(LOG_ERR, "\"%s\" is an invalid value for device \"%s\"", name, device); for(q=0;q<n;q++) { FREE(array[q]); } FREE(array); FREE(name); json_delete(json); goto close; } } FREE(name); } unsigned int z = 0; for(z=q;z<n;z++) { FREE(array[z]); } if(n > 0) { FREE(array); } } if(devices_valid_state(device, state) == 0) { json_append_member(jcode, "state", json_mkstring(state)); } else { logprintf(LOG_ERR, "\"%s\" is an invalid state for device \"%s\"", state, device); json_delete(json); goto close; } if(has_values == 1) { json_append_member(jcode, "values", jvalues); } else { json_delete(jvalues); } json_append_member(joutput, "action", json_mkstring("control")); json_append_member(joutput, "code", jcode); output = json_stringify(joutput, NULL); socket_write(sockfd, output); json_free(output); json_delete(joutput); if(socket_read(sockfd, &recvBuff, 0) != 0 || strcmp(recvBuff, "{\"status\":\"success\"}") != 0) { logprintf(LOG_ERR, "failed to control %s", device); } } else { logprintf(LOG_ERR, "the device \"%s\" does not exist", device); json_delete(json); goto close; } } } } json_delete(json); } } close: if(recvBuff) { FREE(recvBuff); } if(sockfd > 0) { socket_close(sockfd); } if(server != NULL) { FREE(server); } if(device != NULL) { FREE(device); } if(state != NULL) { FREE(state); } if(values != NULL) { FREE(values); } log_shell_disable(); socket_gc(); config_gc(); protocol_gc(); options_gc(); event_operator_gc(); event_action_gc(); dso_gc(); log_gc(); threads_gc(); gc_clear(); FREE(progname); xfree(); return EXIT_SUCCESS; }
static void *thread(void *param) { struct protocol_threads_t *pnode = (struct protocol_threads_t *)param; struct JsonNode *json = (struct JsonNode *)pnode->param; struct JsonNode *jid = NULL; struct JsonNode *jchild = NULL; char *state = NULL, *onquery = NULL, *offquery = NULL, *onsuccess = NULL, *offsuccess = NULL; char *errresponse = NULL, *onuri = NULL, *offuri = NULL, *response = NULL, *method = NULL; int interval = 1, nrloops = 0; double itmp = 0; threads++; json_find_string(json, "method", &method); json_find_string(json, "on_uri", &onuri); json_find_string(json, "off_uri", &offuri); json_find_string(json, "on_query", &onquery); json_find_string(json, "off_query", &offquery); json_find_string(json, "on_success", &onsuccess); json_find_string(json, "off_success", &offsuccess); json_find_string(json, "err_response", &errresponse); json_find_string(json, "response", &response); json_find_string(json, "state", &state); struct settings_t *lnode = MALLOC(sizeof(struct settings_t)); lnode->wait = 0; lnode->hasthread = 0; memset(&lnode->pth, '\0', sizeof(pthread_t)); if(strcmp(state, "running") == 0) { lnode->newstate = 1; } else { lnode->newstate = 0; } lnode->id = 0; if((jid = json_find_member(json, "id"))) { jchild = json_first_child(jid); if(json_find_number(jchild, "id", &itmp) == 0) lnode->id = (int)round(itmp); } if(strcmp(method, "GET") != 0 && strcmp(method, "POST") != 0) { logprintf(LOG_ERR, "Webswitch %i: method must be either \"GET\" or \"POST\"", lnode->id); exit(EXIT_FAILURE); } if(method != NULL && strlen(method) > 0) { if((lnode->method = MALLOC(strlen(method)+1)) == NULL) { fprintf(stderr, "out of memory\n"); exit(EXIT_FAILURE); } strcpy(lnode->method, method); } else { lnode->method = NULL; } if(onuri != NULL && strlen(onuri) > 0) { if((lnode->on_uri = MALLOC(strlen(onuri)+1)) == NULL) { fprintf(stderr, "out of memory\n"); exit(EXIT_FAILURE); } strcpy(lnode->on_uri, onuri); } else { lnode->on_uri = NULL; } if(offuri != NULL && strlen(offuri) > 0) { if((lnode->off_uri = MALLOC(strlen(offuri)+1)) == NULL) { fprintf(stderr, "out of memory\n"); exit(EXIT_FAILURE); } strcpy(lnode->off_uri, offuri); } else { lnode->off_uri = NULL; } if(onquery != NULL && strlen(onquery) > 0) { if((lnode->on_query = MALLOC(strlen(onquery)+1)) == NULL) { fprintf(stderr, "out of memory\n"); exit(EXIT_FAILURE); } strcpy(lnode->on_query, onquery); } else { lnode->on_query = NULL; } if(offquery != NULL && strlen(offquery) > 0) { if((lnode->off_query = MALLOC(strlen(offquery)+1)) == NULL) { fprintf(stderr, "out of memory\n"); exit(EXIT_FAILURE); } strcpy(lnode->off_query, offquery); } else { lnode->off_query = NULL; } if(onsuccess != NULL && strlen(onsuccess) > 0) { if((lnode->on_success = MALLOC(strlen(onsuccess)+1)) == NULL) { fprintf(stderr, "out of memory\n"); exit(EXIT_FAILURE); } strcpy(lnode->on_success, onsuccess); } else { lnode->on_success = NULL; } if(offsuccess != NULL && strlen(offsuccess) > 0) { if((lnode->off_success = MALLOC(strlen(offsuccess)+1)) == NULL) { fprintf(stderr, "out of memory\n"); exit(EXIT_FAILURE); } strcpy(lnode->off_success, offsuccess); } else { lnode->off_success = NULL; } if(errresponse != NULL && strlen(errresponse) > 0) { if((lnode->err_response = MALLOC(strlen(errresponse)+1)) == NULL) { fprintf(stderr, "out of memory\n"); exit(EXIT_FAILURE); } strcpy(lnode->err_response, errresponse); } else { lnode->err_response = NULL; } if(response != NULL && strlen(response) > 0) { if((lnode->response = MALLOC(strlen(response)+1)) == NULL) { //if((lnode->response = MALLOC(BUFFER_SIZE)) == NULL) { fprintf(stderr, "out of memory\n"); exit(EXIT_FAILURE); } strcpy(lnode->response, response); } else { lnode->response = NULL; } lnode->thread = pnode; lnode->laststate = -1; lnode->currentstate = -1; lnode->next = settings; settings = lnode; if(json_find_number(json, "poll-interval", &itmp) == 0) interval = (int)round(itmp); while(loop) { if(protocol_thread_wait(pnode, interval, &nrloops) == ETIMEDOUT) { pthread_mutex_lock(&lock); if(lnode->wait == 0) { struct JsonNode *message = json_mkobject(); JsonNode *code = json_mkobject(); json_append_member(code, "id", json_mknumber(lnode->id, 0)); json_append_member(code, "response", json_mkstring(lnode->response)); if(lnode->currentstate == -1 && lnode->laststate == -1) { lnode->laststate=lnode->newstate; } if(lnode->newstate == 1) { lnode->currentstate = 1; json_append_member(code, "state", json_mkstring("running")); } else { lnode->currentstate = 0; json_append_member(code, "state", json_mkstring("stopped")); } json_append_member(message, "message", code); json_append_member(message, "origin", json_mkstring("receiver")); json_append_member(message, "protocol", json_mkstring(webswitch->id)); if(lnode->currentstate != lnode->laststate) { lnode->laststate = lnode->currentstate; if(pilight.broadcast != NULL ) { pilight.broadcast(webswitch->id, message, PROTOCOL); } } json_delete(message); message = NULL; } pthread_mutex_unlock(&lock); } } pthread_mutex_unlock(&lock); threads--; return (void *)NULL; }
int main(int argc, char **argv) { log_shell_enable(); log_file_disable(); log_level_set(LOG_NOTICE); progname = malloc(16); if(!progname) { logprintf(LOG_ERR, "out of memory"); exit(EXIT_FAILURE); } strcpy(progname, "pilight-receive"); struct options_t *options = NULL; struct ssdp_list_t *ssdp_list = NULL; JsonNode *json = NULL; char *server = NULL; unsigned short port = 0; int sockfd = 0; char *recvBuff = NULL; char *message = NULL; char *args = NULL; steps_t steps = WELCOME; options_add(&options, 'H', "help", OPTION_NO_VALUE, 0, JSON_NULL, NULL, NULL); options_add(&options, 'V', "version", OPTION_NO_VALUE, 0, JSON_NULL, NULL, NULL); options_add(&options, 'S', "server", OPTION_HAS_VALUE, 0, JSON_NULL, NULL, "^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]).){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$"); options_add(&options, 'P', "port", OPTION_HAS_VALUE, 0, JSON_NULL, NULL, "[0-9]{1,4}"); /* Store all CLI arguments for later usage and also check if the CLI arguments where used correctly by the user. This will also fill all necessary values in the options struct */ while(1) { int c; c = options_parse(&options, argc, argv, 1, &args); if(c == -1) break; if(c == -2) c = 'H'; switch(c) { case 'H': printf("\t -H --help\t\t\tdisplay this message\n"); printf("\t -V --version\t\t\tdisplay version\n"); printf("\t -S --server=x.x.x.x\t\tconnect to server address\n"); printf("\t -P --port=xxxx\t\t\tconnect to server port\n"); exit(EXIT_SUCCESS); break; case 'V': printf("%s %s\n", progname, VERSION); exit(EXIT_SUCCESS); break; case 'S': server = realloc(server, strlen(args)+1); memset(server, '\0', strlen(args)+1); if(!server) { logprintf(LOG_ERR, "out of memory"); exit(EXIT_FAILURE); } strcpy(server, args); break; case 'P': port = (unsigned short)atoi(args); break; default: printf("Usage: %s -l location -d device\n", progname); exit(EXIT_SUCCESS); break; } } options_delete(options); if(server && port > 0) { if((sockfd = socket_connect(server, port)) == -1) { logprintf(LOG_ERR, "could not connect to pilight-daemon"); return EXIT_FAILURE; } } else if(ssdp_seek(&ssdp_list) == -1) { logprintf(LOG_ERR, "no pilight ssdp connections found"); goto close; } else { if((sockfd = socket_connect(ssdp_list->ip, ssdp_list->port)) == -1) { logprintf(LOG_ERR, "could not connect to pilight-daemon"); goto close; } } if(ssdp_list) { ssdp_free(ssdp_list); } if(server) { sfree((void *)&server); } while(1) { if(steps > WELCOME) { if((recvBuff = socket_read(sockfd)) == NULL) { goto close; } } switch(steps) { case WELCOME: socket_write(sockfd, "{\"message\":\"client receiver\"}"); steps=IDENTIFY; break; case IDENTIFY: //extract the message json = json_decode(recvBuff); json_find_string(json, "message", &message); if(strcmp(message, "accept client") == 0) { steps=RECEIVE; } else if(strcmp(message, "reject client") == 0) { steps=REJECT; } //cleanup json_delete(json); sfree((void *)&recvBuff); json = NULL; message = NULL; recvBuff = NULL; break; case RECEIVE: { char *line = strtok(recvBuff, "\n"); //for each line while(line) { json = json_decode(line); char *output = json_stringify(json, "\t"); printf("%s\n", output); sfree((void *)&output); json_delete(json); line = strtok(NULL,"\n"); } sfree((void *)&recvBuff); sfree((void *)&line); recvBuff = NULL; } break; case REJECT: default: goto close; break; } } close: if(sockfd > 0) { socket_close(sockfd); } if(recvBuff) { sfree((void *)&recvBuff); } options_gc(); log_shell_disable(); log_gc(); sfree((void *)&progname); return EXIT_SUCCESS; }
static void *thread(void *param) { struct protocol_threads_t *node = (struct protocol_threads_t *)param; struct JsonNode *json = (struct JsonNode *)node->param; struct JsonNode *jid = NULL; struct JsonNode *jchild = NULL; #ifndef _WIN32 struct dirent *file = NULL; struct stat st; DIR *d = NULL; FILE *fp = NULL; char crcVar[5]; int w1valid = 0; double w1temp = 0.0; size_t bytes = 0; #endif char **id = NULL, *stmp = NULL, *content = NULL; char *ds18s20_sensor = NULL; int nrid = 0, interval = 10, nrloops = 0, y = 0; double temp_offset = 0.0, itmp = 0.0; threads++; if((jid = json_find_member(json, "id"))) { jchild = json_first_child(jid); while(jchild) { if(json_find_string(jchild, "id", &stmp) == 0) { if((id = REALLOC(id, (sizeof(char *)*(size_t)(nrid+1)))) == NULL) { fprintf(stderr, "out of memory\n"); exit(EXIT_FAILURE); } if((id[nrid] = MALLOC(strlen(stmp)+1)) == NULL) { fprintf(stderr, "out of memory\n"); exit(EXIT_FAILURE); } strcpy(id[nrid], stmp); nrid++; } jchild = jchild->next; } } if(json_find_number(json, "poll-interval", &itmp) == 0) interval = (int)round(itmp); json_find_number(json, "temperature-offset", &temp_offset); while(loop) { if(protocol_thread_wait(node, interval, &nrloops) == ETIMEDOUT) { #ifndef _WIN32 pthread_mutex_lock(&lock); for(y=0;y<nrid;y++) { if((ds18s20_sensor = REALLOC(ds18s20_sensor, strlen(source_path)+strlen(id[y])+5)) == NULL) { fprintf(stderr, "out of memory\n"); exit(EXIT_FAILURE); } sprintf(ds18s20_sensor, "%s10-%s/", source_path, id[y]); if((d = opendir(ds18s20_sensor))) { while((file = readdir(d)) != NULL) { if(file->d_type == DT_REG) { if(strcmp(file->d_name, "w1_slave") == 0) { size_t w1slavelen = strlen(ds18s20_sensor)+10; char ds18s20_w1slave[w1slavelen]; memset(ds18s20_w1slave, '\0', w1slavelen); strncpy(ds18s20_w1slave, ds18s20_sensor, strlen(ds18s20_sensor)); strcat(ds18s20_w1slave, "w1_slave"); if(!(fp = fopen(ds18s20_w1slave, "rb"))) { logprintf(LOG_ERR, "cannot read w1 file: %s", ds18s20_w1slave); break; } fstat(fileno(fp), &st); bytes = (size_t)st.st_size; if(!(content = REALLOC(content, bytes+1))) { fprintf(stderr, "out of memory\n"); fclose(fp); break; } memset(content, '\0', bytes+1); if(fread(content, sizeof(char), bytes, fp) == -1) { logprintf(LOG_ERR, "cannot read config file: %s", ds18s20_w1slave); fclose(fp); break; } fclose(fp); w1valid = 0; char **array = NULL; unsigned int n = explode(content, "\n", &array); if(n > 0) { sscanf(array[0], "%*x %*x %*x %*x %*x %*x %*x %*x %*x : crc=%*x %s", crcVar); if(strncmp(crcVar, "YES", 3) == 0 && n > 1) { w1valid = 1; sscanf(array[1], "%*x %*x %*x %*x %*x %*x %*x %*x %*x t=%lf", &w1temp); w1temp = (w1temp/1000)+temp_offset; } } array_free(&array, n); if(w1valid) { ds18s20->message = json_mkobject(); JsonNode *code = json_mkobject(); json_append_member(code, "id", json_mkstring(id[y])); json_append_member(code, "temperature", json_mknumber(w1temp, 1)); json_append_member(ds18s20->message, "message", code); json_append_member(ds18s20->message, "origin", json_mkstring("receiver")); json_append_member(ds18s20->message, "protocol", json_mkstring(ds18s20->id)); if(pilight.broadcast != NULL) { pilight.broadcast(ds18s20->id, ds18s20->message, PROTOCOL); } json_delete(ds18s20->message); ds18s20->message = NULL; } } } } closedir(d); } else { logprintf(LOG_ERR, "1-wire device %s does not exists", ds18s20_sensor); } } #endif pthread_mutex_unlock(&lock); } } pthread_mutex_unlock(&lock); if(ds18s20_sensor) { FREE(ds18s20_sensor); } if(content) { FREE(content); } for(y=0;y<nrid;y++) { FREE(id[y]); } FREE(id); threads--; return (void *)NULL; }
int programCreateCode(JsonNode *code) { char *name = NULL; double itmp = -1; int state = -1; int pid = 0; if(json_find_string(code, "name", &name) == 0) { if(strstr(progname, "daemon") != NULL) { struct programs_t *tmp = programs; while(tmp) { if(strcmp(tmp->name, name) == 0) { if(tmp->wait == 0 && tmp->pth == 0) { if(tmp->name != NULL && tmp->stop != NULL && tmp->start != NULL) { if(json_find_number(code, "running", &itmp) == 0) state = 1; else if(json_find_number(code, "stopped", &itmp) == 0) state = 0; if((pid = (int)findproc(tmp->program, tmp->arguments)) > 0 && state == 1) { logprintf(LOG_ERR, "program \"%s\" already running", tmp->name); } else if(pid == -1 && state == 0) { logprintf(LOG_ERR, "program \"%s\" already stopped", tmp->name); break; } else { if(state > -1) { program->message = json_mkobject(); JsonNode *code1 = json_mkobject(); json_append_member(code1, "name", json_mkstring(name)); if(state == 1) { json_append_member(code1, "state", json_mkstring("running")); } else { json_append_member(code1, "state", json_mkstring("stopped")); } json_append_member(program->message, "message", code1); json_append_member(program->message, "origin", json_mkstring("receiver")); json_append_member(program->message, "protocol", json_mkstring(program->id)); pilight.broadcast(program->id, program->message); json_delete(program->message); program->message = NULL; } tmp->wait = 1; threads_create(&tmp->pth, NULL, programThread, (void *)tmp); pthread_detach(tmp->pth); program->message = json_mkobject(); json_append_member(program->message, "name", json_mkstring(name)); json_append_member(program->message, "state", json_mkstring("pending")); } } else { logprintf(LOG_ERR, "program \"%s\" cannot be controlled", tmp->name); } } else { logprintf(LOG_ERR, "please wait for program \"%s\" to finish it's state change", tmp->name); } break; } tmp = tmp->next; } } else { program->message = json_mkobject(); if(json_find_number(code, "running", &itmp) == 0) json_append_member(program->message, "state", json_mkstring("running")); else if(json_find_number(code, "stopped", &itmp) == 0) json_append_member(program->message, "state", json_mkstring("stopped")); json_append_member(program->message, "name", json_mkstring(name)); json_append_member(program->message, "state", json_mkstring("pending")); } } else { return EXIT_FAILURE; } return EXIT_SUCCESS; }
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; }
void *programParse(void *param) { struct protocol_threads_t *pnode = (struct protocol_threads_t *)param; struct JsonNode *json = (struct JsonNode *)pnode->param; struct JsonNode *jid = NULL; struct JsonNode *jchild = NULL; struct JsonNode *jchild1 = NULL; char *prog = NULL, *args = NULL, *stopcmd = NULL, *startcmd = NULL; int interval = 1, nrloops = 0, currentstate = 0, laststate = -1; int pid = 0; double itmp = 0; program_threads++; json_find_string(json, "program", &prog); json_find_string(json, "arguments", &args); json_find_string(json, "stop-command", &stopcmd); json_find_string(json, "start-command", &startcmd); struct programs_t *lnode = malloc(sizeof(struct programs_t)); lnode->wait = 0; lnode->pth = 0; if(args && strlen(args) > 0) { if(!(lnode->arguments = malloc(strlen(args)+1))) { logprintf(LOG_ERR, "out of memory"); exit(EXIT_FAILURE); } strcpy(lnode->arguments, args); } else { lnode->arguments = NULL; } if(prog) { if(!(lnode->program = malloc(strlen(prog)+1))) { logprintf(LOG_ERR, "out of memory"); exit(EXIT_FAILURE); } strcpy(lnode->program, prog); } else { lnode->program = NULL; } if(stopcmd) { if(!(lnode->stop = malloc(strlen(stopcmd)+1))) { logprintf(LOG_ERR, "out of memory"); exit(EXIT_FAILURE); } strcpy(lnode->stop, stopcmd); } else { lnode->stop = NULL; } if(startcmd) { if(!(lnode->start = malloc(strlen(startcmd)+1))) { logprintf(LOG_ERR, "out of memory"); exit(EXIT_FAILURE); } strcpy(lnode->start, startcmd); } else { lnode->start = NULL; } if((jid = json_find_member(json, "id"))) { jchild = json_first_child(jid); while(jchild) { jchild1 = json_first_child(jchild); while(jchild1) { if(strcmp(jchild1->key, "name") == 0) { if(!(lnode->name = malloc(strlen(jchild1->string_)+1))) { logprintf(LOG_ERR, "out of memory"); exit(EXIT_FAILURE); } strcpy(lnode->name, jchild1->string_); } jchild1 = jchild1->next; } jchild = jchild->next; } } struct programs_t *tmp = programs; if(tmp) { while(tmp->next != NULL) { tmp = tmp->next; } tmp->next = lnode; } else { lnode->next = tmp; programs = lnode; } if(json_find_number(json, "poll-interval", &itmp) == 0) interval = (int)round(itmp); while(program_loop) { if(protocol_thread_wait(pnode, interval, &nrloops) == ETIMEDOUT) { if(lnode->wait == 0) { program->message = json_mkobject(); JsonNode *code = json_mkobject(); json_append_member(code, "name", json_mkstring(lnode->name)); if((pid = (int)findproc(lnode->program, lnode->arguments)) > 0) { currentstate = 1; json_append_member(code, "state", json_mkstring("running")); json_append_member(code, "pid", json_mknumber((int)pid)); } else { currentstate = 0; json_append_member(code, "state", json_mkstring("stopped")); json_append_member(code, "pid", json_mknumber(0)); } json_append_member(program->message, "message", code); json_append_member(program->message, "origin", json_mkstring("receiver")); json_append_member(program->message, "protocol", json_mkstring(program->id)); if(currentstate != laststate) { laststate = currentstate; pilight.broadcast(program->id, program->message); } json_delete(program->message); program->message = NULL; } } } program_threads--; return (void *)NULL; }
int main(int argc, char **argv) { disable_file_log(); enable_shell_log(); set_loglevel(LOG_NOTICE); progname = malloc((10*sizeof(char))+1); progname = strdup("433-control"); options = malloc(255*sizeof(struct options_t)); int sockfd = 0; char *recvBuff = NULL; char *message; steps_t steps = WELCOME; char device[50]; char location[50]; char state[10] = {'\0'}; struct conf_locations_t *slocation = NULL; struct conf_devices_t *sdevice = NULL; char server[16] = "127.0.0.1"; unsigned short port = PORT; JsonNode *json = json_mkobject(); JsonNode *config = json_mkobject(); JsonNode *code = json_mkobject(); /* Define all CLI arguments of this program */ addOption(&options, 'h', "help", no_value, 0, NULL); addOption(&options, 'v', "version", no_value, 0, NULL); addOption(&options, 'l', "location", has_value, 0, NULL); addOption(&options, 'd', "device", has_value, 0, NULL); addOption(&options, 's', "state", has_value, 0, NULL); addOption(&options, 'S', "server", has_value, 0, "^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]).){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$"); addOption(&options, 'P', "port", has_value, 0, "[0-9]{1,4}"); /* Store all CLI arguments for later usage and also check if the CLI arguments where used correctly by the user. This will also fill all necessary values in the options struct */ while(1) { int c; c = getOptions(&options, argc, argv, 1); if(c == -1) break; switch(c) { case 'h': printf("\t -h --help\t\t\tdisplay this message\n"); printf("\t -v --version\t\t\tdisplay version\n"); printf("\t -S --server=%s\t\tconnect to server address\n", server); printf("\t -P --port=%d\t\t\tconnect to server port\n", port); printf("\t -l --location=location\t\tthe location in which the device resides\n"); printf("\t -d --device=device\t\tthe device that you want to control\n"); printf("\t -s --state=state\t\tthe new state of the device\n"); exit(EXIT_SUCCESS); break; case 'v': printf("%s %s\n", progname, "1.0"); exit(EXIT_SUCCESS); break; case 'l': strcpy(location, optarg); break; case 'd': strcpy(device, optarg); break; case 's': strcpy(state, optarg); break; case 'S': strcpy(server, optarg); break; case 'P': port = (unsigned short)atoi(optarg); break; default: printf("Usage: %s -l location -d device\n", progname); exit(EXIT_SUCCESS); break; } } if(strlen(location) == 0 || strlen(device) == 0) { printf("Usage: %s -l location -d device\n", progname); exit(EXIT_SUCCESS); } if((sockfd = connect_to_server(strdup(server), port)) == -1) { logprintf(LOG_ERR, "could not connect to 433-daemon"); exit(EXIT_FAILURE); } /* Initialize peripheral modules */ hw_init(); while(1) { if(steps > WELCOME) { /* Clear the receive buffer again and read the welcome message */ if(steps == REQUEST) { if((recvBuff = socket_read_big(sockfd)) != NULL) { json = json_decode(recvBuff); json_find_string(json, "message", &message); } else { goto close; } } else { if((recvBuff = socket_read(sockfd)) != NULL) { json = json_decode(recvBuff); json_find_string(json, "message", &message); } else { goto close; } } usleep(250); } switch(steps) { case WELCOME: socket_write(sockfd, "{\"message\":\"client controller\"}"); steps=IDENTIFY; break; case IDENTIFY: if(strcmp(message, "accept client") == 0) { steps=REQUEST; } if(strcmp(message, "reject client") == 0) { steps=REJECT; } case REQUEST: socket_write(sockfd, "{\"message\":\"request config\"}"); steps=CONFIG; break; case CONFIG: if((config = json_find_member(json, "config")) != NULL) { config_parse(config); if(config_get_location(location, &slocation) == 0) { if(config_get_device(location, device, &sdevice) == 0) { json_delete(json); json = json_mkobject(); code = json_mkobject(); json_append_member(code, "location", json_mkstring(location)); json_append_member(code, "device", json_mkstring(device)); if(strlen(state) > 0) { if(config_valid_state(location, device, state) == 0) { json_append_member(code, "state", json_mkstring(state)); } else { logprintf(LOG_ERR, "\"%s\" is an invalid state for device \"%s\"", state, device); goto close; } } json_append_member(json, "message", json_mkstring("send")); json_append_member(json, "code", code); socket_write(sockfd, json_stringify(json, NULL)); } else { logprintf(LOG_ERR, "the device \"%s\" does not exist", device); goto close; } } else { logprintf(LOG_ERR, "the location \"%s\" does not exist", location); goto close; } } goto close; break; case REJECT: default: goto close; break; } } close: json_delete(json); socket_close(sockfd); return EXIT_SUCCESS; }