TeleStern/ao-tools/lib/ao-eeprom-read.c

259 lines
7.2 KiB
C

/*
* 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;
}
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;
}
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)-1);
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_eeprom_get_pyro(config, obj))
return 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);
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;
}