예제 #1
0
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;
}
예제 #2
0
파일: xbmc.c 프로젝트: knudje/pilight
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;
}
예제 #3
0
파일: x10.c 프로젝트: Johan-M/pilight
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;
}
예제 #4
0
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;
}
예제 #5
0
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;
}
예제 #6
0
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;
}
예제 #7
0
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;
}
예제 #8
0
파일: raw.c 프로젝트: Johan-M/pilight
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;
}
예제 #9
0
파일: clarus.c 프로젝트: knudje/pilight
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;
}
예제 #10
0
파일: raw.c 프로젝트: 1000io/pilight
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;
}
예제 #11
0
파일: receive.c 프로젝트: John1988/pilight
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;
}
예제 #12
0
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;
}
예제 #13
0
파일: rules.c 프로젝트: Lyve1981/pilight
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;
}
예제 #14
0
파일: plview.c 프로젝트: qrti/plview
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;
}
예제 #15
0
파일: relay.c 프로젝트: Lyve1981/pilight
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;
	}
}
예제 #16
0
파일: rules.c 프로젝트: Johan-M/pilight
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;
}
예제 #17
0
파일: lm76.c 프로젝트: 1000io/pilight
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
		}
예제 #18
0
파일: ds18b20.c 프로젝트: knudje/pilight
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;
}
예제 #19
0
파일: control.c 프로젝트: 1000io/pilight
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;
}
예제 #20
0
파일: daemon.c 프로젝트: CurlyMoo/Splash
/* 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);
}
예제 #21
0
파일: xbmc.c 프로젝트: knudje/pilight
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;
}
예제 #22
0
파일: control.c 프로젝트: Johan-M/pilight
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;
}
예제 #23
0
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;
}
예제 #24
0
파일: receive.c 프로젝트: knudje/pilight
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;
}
예제 #25
0
파일: ds18s20.c 프로젝트: Lyve1981/pilight
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;
}
예제 #26
0
파일: program.c 프로젝트: knudje/pilight
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;
}
예제 #27
0
파일: relay.c 프로젝트: Lyve1981/pilight
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;
}
예제 #28
0
파일: program.c 프로젝트: knudje/pilight
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;
}
예제 #29
0
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;
}