Просмотр исходного кода

Conversion to field set: WIP 2.

antirez 3 лет назад
Родитель
Сommit
2a053c1493

+ 4 - 4
app.h

@@ -165,7 +165,7 @@ struct ProtoViewApp {
 #define PROTOVIEW_MSG_STR_LEN 32
 typedef struct ProtoViewMsgInfo {
     ProtoViewDecoder *decoder;  /* The decoder that decoded the message. */
-    ProtoViewFieldSet *fields;  /* Decoded fields. */
+    ProtoViewFieldSet *fieldset; /* Decoded fields. */
     /* Low level information of the detected signal: the following are filled
      * by the protocol decoding function: */
     uint32_t start_off;         /* Pulses start offset in the bitmap. */
@@ -188,7 +188,7 @@ typedef enum {
     FieldTypeSignedInt,
     FieldTypeUnsignedInt,
     FieldTypeBinary,
-    FiledTypeHex,
+    FieldTypeHex,
     FieldTypeBytes,
     FieldTypeFloat,
 } ProtoViewFieldType;
@@ -286,7 +286,7 @@ void ui_draw_alert_if_needed(Canvas *canvas, ProtoViewApp *app);
 void canvas_draw_str_with_border(Canvas* canvas, uint8_t x, uint8_t y, const char* str, Color text_color, Color border_color);
 
 /* fields.c */
-void fieldset_free_set(ProtoViewFieldSet *fs);
+void fieldset_free(ProtoViewFieldSet *fs);
 ProtoViewFieldSet *fieldset_new(void);
 void fieldset_add_int(ProtoViewFieldSet *fs, const char *name, int64_t val, uint8_t bits);
 void fieldset_add_uint(ProtoViewFieldSet *fs, const char *name, uint64_t uval, uint8_t bits);
@@ -294,7 +294,7 @@ void fieldset_add_hex(ProtoViewFieldSet *fs, const char *name, uint64_t uval, ui
 void fieldset_add_bin(ProtoViewFieldSet *fs, const char *name, uint64_t uval, uint8_t bits);
 void fieldset_add_str(ProtoViewFieldSet *fs, const char *name, const char *s);
 void fieldset_add_bytes(ProtoViewFieldSet *fs, const char *name, const uint8_t *bytes, uint32_t count);
-void fieldset_add_float(ProtoViewFieldSet *fs, const char *name, float val);
+void fieldset_add_float(ProtoViewFieldSet *fs, const char *name, float val, uint32_t digits_after_dot);
 
 /* crc.c */
 uint8_t crc8(const uint8_t *data, size_t len, uint8_t init, uint8_t poly);

+ 3 - 3
fields.c

@@ -26,7 +26,7 @@ static void field_free(ProtoViewField *f) {
 }
 
 /* Free a field set and its contained fields. */
-void fieldset_free_set(ProtoViewFieldSet *fs) {
+void fieldset_free(ProtoViewFieldSet *fs) {
     for (uint32_t j = 0; j < fs->numfields; j++)
         field_free(fs->fields[j]);
     free(fs->fields);
@@ -101,9 +101,9 @@ void fieldset_add_bytes(ProtoViewFieldSet *fs, const char *name, const uint8_t *
 }
 
 /* Allocate and append a float field. */
-void fieldset_add_float(ProtoViewFieldSet *fs, const char *name, float val) {
+void fieldset_add_float(ProtoViewFieldSet *fs, const char *name, float val, uint32_t digits_after_dot) {
     ProtoViewField *f = field_new(FieldTypeFloat,name);
     f->fvalue = val;
-    f->len = 0; // Not used for floats
+    f->len = digits_after_dot;
     fieldset_add_field(fs,f);
 }

+ 2 - 2
protocols/b4b1.c

@@ -41,8 +41,8 @@ static bool decode(uint8_t *bits, uint32_t numbytes, uint32_t numbits, ProtoView
     off++; // In this protocol there is a final pulse as terminator.
     info->pulses_count = off - info->start_off;
 
-    fieldset_add_bytes(info->fields,"id",d,5);
-    fieldset_add_int(info->fields,"button",d[2]&0xf,4);
+    fieldset_add_bytes(info->fieldset,"id",d,5);
+    fieldset_add_int(info->fieldset,"button",d[2]&0xf,4);
     return true;
 }
 

+ 5 - 5
protocols/keeloq.c

@@ -67,11 +67,11 @@ static bool decode(uint8_t *bits, uint32_t numbytes, uint32_t numbits, ProtoView
                      (raw[4] << 0);
     int lowbat = (raw[8]&0x80) != 0;
 
-    fieldset_add_bytes(info->fields,"raw",raw,9*2);
-    fieldset_add_bytes(info->fields,"encr",raw,4*2);
-    fieldset_add_hex(info->fields,"id",remote_id,28);
-    fieldset_add_bin(info->fields,"s2|s1|s0|s3",buttons,4);
-    fieldset_add_bin(info->fields,"low battery",lowbat,1);
+    fieldset_add_bytes(info->fieldset,"raw",raw,9*2);
+    fieldset_add_bytes(info->fieldset,"encr",raw,4*2);
+    fieldset_add_hex(info->fieldset,"id",remote_id,28);
+    fieldset_add_bin(info->fieldset,"s2 s1 s0 s3",buttons,4);
+    fieldset_add_bin(info->fieldset,"low battery",lowbat,1);
     return true;
 }
 

+ 5 - 4
protocols/oregon2.c

@@ -24,7 +24,8 @@ static bool decode(uint8_t *bits, uint32_t numbytes, uint32_t numbits, ProtoView
     if (decoded < 11*4) return false; /* Minimum len to extract some data. */
     info->pulses_count = (off+11*4*4) - info->start_off;
 
-    char temp[3] = {0}, deviceid[2] = {0}, hum[2] = {0};
+    char temp[3] = {0}, hum[2] = {0};
+    uint8_t deviceid[2];
     for (int j = 0; j < 64; j += 4) {
         uint8_t nib[1];
         nib[0] = (bitmap_get(buffer,8,j+0) |
@@ -52,9 +53,9 @@ static bool decode(uint8_t *bits, uint32_t numbytes, uint32_t numbits, ProtoView
                     ((float)(temp[2]-'0')*0.1);
     int humval = (hum[0]-'0')*10 + (hum[1]-'0');
 
-    fieldset_add_bytes(info->fields,"Sensor ID",deviceid,4);
-    fieldset_add_float(info->fields,"Temperature",tempval,1);
-    fieldset_add_uint(info->fields,"Humidity",humval,7);
+    fieldset_add_bytes(info->fieldset,"Sensor ID",deviceid,4);
+    fieldset_add_float(info->fieldset,"Temperature",tempval,1);
+    fieldset_add_uint(info->fieldset,"Humidity",humval,7);
     return true;
 }
 

+ 5 - 12
protocols/tpms/citroen.c

@@ -45,18 +45,11 @@ static bool decode(uint8_t *bits, uint32_t numbytes, uint32_t numbits, ProtoView
     int temp = raw[7]-50;
     int battery = raw[8]; /* This may be the battery. It's not clear. */
 
-#if 0
-    snprintf(info->name,sizeof(info->name),"%s","Citroen TPMS");
-    snprintf(info->raw,sizeof(info->raw),
-        "%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X",
-        raw[0],raw[1],raw[2],raw[3],raw[4],raw[5],
-        raw[6],raw[7],raw[8],raw[9]);
-    snprintf(info->info1,sizeof(info->info1),"Tire ID %02X%02X%02X%02X",
-        raw[1],raw[2],raw[3],raw[4]);
-    snprintf(info->info2,sizeof(info->info2),"Pressure %.2f kpa", (double)kpa);
-    snprintf(info->info3,sizeof(info->info3),"Temperature %d C", temp);
-    snprintf(info->info4,sizeof(info->info4),"Repeat %d, Bat %d", repeat, battery);
-#endif
+    fieldset_add_bytes(info->fieldset,"Tire ID",raw+1,4*2);
+    fieldset_add_float(info->fieldset,"Pressure kpa",kpa,2);
+    fieldset_add_int(info->fieldset,"Temperature C",temp,8);
+    fieldset_add_uint(info->fieldset,"Repeat",repeat,4);
+    fieldset_add_uint(info->fieldset,"Battery",battery,8);
     return true;
 }
 

+ 5 - 14
protocols/tpms/ford.c

@@ -47,20 +47,11 @@ static bool decode(uint8_t *bits, uint32_t numbytes, uint32_t numbits, ProtoView
     int flags = raw[5] & 0x7f;
     int car_moving = (raw[6] & 0x44) == 0x44;
 
-#if 0
-    snprintf(info->name,sizeof(info->name),"%s","Ford TPMS");
-    snprintf(info->raw,sizeof(info->raw),"%02X%02X%02X%02X%02X%02X%02X%02X",
-        raw[0],raw[1],raw[2],raw[3],raw[4],raw[5],
-        raw[6],raw[7]);
-    snprintf(info->info1,sizeof(info->info1),"Tire ID %02X%02X%02X%02X",
-        raw[0],raw[1],raw[2],raw[3]);
-    snprintf(info->info2,sizeof(info->info2),"Pressure %.2f psi", (double)psi);
-    if (temp)
-        snprintf(info->info3,sizeof(info->info3),"Temperature %d C", temp);
-    else
-        snprintf(info->info3,sizeof(info->info3),"Flags %d", flags);
-    snprintf(info->info4,sizeof(info->info4),"Moving %s", car_moving ? "yes" : "no");
-#endif
+    fieldset_add_bytes(info->fieldset,"Tire ID",raw,4*2);
+    fieldset_add_float(info->fieldset,"Pressure psi",psi,2);
+    fieldset_add_int(info->fieldset,"Temperature C",temp,8);
+    fieldset_add_hex(info->fieldset,"Flags",flags,7);
+    fieldset_add_uint(info->fieldset,"Moving",car_moving,1);
     return true;
 }
 

+ 3 - 10
protocols/tpms/renault.c

@@ -53,16 +53,9 @@ static bool decode(uint8_t *bits, uint32_t numbytes, uint32_t numbits, ProtoView
     float kpa = 0.75 *((uint32_t)((raw[0]&3)<<8) | raw[1]);
     int temp = raw[2]-30;
 
-#if 0
-    snprintf(info->name,sizeof(info->name),"%s","Renault TPMS");
-    snprintf(info->raw,sizeof(info->raw),"%02X%02X%02X%02X%02X%02X%02X%02X%02X",
-        raw[0],raw[1],raw[2],raw[3],raw[4],raw[5],
-        raw[6],raw[7],raw[8]);
-    snprintf(info->info1,sizeof(info->info1),"Tire ID %02X%02X%02X",
-        raw[3],raw[4],raw[5]);
-    snprintf(info->info2,sizeof(info->info2),"Pressure %.2f kpa", (double)kpa);
-    snprintf(info->info3,sizeof(info->info3),"Temperature %d C", temp);
-#endif
+    fieldset_add_bytes(info->fieldset,"Tire ID",raw+3,3*2);
+    fieldset_add_float(info->fieldset,"Pressure kpa",kpa,2);
+    fieldset_add_int(info->fieldset,"Temperature C",temp,8);
     return true;
 }
 

+ 8 - 10
protocols/tpms/schrader.c

@@ -33,6 +33,7 @@ static bool decode(uint8_t *bits, uint32_t numbytes, uint32_t numbits, ProtoView
                   0011 = 0x3. */
 
     uint8_t raw[8];
+    uint8_t id[4];
     uint32_t decoded =
         convert_from_line_code(raw,sizeof(raw),bits,numbytes,off,
             "01","10"); /* Manchester code. */
@@ -51,17 +52,14 @@ static bool decode(uint8_t *bits, uint32_t numbytes, uint32_t numbits, ProtoView
 
     float kpa = (float)raw[5]*2.5;
     int temp = raw[6]-50;
+    id[0] = raw[1]&7;
+    id[1] = raw[2];
+    id[2] = raw[3];
+    id[3] = raw[4];
 
-#if 0
-    snprintf(info->name,sizeof(info->name),"%s","Schrader TPMS");
-    snprintf(info->raw,sizeof(info->raw),"%02X%02X%02X%02X%02X%02X%02X%02X",
-        raw[0],raw[1],raw[2],raw[3],raw[4],raw[5],
-        raw[6],raw[7]);
-    snprintf(info->info1,sizeof(info->info1),"Tire ID %01X%02X%02X%02X",
-        raw[1]&7,raw[2],raw[3],raw[4]); /* Only 28 bits of ID, not 32. */
-    snprintf(info->info2,sizeof(info->info2),"Pressure %.2f kpa", (double)kpa);
-    snprintf(info->info3,sizeof(info->info3),"Temperature %d C", temp);
-#endif
+    fieldset_add_bytes(info->fieldset,"Tire ID",id,4*2);
+    fieldset_add_float(info->fieldset,"Pressure kpa",kpa,2);
+    fieldset_add_int(info->fieldset,"Temperature C",temp,8);
     return true;
 }
 

+ 3 - 10
protocols/tpms/schrader_eg53ma4.c

@@ -50,16 +50,9 @@ static bool decode(uint8_t *bits, uint32_t numbytes, uint32_t numbits, ProtoView
     int temp_f = raw[8];
     int temp_c = (temp_f-32)*5/9; /* Convert Fahrenheit to Celsius. */
 
-#if 0
-    snprintf(info->name,sizeof(info->name),"%s","Schrader EG53MA4 TPMS");
-    snprintf(info->raw,sizeof(info->raw),"%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X",
-        raw[0],raw[1],raw[2],raw[3],raw[4],raw[5],
-        raw[6],raw[7],raw[8],raw[9]);
-    snprintf(info->info1,sizeof(info->info1),"Tire ID %02X%02X%02X",
-        raw[4],raw[5],raw[6]); /* Only 28 bits of ID, not 32. */
-    snprintf(info->info2,sizeof(info->info2),"Pressure %.2f kpa", (double)kpa);
-    snprintf(info->info3,sizeof(info->info3),"Temperature %d C", temp_c);
-#endif
+    fieldset_add_bytes(info->fieldset,"Tire ID",raw+4,3*2);
+    fieldset_add_float(info->fieldset,"Pressure kpa",kpa,2);
+    fieldset_add_int(info->fieldset,"Temperature C",temp_c,8);
     return true;
 }
 

+ 4 - 11
protocols/tpms/toyota.c

@@ -72,19 +72,12 @@ static bool decode(uint8_t *bits, uint32_t numbytes, uint32_t numbits, ProtoView
 
     info->pulses_count = (off+8*9*2) - info->start_off;
 
-    float kpa = (float)((raw[4]&0x7f)<<1 | raw[5]>>7) * 0.25 - 7;
+    float psi = (float)((raw[4]&0x7f)<<1 | raw[5]>>7) * 0.25 - 7;
     int temp = ((raw[5]&0x7f)<<1 | raw[6]>>7) - 40;
 
-#if 0
-    snprintf(info->name,sizeof(info->name),"%s","Toyota TPMS");
-    snprintf(info->raw,sizeof(info->raw),"%02X%02X%02X%02X%02X%02X%02X%02X%02X",
-        raw[0],raw[1],raw[2],raw[3],raw[4],raw[5],
-        raw[6],raw[7],raw[8]);
-    snprintf(info->info1,sizeof(info->info1),"Tire ID %02X%02X%02X%02X",
-        raw[0],raw[1],raw[2],raw[3]);
-    snprintf(info->info2,sizeof(info->info2),"Pressure %.2f psi", (double)kpa);
-    snprintf(info->info3,sizeof(info->info3),"Temperature %d C", temp);
-#endif
+    fieldset_add_bytes(info->fieldset,"Tire ID",raw,4*2);
+    fieldset_add_float(info->fieldset,"Pressure psi",psi,2);
+    fieldset_add_int(info->fieldset,"Temperature C",temp,8);
     return true;
 }
 

+ 3 - 5
signal.c

@@ -543,7 +543,7 @@ ProtoViewDecoder *Decoders[] = {
 /* Free the message info and allocated data. */
 void free_msg_info(ProtoViewMsgInfo *i) {
     if (i == NULL) return;
-    fieldset_free(i->fields);
+    fieldset_free(i->fieldset);
     free(i->bits);
     free(i);
 }
@@ -554,7 +554,7 @@ void init_msg_info(ProtoViewMsgInfo *i, ProtoViewApp *app) {
     UNUSED(app);
     memset(i,0,sizeof(ProtoViewMsgInfo));
     i->bits = NULL;
-    i->fields = fieldset_new();
+    i->fieldset = fieldset_new();
 }
 
 /* This function is called when a new signal is detected. It converts it
@@ -604,9 +604,7 @@ bool decode_signal(RawSamplesBuffer *s, uint64_t len, ProtoViewMsgInfo *info) {
     if (!decoded) {
         FURI_LOG_E(TAG, "No decoding possible");
     } else {
-        FURI_LOG_E(TAG, "Decoded %s, raw=%s info=[%s,%s,%s,%s]",
-            info->name, info->raw, info->info1, info->info2,
-            info->info3, info->info4);
+        FURI_LOG_E(TAG, "+++ Decoded %s", info->decoder->name);
         /* The message was correctly decoded: fill the info structure
          * with the decoded signal. The decoder may not implement offset/len
          * filling of the structure. In such case we have no info and

+ 62 - 12
view_info.c

@@ -23,27 +23,77 @@ typedef struct {
     char *filename;
 } InfoViewPrivData;
 
+/* Draw the text label and value of the specified info field at x,y. */
+static void render_info_field(Canvas *const canvas,
+                              ProtoViewField *f, uint8_t x, uint8_t y)
+{
+    char buf[64];
+    canvas_set_font(canvas, FontSecondary);
+    switch(f->type) {
+    case FieldTypeStr:
+        snprintf(buf,sizeof(buf),"%s: %s", f->name, f->str);
+        break;
+    case FieldTypeSignedInt:
+        snprintf(buf,sizeof(buf),"%s: %lld", f->name, (long long) f->value);
+        break;
+    case FieldTypeUnsignedInt:
+        snprintf(buf,sizeof(buf),"%s: %llu", f->name,
+                    (unsigned long long) f->uvalue);
+        break;
+    case FieldTypeBinary:
+        {
+            uint64_t test_bit = (1 << (f->len-1));
+            uint64_t idx = snprintf(buf,sizeof(buf),"%s: ", f->name);
+            while(idx < sizeof(buf)-1 && test_bit) {
+                buf[idx++] = (f->uvalue & test_bit) ? '1' : '0';
+                test_bit >>= 1;
+            }
+            buf[idx] = 0;
+        }
+        break;
+    case FieldTypeHex:
+        snprintf(buf, sizeof(buf), "%s: 0x%*llX", f->name,
+            (int)(f->len+7)/8, f->uvalue);
+        break;
+    case FieldTypeFloat:
+        snprintf(buf, sizeof(buf), "%s: 0x%.*f", f->name,
+            (int)f->len, (double)f->fvalue);
+        break;
+    case FieldTypeBytes:
+        {
+            uint64_t idx = snprintf(buf,sizeof(buf),"%s: ", f->name);
+            uint32_t nibble_num = 0;
+            while(idx < sizeof(buf)-1 && nibble_num < f->len) {
+                const char *charset = "0123456789ABCDEF";
+                uint32_t nibble = nibble_num & 1 ?
+                    (f->bytes[nibble_num/2] >> 4) :
+                    (f->bytes[nibble_num/2] & 0xf);
+                buf[idx++] = charset[nibble];
+                nibble_num++;
+            }
+            buf[idx] = 0;
+        }
+        break;
+    }
+    canvas_draw_str(canvas, x, y, buf);
+}
+
 /* Render the view with the detected message information. */
 static void render_subview_main(Canvas *const canvas, ProtoViewApp *app) {
     /* Protocol name as title. */
     canvas_set_font(canvas, FontPrimary);
     uint8_t y = 8, lineheight = 10;
-    canvas_draw_str(canvas, 0, y, app->msg_info->name);
+    canvas_draw_str(canvas, 0, y, app->msg_info->decoder->name);
     y += lineheight;
 
-    /* Info fields. */
-    char buf[128];
-    canvas_set_font(canvas, FontSecondary);
-    if (app->msg_info->raw[0]) {
-        snprintf(buf,sizeof(buf),"Raw: %s", app->msg_info->raw);
-        canvas_draw_str(canvas, 0, y, buf);
+    /* Draw the info fields. */
+    for (uint32_t j = 0; j < app->msg_info->fieldset->numfields; j++) {
+        render_info_field(canvas,app->msg_info->fieldset->fields[j],0,y);
         y += lineheight;
     }
-    canvas_draw_str(canvas, 0, y, app->msg_info->info1); y += lineheight;
-    canvas_draw_str(canvas, 0, y, app->msg_info->info2); y += lineheight;
-    canvas_draw_str(canvas, 0, y, app->msg_info->info3); y += lineheight;
-    canvas_draw_str(canvas, 0, y, app->msg_info->info4); y += lineheight;
 
+    /* Draw a vertical "save" label. Temporary solution, to switch to
+     * something better ASAP. */
     y = 37;
     lineheight = 7;
     canvas_draw_str(canvas, 119, y, "s"); y += lineheight;
@@ -132,7 +182,7 @@ void str_replace(char *buf, char c1, char c2) {
 void set_signal_random_filename(ProtoViewApp *app, char *buf, size_t buflen) {
     char suffix[6];
     set_random_name(suffix,sizeof(suffix));
-    snprintf(buf,buflen,"%.10s-%s-%d",app->msg_info->name,suffix,rand()%1000);
+    snprintf(buf,buflen,"%.10s-%s-%d",app->msg_info->decoder->name,suffix,rand()%1000);
     str_replace(buf,' ','_');
     str_replace(buf,'-','_');
     str_replace(buf,'/','_');

+ 1 - 1
view_raw_signal.c

@@ -65,7 +65,7 @@ void render_view_raw_pulses(Canvas *const canvas, ProtoViewApp *app) {
     canvas_draw_str_with_border(canvas, 97, 63, buf, ColorWhite, ColorBlack);
     if (app->signal_decoded) {
         canvas_set_font(canvas, FontPrimary);
-        canvas_draw_str_with_border(canvas, 1, 61, app->msg_info->name, ColorWhite, ColorBlack);
+        canvas_draw_str_with_border(canvas, 1, 61, app->msg_info->decoder->name, ColorWhite, ColorBlack);
     }
 }