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

Protocol decoding, work in progress 2.

antirez 3 лет назад
Родитель
Сommit
10227a45bc
3 измененных файлов с 78 добавлено и 7 удалено
  1. 2 1
      app.h
  2. 39 0
      protocols/b4b1.c
  3. 37 6
      signal.c

+ 2 - 1
app.h

@@ -102,7 +102,7 @@ typedef struct ProtoViewMsgInfo {
     char info1[16];     /* Protocol specific decoded string, line 1. */
     char info2[16];     /* Protocol specific decoded string, line 2. */
     char info3[16];     /* Protocol specific decoded string, line 3. */
-    uint64_t len;       /* Bits found. */
+    uint64_t len;       /* Bits consumed from the stream. */
 } ProtoViewMsgInfo;
 
 typedef struct ProtoViewDecoder {
@@ -125,6 +125,7 @@ void scan_for_signal(ProtoViewApp *app);
 bool bitmap_get(uint8_t *b, uint32_t blen, uint32_t bitpos);
 bool bitmap_match_bits(uint8_t *b, uint32_t blen, uint32_t bitpos, const char *bits);
 uint32_t bitmap_seek_bits(uint8_t *b, uint32_t blen, uint32_t startpos, const char *bits);
+uint32_t convert_from_line_code(uint8_t *buf, uint64_t buflen, uint8_t *bits, uint32_t len, uint32_t offset, const char *zero_pattern, const char *one_pattern);
 
 /* view_*.c */
 void render_view_raw_pulses(Canvas *const canvas, ProtoViewApp *app);

+ 39 - 0
protocols/b4b1.c

@@ -0,0 +1,39 @@
+/* This line code is used in many remotes such as Princeton chips
+ * named PT<number>, Silian Microelectronics SC5262 and others.
+ * Basically every 4 pulsee represent a bit, where 1000 means 0, and
+ * 1110 means 1. Usually we can read 24 bits of data.
+ * In this specific implementation we check for a prelude that is
+ * 1 bit high, 31 bits low, but the check is relaxed. */
+
+#include "../app.h"
+
+static bool decode(uint8_t *bits, uint64_t numbits, ProtoViewMsgInfo *info) {
+    const char *sync_patterns[3] = {
+        "10000000000000000000000000000001", /* 30 zero bits. */
+        "100000000000000000000000000000001", /* 31 zero bits. */
+        "1000000000000000000000000000000001", /* 32 zero bits. */
+    };
+
+    uint64_t off;
+    int j;
+    for (j = 0; j < 3; j++) {
+        off = bitmap_seek_bits(bits,numbits,0,sync_patterns[j]);
+        if (off != BITMAP_SEEK_NOT_FOUND) break;
+    }
+    if (off == BITMAP_SEEK_NOT_FOUND) return false;
+    off += strlen(sync_patterns[j]);
+
+    uint8_t d[3]; /* 24 bits of data. */
+    uint32_t decoded =
+        convert_from_line_code(d,sizeof(d),bits,numbits,off,"1000","1110");
+
+    if (decoded != 24) return false;
+    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]);
+    info->len = off+(4*24);
+    return true;
+}
+
+ProtoViewDecoder B4B1Decoder = {
+    "B4B1", decode
+};

+ 37 - 6
signal.c

@@ -261,23 +261,46 @@ uint32_t convert_signal_to_bits(uint8_t *b, uint32_t blen, RawSamplesBuffer *s,
  * representation. In such a case I could use "10??" and "01??".
  *
  * The function returns the number of bits converted. It will stop as soon
- * as it finds a pattern that does not match zero or one patterns. */
-#if 0
-uint32_t convert_from_line_code(uint8_t *buf, uint64_t buflen, uint8_t *bits, uint32_t len, const char *zero_pattern, const char *one_pattern)
+ * as it finds a pattern that does not match zero or one patterns. The
+ * decoding starts at the specified offset 'off'. */
+uint32_t convert_from_line_code(uint8_t *buf, uint64_t buflen, uint8_t *bits, uint32_t len, uint32_t off, const char *zero_pattern, const char *one_pattern)
 {
+    uint32_t decoded = 0; /* Number of bits extracted. */
+    while(off < len) {
+        bool level;
+        if (bitmap_match_bits(bits,len,off,zero_pattern)) {
+            level = true;
+            off += strlen(zero_pattern);
+        } else if (bitmap_match_bits(bits,len,off,one_pattern)) {
+            level = false;
+            off += strlen(zero_pattern);
+        } else {
+            break;
+        }
+        bitmap_set(buf,buflen,decoded++,level);
+        if (decoded/8 == buflen) break; /* No space left on target buffer. */
+    }
+    return decoded;
 }
-#endif
 
 /* Supported protocols go here, with the relevant implementation inside
  * protocols/<name>.c */
 
 extern ProtoViewDecoder Oregon2Decoder;
+extern ProtoViewDecoder B4B1Decoder;
 
 ProtoViewDecoder *Decoders[] = {
-    &Oregon2Decoder,
+    &Oregon2Decoder,        /* Oregon sensors v2.1 protocol. */
+    &B4B1Decoder,           /* PT, SC, ... 24 bits remotes. */
     NULL
 };
 
+/* Reset the message info structure before passing it to the decoding
+ * functions. */
+void initialize_msg_info(ProtoViewMsgInfo *i) {
+    memset(i,0,sizeof(ProtoViewMsgInfo));
+}
+
 /* This function is called when a new signal is detected. It converts it
  * to a bitstream, and the calls the protocol specific functions for
  * decoding. */
@@ -305,6 +328,9 @@ void decode_signal(RawSamplesBuffer *s, uint64_t len) {
 
     /* Try all the decoders available. */
     int j = 0;
+
+    ProtoViewMsgInfo info;
+    initialize_msg_info(&info);
     while(Decoders[j]) {
         FURI_LOG_E(TAG, "Calling decoder %s", Decoders[j]->name);
         ProtoViewMsgInfo info;
@@ -314,6 +340,11 @@ void decode_signal(RawSamplesBuffer *s, uint64_t len) {
         }
         j++;
     }
-    if (Decoders[j] == NULL) FURI_LOG_E(TAG, "No decoding possible");
+    if (Decoders[j] == NULL) {
+        FURI_LOG_E(TAG, "No decoding possible");
+    } else {
+        FURI_LOG_E(TAG, "Decoded %s, raw=%s",
+            info.name, info.raw);
+    }
     free(bitmap);
 }