wifidmm/tools/frame-parser.c

127 lines
4.0 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];
char eos;
};
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;
}
int read_packet(struct packet_s *packet) {
char *r;
int i;
int valid;
while (1) {
r = fgets((char *)packet, sizeof(*packet), stdin);
if (r == NULL)
return 0;
// Sanity checks
// Packet must end with CR+LF
if (packet->eol[0] != '\r' || packet->eol[1] != '\n')
continue;
// All fields must be encoded as 0x3X
for (valid=1, i=0; i<sizeof(*packet)-4; i++)
if ((r[i] & 0xf0) != 0x30)
valid = 0;
// Should also check for valid BCD values for digits
if (valid)
return 1;
}
}
int main() {
struct packet_s packet;
while (read_packet(&packet)) {
parse_packet(&packet);
}
return EXIT_SUCCESS;
}