wifidmm/tools/frame-parser.c

151 lines
4.6 KiB
C

#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <math.h>
struct packet_s {
char range;
char digits[5];
char function;
char status;
char options[4];
char eol[2];
};
enum unit_e {
U_UNKNOWN = 0,
U_VOLTAGE,
U_CURRENT,
U_RESISTANCE,
U_FREQUENCY,
U_CAPACITANCE,
U_ADP // ???
};
struct range_entry_s {
uint8_t divider; // Where to place the decimal point
int8_t exponent; // 0->Unit 3->KUnit 6->MUnit -3->mUnit -6->uUnit ...
};
char *units[] = { "?", "V", "A", "Ohm", "Hz", "F", "?" };
enum unit_e function_unit[] = {
U_CURRENT, // 22A
U_VOLTAGE, // Diode
U_FREQUENCY,
U_RESISTANCE,
U_UNKNOWN, // Temperature
U_RESISTANCE, // Continuity
U_CAPACITANCE,
U_UNKNOWN,
U_UNKNOWN,
U_CURRENT, // Manual current
U_UNKNOWN,
U_VOLTAGE,
U_UNKNOWN,
U_CURRENT, // Auto uA
U_UNKNOWN, // ADP
U_CURRENT // Auto mA
};
struct range_entry_s ranges[8][16] = {
// 22A Diode Freq Resist Temp Cont Capac ? ? Man A ? V ? Auto uA ADP Auto mA
{ { 3, 0 }, { 4, 0 }, { 2, 0 }, { 2, 0 }, { 0, 0 }, { 2, 0 }, { 3, -9}, { 0, 0 }, { 0, 0 }, { 4, 0 }, { 0, 0 }, { 4, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 } },
{ { 0, 0 }, { 0, 0 }, { 1, 0 }, { 4, 3 }, { 0, 0 }, { 0, 0 }, { 2, -9}, { 0, 0 }, { 0, 0 }, { 3, 0 }, { 0, 0 }, { 3, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 } },
{ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 3, 3 }, { 0, 0 }, { 0, 0 }, { 4, -6}, { 0, 0 }, { 0, 0 }, { 2, 0 }, { 0, 0 }, { 2, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 } },
{ { 0, 0 }, { 0, 0 }, { 3, 3 }, { 2, 3 }, { 0, 0 }, { 0, 0 }, { 3, -6}, { 0, 0 }, { 0, 0 }, { 1, 0 }, { 0, 0 }, { 1, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 } },
{ { 0, 0 }, { 0, 0 }, { 2, 3 }, { 4, 6 }, { 0, 0 }, { 0, 0 }, { 2, -6}, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 2, -3}, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 } },
{ { 0, 0 }, { 0, 0 }, { 4, 6 }, { 3, 6 }, { 0, 0 }, { 0, 0 }, { 4, -3}, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 } },
{ { 0, 0 }, { 0, 0 }, { 3, 6 }, { 2, 6 }, { 0, 0 }, { 0, 0 }, { 3, -3}, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 } },
{ { 0, 0 }, { 0, 0 }, { 2, 6 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 2, -3}, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 } }
};
int parse_packet(struct packet_s *packet) {
int32_t number;
double reading;
int i;
int range, function;
struct range_entry_s re;
for (number = 0, i = 0; i < sizeof(packet->digits); i++) {
number *= 10;
number += packet->digits[i] & 0x0f;
}
printf("%6d <- %s", number, (char *)packet);
range = packet->range & 0x07;
function = packet->function & 0x0f;
re = ranges[range][function];
if ((re.divider == 0) && (re.exponent == 0)) {
printf("Invalid function/range combo: f=%x r=%x\n", function, range);
}
reading = number * pow(10.0, re.exponent - re.divider);
printf("Reading = %lf %s\n", reading, units[function_unit[function]]);
return 0;
}
void log_packet(struct packet_s *packet) {
int i;
char *c = (char *)packet;
for (i=0; i<sizeof(*packet); i++)
putc(c[i], stderr);
}
int read_packet(struct packet_s *packet) {
char ring[sizeof(*packet)];
char *p;
int ring_pos;
char c;
int ch;
int shift;
p = (char *)packet;
ring_pos = 0;
shift = sizeof(*packet);
for (;;) {
ch = getc(stdin);
if (ch == EOF)
return 0;
c = (char) ch;
ring[ring_pos] = c;
ring_pos = (ring_pos + 1) % sizeof(*packet);
if (((c & 0xf0) != 0x30) && (c != '\r') && (c != '\n')) {
shift = sizeof(*packet);
} else {
if ((c == '\r') && (shift != 2)) {
shift = sizeof(*packet);
continue;
}
if (c == '\n') {
if (shift == 1) {
for (int i=0; i<sizeof(ring); i++)
p[i] = ring[(ring_pos + i) % sizeof(*packet)];
log_packet(packet);
return 1;
}
shift = sizeof(*packet);
continue;
}
shift = (shift > 0) ? shift - 1 : 0;
}
}
}
int main() {
struct packet_s packet;
while (read_packet(&packet)) {
parse_packet(&packet);
}
return EXIT_SUCCESS;
}