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

Conversion to field set: WIP 1.

antirez 3 лет назад
Родитель
Сommit
69053858c2

+ 11 - 11
app.h

@@ -34,6 +34,8 @@
 
 typedef struct ProtoViewApp ProtoViewApp;
 typedef struct ProtoViewMsgInfo ProtoViewMsgInfo;
+typedef struct ProtoViewFieldSet ProtoViewFieldSet;
+typedef struct ProtoViewDecoder ProtoViewDecoder;
 
 /* ============================== enumerations ============================== */
 
@@ -162,14 +164,8 @@ struct ProtoViewApp {
  * in the message info view. */
 #define PROTOVIEW_MSG_STR_LEN 32
 typedef struct ProtoViewMsgInfo {
-    char name[PROTOVIEW_MSG_STR_LEN]; /* Protocol name and version. */
-    char raw[PROTOVIEW_MSG_STR_LEN]; /* Protocol specific raw representation.*/
-    /* The following is what the decoder wants to show to user. Each decoder
-     * can use the number of fileds it needs. */
-    char info1[PROTOVIEW_MSG_STR_LEN]; /* Protocol specific info line 1. */
-    char info2[PROTOVIEW_MSG_STR_LEN]; /* Protocol specific info line 2. */
-    char info3[PROTOVIEW_MSG_STR_LEN]; /* Protocol specific info line 3. */
-    char info4[PROTOVIEW_MSG_STR_LEN]; /* Protocol specific info line 4. */
+    ProtoViewDecoder *decoder;  /* The decoder that decoded the message. */
+    ProtoViewFieldSet *fields;  /* 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. */
@@ -191,6 +187,8 @@ typedef enum {
     FieldTypeStr,
     FieldTypeSignedInt,
     FieldTypeUnsignedInt,
+    FieldTypeBinary,
+    FiledTypeHex,
     FieldTypeBytes,
     FieldTypeFloat,
 } ProtoViewFieldType;
@@ -198,10 +196,10 @@ typedef enum {
 typedef struct {
     ProtoViewFieldType type;
     uint32_t len;       // Depends on type:
-                        // Bits for integers.
+                        // Bits for integers (signed,unsigned,binary,hex).
                         // Number of characters for strings.
                         // Number of nibbles for bytes (1 for each 4 bits).
-                        // Not used for floats.
+                        // Number of digits after dot for floats.
     char *name;         // Field name.
     union {
         char *str;          // String type.
@@ -212,7 +210,7 @@ typedef struct {
     };
 } ProtoViewField;
 
-typedef struct {
+typedef struct ProtoViewFieldSet {
     ProtoViewField **fields;
     uint32_t numfields;
 } ProtoViewFieldSet;
@@ -292,6 +290,8 @@ void fieldset_free_set(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);
+void fieldset_add_hex(ProtoViewFieldSet *fs, const char *name, uint64_t uval, uint8_t bits);
+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);

+ 24 - 5
fields.c

@@ -64,6 +64,24 @@ void fieldset_add_uint(ProtoViewFieldSet *fs, const char *name, uint64_t uval, u
     fieldset_add_field(fs,f);
 }
 
+/* Allocate and append a hex field. This is an unsigned number but
+ * with an hex representation. */
+void fieldset_add_hex(ProtoViewFieldSet *fs, const char *name, uint64_t uval, uint8_t bits) {
+    ProtoViewField *f = field_new(FieldTypeHex,name);
+    f->uvalue = uval;
+    f->len = bits;
+    fieldset_add_field(fs,f);
+}
+
+/* Allocate and append a bin field. This is an unsigned number but
+ * with a binary representation. */
+void fieldset_add_bin(ProtoViewFieldSet *fs, const char *name, uint64_t uval, uint8_t bits) {
+    ProtoViewField *f = field_new(FieldTypeBinary,name);
+    f->uvalue = uval;
+    f->len = bits;
+    fieldset_add_field(fs,f);
+}
+
 /* Allocate and append a string field. */
 void fieldset_add_str(ProtoViewFieldSet *fs, const char *name, const char *s) {
     ProtoViewField *f = field_new(FieldTypeStr,name);
@@ -72,12 +90,13 @@ void fieldset_add_str(ProtoViewFieldSet *fs, const char *name, const char *s) {
     fieldset_add_field(fs,f);
 }
 
-/* Allocate and append a bytes field. */
-void fieldset_add_bytes(ProtoViewFieldSet *fs, const char *name, const uint8_t *bytes, uint32_t count) {
+/* Allocate and append a bytes field. Note that 'count' is specified in
+ * nibbles (bytes*2). */
+void fieldset_add_bytes(ProtoViewFieldSet *fs, const char *name, const uint8_t *bytes, uint32_t count_nibbles) {
     ProtoViewField *f = field_new(FieldTypeBytes,name);
-    f->bytes = malloc(count);
-    memcpy(f->bytes,bytes,count);
-    f->len = count;
+    f->bytes = malloc(count_nibbles/2);
+    memcpy(f->bytes,bytes,count_nibbles/2);
+    f->len = count_nibbles;
     fieldset_add_field(fs,f);
 }
 

+ 5 - 4
protocols/b4b1.c

@@ -40,14 +40,15 @@ static bool decode(uint8_t *bits, uint32_t numbytes, uint32_t numbits, ProtoView
     off += 24*4; // seek to end symbol offset to calculate the length.
     off++; // In this protocol there is a final pulse as terminator.
     info->pulses_count = off - info->start_off;
-    snprintf(info->name,PROTOVIEW_MSG_STR_LEN,"PT/SC remote");
-    snprintf(info->raw,PROTOVIEW_MSG_STR_LEN,"%02X%02X%02X",d[0],d[1],d[2]);
+
+    fieldset_add_bytes(info->fields,"id",d,5);
+    fieldset_add_int(info->fields,"button",d[2]&0xf,4);
     return true;
 }
 
 ProtoViewDecoder B4B1Decoder = {
-    .name = "B4B1",
+    .name = "PT/SC remote",
     .decode = decode,
     .get_fields = NULL,
-    .build_message = NULL
+    .build_message = NULL 
 };

+ 6 - 17
protocols/keeloq.c

@@ -61,28 +61,17 @@ static bool decode(uint8_t *bits, uint32_t numbytes, uint32_t numbits, ProtoView
     bitmap_reverse_bytes(raw,sizeof(raw)); /* Keeloq is LSB first. */
 
     int buttons = raw[7]>>4;
-    int s3 = (buttons&1) != 0;
-    int s0 = (buttons&2) != 0;
-    int s1 = (buttons&4) != 0;
-    int s2 = (buttons&8) != 0;
-
     int remote_id = ((raw[7]&0x0f) << 24) |
                      (raw[6] << 16) |
                      (raw[5] << 8) |
                      (raw[4] << 0);
-    int lowbat = raw[8]&0x80;
+    int lowbat = (raw[8]&0x80) != 0;
 
-    snprintf(info->name,sizeof(info->name),"%s","Keeloq remote");
-    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),"Encrpyted %02X%02X%02X%02X",
-        raw[3],raw[2],raw[1],raw[0]);
-    snprintf(info->info2,sizeof(info->info2),"ID %08X", remote_id);
-    snprintf(info->info3,sizeof(info->info3),"s0-s3: %d%d%d%d",
-        s0,s1,s2,s3);
-    snprintf(info->info4,sizeof(info->info4),"Low battery? %s",
-        lowbat ? "yes" : "no");
+    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);
     return true;
 }
 

+ 8 - 12
protocols/oregon2.c

@@ -47,18 +47,14 @@ static bool decode(uint8_t *bits, uint32_t numbytes, uint32_t numbits, ProtoView
         }
     }
 
-    snprintf(info->name,sizeof(info->name),"%s","Oregon v2.1");
-    /* The following line crashes the Flipper because of broken
-     * snprintf() implementation. */
-    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),"Sensor ID %02X%02X",
-        deviceid[0], deviceid[1]);
-    snprintf(info->info2,sizeof(info->info2),"Temperature %d%d.%d",
-        temp[0],temp[1],temp[2]);
-    snprintf(info->info3,sizeof(info->info3),"Humidity %d%d",
-        hum[0],hum[1]);
+    float tempval = ((temp[0]-'0')*10) +
+                     (temp[1]-'0') +
+                    ((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);
     return true;
 }
 

+ 2 - 0
protocols/tpms/citroen.c

@@ -45,6 +45,7 @@ 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",
@@ -55,6 +56,7 @@ static bool decode(uint8_t *bits, uint32_t numbytes, uint32_t numbits, ProtoView
     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
     return true;
 }
 

+ 2 - 0
protocols/tpms/ford.c

@@ -47,6 +47,7 @@ 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],
@@ -59,6 +60,7 @@ static bool decode(uint8_t *bits, uint32_t numbytes, uint32_t numbits, ProtoView
     else
         snprintf(info->info3,sizeof(info->info3),"Flags %d", flags);
     snprintf(info->info4,sizeof(info->info4),"Moving %s", car_moving ? "yes" : "no");
+#endif
     return true;
 }
 

+ 2 - 0
protocols/tpms/renault.c

@@ -53,6 +53,7 @@ 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],
@@ -61,6 +62,7 @@ static bool decode(uint8_t *bits, uint32_t numbytes, uint32_t numbits, ProtoView
         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
     return true;
 }
 

+ 2 - 0
protocols/tpms/schrader.c

@@ -52,6 +52,7 @@ 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;
 
+#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],
@@ -60,6 +61,7 @@ static bool decode(uint8_t *bits, uint32_t numbytes, uint32_t numbits, ProtoView
         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
     return true;
 }
 

+ 2 - 0
protocols/tpms/schrader_eg53ma4.c

@@ -50,6 +50,7 @@ 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],
@@ -58,6 +59,7 @@ static bool decode(uint8_t *bits, uint32_t numbytes, uint32_t numbits, ProtoView
         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
     return true;
 }
 

+ 2 - 0
protocols/tpms/toyota.c

@@ -75,6 +75,7 @@ static bool decode(uint8_t *bits, uint32_t numbytes, uint32_t numbits, ProtoView
     float kpa = (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],
@@ -83,6 +84,7 @@ static bool decode(uint8_t *bits, uint32_t numbytes, uint32_t numbits, ProtoView
         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
     return true;
 }
 

+ 6 - 1
signal.c

@@ -543,6 +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);
     free(i->bits);
     free(i);
 }
@@ -553,6 +554,7 @@ void init_msg_info(ProtoViewMsgInfo *i, ProtoViewApp *app) {
     UNUSED(app);
     memset(i,0,sizeof(ProtoViewMsgInfo));
     i->bits = NULL;
+    i->fields = fieldset_new();
 }
 
 /* This function is called when a new signal is detected. It converts it
@@ -592,7 +594,10 @@ bool decode_signal(RawSamplesBuffer *s, uint64_t len, ProtoViewMsgInfo *info) {
         uint32_t delta = furi_get_tick() - start_time;
         FURI_LOG_E(TAG, "Decoder %s took %lu ms",
             Decoders[j]->name, (unsigned long)delta);
-        if (decoded) break;
+        if (decoded) {
+            info->decoder = Decoders[j];
+            break;
+        }
         j++;
     }