X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=cochran.c;h=933e1de1fcac5f95b36498d76693a62b1db525e1;hb=77a903a6bb26d60e1736f7d5c118b598916b37f2;hp=907dc765aa03cd9944252cd559457acffa09424c;hpb=b1a747f537d1df8b9ea9f4caf55e568dd4c3a733;p=ext%2Fsubsurface.git diff --git a/cochran.c b/cochran.c index 907dc76..933e1de 100644 --- a/cochran.c +++ b/cochran.c @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -7,6 +8,8 @@ #include "dive.h" #include "file.h" +#define DON + /* * The Cochran file format is designed to be annoying to read. It's roughly: * @@ -76,24 +79,146 @@ static int figure_out_modulus(const unsigned char *decode, const unsigned char * return best; } -static void cochran_debug_write(int dive, const unsigned char *data, unsigned size) +#define hexchar(n) ("0123456789abcdef"[(n)&15]) + +static int show_line(unsigned offset, const unsigned char *data, unsigned size, int show_empty) { - char buffer[60]; - int fd; - - snprintf(buffer, sizeof(buffer), "cochran.%d.out", dive); - fd = open(buffer, O_CREAT | O_TRUNC | O_WRONLY, 0666); - if (fd >= 0) { - write(fd, data, size); - close(fd); + unsigned char bits; + int i, off; + char buffer[120]; + + if (size > 16) + size = 16; + + bits = 0; + memset(buffer, ' ', sizeof(buffer)); + off = sprintf(buffer, "%06x ", offset); + for (i = 0; i < size; i++) { + char *hex = buffer + off + 3*i; + char *asc = buffer + off + 50 + i; + unsigned char byte = data[i]; + + hex[0] = hexchar(byte>>4); + hex[1] = hexchar(byte); + bits |= byte; + if (byte < 32 || byte > 126) + byte = '.'; + asc[0] = byte; + asc[1] = 0; } + + if (bits) { + puts(buffer); + return 1; + } + if (show_empty) + puts("..."); + return 0; +} + +static void cochran_debug_write(const char *filename, const unsigned char *data, unsigned size) +{ + int i, show = 1; + + for (i = 0; i < size; i += 16) + show = show_line(i, data + i, size - i, show); } -static void parse_cochran_dive(int dive, const unsigned char *decode, unsigned mod, +static void parse_cochran_header(const char *filename, + const unsigned char *decode, unsigned mod, const unsigned char *in, unsigned size) { char *buf = malloc(size); + /* Do the "null decode" using a one-byte decode array of '\0' */ + partial_decode(0 , 0x0b14, "", 0, 1, in, size, buf); + + /* + * The header scrambling is different form the dive + * scrambling. Oh yay! + */ + partial_decode(0x010e, 0x0b14, decode, 0, mod, in, size, buf); + partial_decode(0x0b14, 0x1b14, decode, 0, mod, in, size, buf); + partial_decode(0x1b14, 0x2b14, decode, 0, mod, in, size, buf); + partial_decode(0x2b14, 0x3b14, decode, 0, mod, in, size, buf); + partial_decode(0x3b14, 0x5414, decode, 0, mod, in, size, buf); + partial_decode(0x5414, size, decode, 0, mod, in, size, buf); + + printf("\n%s, header\n\n", filename); + cochran_debug_write(filename, buf, size); + + free(buf); +} + +/* + * Cochran export files show that depths seem to be in + * quarter feet (rounded up to tenths). + * + * Temperature seems to be exported in Fahrenheit. + * + * Cylinder pressure seems to be in multiples of 4 psi. + * + * The data seems to be some byte-stream where the pattern + * appears to be that the two high bits indicate type of + * data. + * + * For '00', the low six bits seem to be positive + * values with a distribution towards zero, probably depth + * deltas. '0 0' exists, but is very rare ("surface"?). 63 + * exists, but is rare. + * + * For '01', the low six bits seem to be a signed binary value, + * with the most common being 0, and 1 and -1 (63) being the + * next most common values. + * + * NOTE! Don's CAN data is different. It shows the reverse pattern + * for 00 and 01 above: 00 looks like signed data, with 01 looking + * like unsigned data. + * + * For '10', there seems to be another positive value distribution, + * but unlike '00' the value 0 is common, and I see examples of 63 + * too ("overflow"?) and a spike at '7'. + * + * Again, Don's data is different. + * + * The values for '11' seem to be some exception case. Possibly + * overflow handling, possibly warning events. It doesn't have + * any clear distribution: values 0, 1, 16, 33, 35, 48, 51, 55 + * and 63 are common. + * + * For David and Don's data, '01' is the most common, with '00' + * and '10' not uncommon. '11' is two orders of magnitude less + * common. + * + * For Alex, '00' is the most common, with 01 about a third as + * common, and 02 a third of that. 11 is least common. + * + * There clearly are variations in the format here. And Alex has + * a different data offset than Don/David too (see the #ifdef DON). + * Christ. Maybe I've misread the patterns entirely. + */ +static void cochran_profile_write(const unsigned char *buf, int size) +{ + int i; + + for (i = 0; i < size; i++) { + unsigned char c = buf[i]; + printf("%d %d\n", + c >> 6, c & 0x3f); + } +} + +static void parse_cochran_dive(const char *filename, int dive, + const unsigned char *decode, unsigned mod, + const unsigned char *in, unsigned size) +{ + char *buf = malloc(size); +#ifdef DON + unsigned int offset = 0x4a14; +#else + unsigned int offset = 0x4b14; +#endif + /* * The scrambling has odd boundaries. I think the boundaries * match some data structure size, but I don't know. They were @@ -115,9 +240,12 @@ static void parse_cochran_dive(int dive, const unsigned char *decode, unsigned m * scrambled, but there seems to be size differences in the data, * so this just descrambles part of it: */ - partial_decode(0x48ff, size, decode, 0, mod, in, size, buf); + partial_decode(0x48ff, offset, decode, 0, mod, in, size, buf); + partial_decode(offset, size, decode, 0, mod, in, size, buf); - cochran_debug_write(dive, buf, size); + printf("\n%s, dive %d\n\n", filename, dive); + cochran_debug_write(filename, buf, size); + cochran_profile_write(buf + offset, size - offset); free(buf); } @@ -139,6 +267,8 @@ int try_to_open_cochran(const char *filename, struct memblock *mem, GError **err mod = figure_out_modulus(decode, mem->buffer + dive1, dive2 - dive1); + parse_cochran_header(filename, decode, mod, mem->buffer + 0x40000, dive1 - 0x40000); + for (i = 0; i < 65534; i++) { dive1 = offsets[i]; dive2 = offsets[i+1]; @@ -146,8 +276,8 @@ int try_to_open_cochran(const char *filename, struct memblock *mem, GError **err break; if (dive2 > mem->size) break; - parse_cochran_dive(i, decode, mod, mem->buffer + dive1, dive2 - dive1); + parse_cochran_dive(filename, i+1, decode, mod, mem->buffer + dive1, dive2 - dive1); } - return 1; + exit(0); }