diff options
Diffstat (limited to 'src/test/ao_eeprom_read.c')
| -rw-r--r-- | src/test/ao_eeprom_read.c | 262 | 
1 files changed, 262 insertions, 0 deletions
diff --git a/src/test/ao_eeprom_read.c b/src/test/ao_eeprom_read.c new file mode 100644 index 00000000..803ef36c --- /dev/null +++ b/src/test/ao_eeprom_read.c @@ -0,0 +1,262 @@ +/* + * Copyright © 2017 Keith Packard <keithp@keithp.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * General Public License for more details. + */ + +#include "ao_eeprom_read.h" +#include <json-c/json.h> +#include <string.h> +#include <errno.h> + +static struct json_object * +ao_eeprom_read_config(FILE *file) +{ +	char			line[1024]; +	struct json_tokener	*tok; +	struct json_object	*obj = NULL; +	enum json_tokener_error	err; + +	tok = json_tokener_new(); +	if (!tok) +		goto fail_tok; + +	for (;;) { +		if (fgets(line, sizeof(line), file) == NULL) +			goto fail_read; +		obj = json_tokener_parse_ex(tok, line, strlen(line)); +		err = json_tokener_get_error(tok); +		if (err == json_tokener_success) +			break; +		if (err != json_tokener_continue) +			goto fail_read; +	} +	json_tokener_free(tok); +	return obj; +fail_read: +	json_tokener_free(tok); +fail_tok: +	return NULL; +} + +static int +ao_eeprom_read_byte(FILE *file) +{ +	int	byte; +	if (fscanf(file, "%x", &byte) != 1) +		return EOF; +	return byte; +} + +static int +ao_eeprom_read_data(FILE *file, struct ao_eeprom *eeprom) +{ +	uint8_t	*data = NULL, *ndata; +	int	len = 0; +	int	size = 0; +	int	byte; + +	data = malloc(size = 64); +	if (!data) +		goto fail_alloc; +	while ((byte = ao_eeprom_read_byte(file)) != EOF) { +		if (len == size) { +			ndata = realloc(data, size *= 2); +			if (!ndata) +				goto fail_realloc; +			data = ndata; +		} +		data[len++] = (uint8_t) byte; +	} +	eeprom->data = data; +	eeprom->len = len; +	return 1; +fail_realloc: +	free(data); +fail_alloc: +	return 0; +} + +static int +ao_json_get_int(struct json_object *obj, const char *key, int def) +{ +	struct json_object *value; +	int i; + +	if (!json_object_object_get_ex(obj, key, &value)) +		return def; +	errno = 0; +	i = (int) json_object_get_int(value); +	if (errno != 0) +		return def; +	return i; +} + +static const char * +ao_json_get_string(struct json_object *obj, const char *key, const char *def) +{ +	struct json_object *value; +	const char *str; + +	if (!json_object_object_get_ex(obj, key, &value)) +		return def; +	errno = 0; +	str = json_object_get_string(value); +	if (errno) +		return def; +	if (!str) +		return def; +	return str; +} + +#if AO_PYRO_NUM +static int +ao_eeprom_get_pyro(struct ao_config *config, struct json_object *obj) +{ +	struct json_object	*pyros; +	struct json_object	*pyro; +	int			i, p; + +	if (!json_object_object_get_ex(obj, "pyros", &pyros)) +		return 1; + +	if (json_object_get_type(pyros) != json_type_array) +		return 0; + +	for (i = 0; i < json_object_array_length(pyros); i++) { +		pyro = json_object_array_get_idx(pyros, i); +		if (pyro) { +			p = ao_json_get_int(pyro, "channel", -1); +			if (0 <= p && p < AO_PYRO_NUM) { +				config->pyro[p].flags		= ao_json_get_int(pyro, "flags", 0); +				config->pyro[p].accel_less	= ao_json_get_int(pyro, "accel_less", 0); +				config->pyro[p].accel_greater	= ao_json_get_int(pyro, "accel_greater", 0); +				config->pyro[p].speed_less	= ao_json_get_int(pyro, "speed_less", 0); +				config->pyro[p].speed_greater	= ao_json_get_int(pyro, "speed_greater", 0); +				config->pyro[p].height_less	= ao_json_get_int(pyro, "height_less", 0); +				config->pyro[p].height_greater	= ao_json_get_int(pyro, "height_greater", 0); +				config->pyro[p].orient_less	= ao_json_get_int(pyro, "orient_less", 0); +				config->pyro[p].orient_greater	= ao_json_get_int(pyro, "orient_greater", 0); +				config->pyro[p].time_less	= ao_json_get_int(pyro, "time_less", 0); +				config->pyro[p].time_greater	= ao_json_get_int(pyro, "time_greater", 0); +				config->pyro[p].delay		= ao_json_get_int(pyro, "delay", 0); +				config->pyro[p].state_less	= ao_json_get_int(pyro, "state_less", 0); +				config->pyro[p].state_greater_or_equal	= ao_json_get_int(pyro, "state_greater_or_equal", 0); +				config->pyro[p].motor		= ao_json_get_int(pyro, "motor", 0); +			} +		} +	} +	return 1; +} +#endif + +static int +ao_eeprom_get_ms5607(struct ao_ms5607_prom *ms5607_prom, struct json_object *obj) +{ +	struct json_object	*ms5607; + +	if (!json_object_object_get_ex(obj, "ms5607", &ms5607)) +		return 1; + +	if (json_object_get_type(ms5607) != json_type_object) +		return 0; + +	ms5607_prom->reserved =	ao_json_get_int(ms5607, "reserved", 0); +	ms5607_prom->sens =	ao_json_get_int(ms5607, "sens", 0); +	ms5607_prom->off =	ao_json_get_int(ms5607, "off", 0); +	ms5607_prom->tcs =	ao_json_get_int(ms5607, "tcs", 0); +	ms5607_prom->tco =	ao_json_get_int(ms5607, "tco", 0); +	ms5607_prom->tref =	ao_json_get_int(ms5607, "tref", 0); +	ms5607_prom->tempsens =	ao_json_get_int(ms5607, "tempsens", 0); +	ms5607_prom->crc =	ao_json_get_int(ms5607, "crc", 0); +	return 1; +} + +static int +ao_eeprom_get_config(struct ao_eeprom *ao_eeprom, struct json_object *obj) +{ +	struct ao_config	*config = &ao_eeprom->config; +	const char		*s; + +	if (json_object_get_type(obj) != json_type_object) +		return 0; + +	ao_eeprom->log_format = 	ao_json_get_int(obj, "log_format", 0); +	ao_eeprom->serial_number =	ao_json_get_int(obj, "serial", 0); + +	config->major =			ao_json_get_int(obj, "config_major", 0); +	config->minor = 		ao_json_get_int(obj, "config_minor", 0); +	if (config->major == 0 || config->minor == 0) +		return 0; + +	config->main_deploy = 		ao_json_get_int(obj, "main_deploy", 250); +	config->accel_plus_g = 		ao_json_get_int(obj, "accel_cal_plus", 0); + +	s = ao_json_get_string(obj, "callsign", "N0CALL"); +	strncpy(config->callsign, s, sizeof(config->callsign)); + +	config->apogee_delay =		ao_json_get_int(obj, "apogee_delay", 0); +	config->accel_minus_g =		ao_json_get_int(obj, "accel_cal_minus", 0); +	config->radio_cal =		ao_json_get_int(obj, "radio_calibration", 0); +	config->flight_log_max =	ao_json_get_int(obj, "flight_log_max", 0); +	config->ignite_mode = 		ao_json_get_int(obj, "ignite_mode", 0); +	config->pad_orientation = 	ao_json_get_int(obj, "pad_orientation", 0); +	config->radio_setting = 	ao_json_get_int(obj, "radio_setting", 0); +	config->radio_enable = 		ao_json_get_int(obj, "radio_enable", 1); +	config->frequency = 		ao_json_get_int(obj, "frequency", 434550); +	config->apogee_lockout = 	ao_json_get_int(obj, "apogee_lockout", 0); +#if AO_PYRO_NUM +	if (!ao_eeprom_get_pyro(config, obj)) +		return 0; +#endif +	config->ignite_mode = 		ao_json_get_int(obj, "ignite_mode", 0); +	config->ignite_mode = 		ao_json_get_int(obj, "ignite_mode", 0); +	config->ignite_mode = 		ao_json_get_int(obj, "ignite_mode", 0); +	config->ignite_mode = 		ao_json_get_int(obj, "ignite_mode", 0); +	config->ignite_mode = 		ao_json_get_int(obj, "ignite_mode", 0); +	config->ignite_mode = 		ao_json_get_int(obj, "ignite_mode", 0); + +	if (!ao_eeprom_get_ms5607(&ao_eeprom->ms5607_prom, obj)) +		return 0; + +	return 1; +} + +struct ao_eeprom * +ao_eeprom_read(FILE *file) +{ +	struct ao_eeprom	*ao_eeprom; +	struct json_object	*obj; +	int			ret; + +	ao_eeprom = calloc(1, sizeof (struct ao_eeprom)); +	if (!ao_eeprom) +		goto fail_ao_eeprom; + +	obj = ao_eeprom_read_config(file); +	if (!obj) +		goto fail_config; + +	ret = ao_eeprom_get_config(ao_eeprom, obj); +	json_object_put(obj); +	if (!ret) +		goto fail_config; + +	if (!ao_eeprom_read_data(file, ao_eeprom)) +		goto fail_data; + +	return ao_eeprom; +fail_data: +fail_config: +	free(ao_eeprom); +fail_ao_eeprom: +	return NULL; +}  | 
