Skip to content

Commit

Permalink
Protocol decoding, work in progress 2.
Browse files Browse the repository at this point in the history
  • Loading branch information
antirez committed Jan 2, 2023
1 parent 4ce568a commit 10227a4
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 7 deletions.
3 changes: 2 additions & 1 deletion app.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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);
Expand Down
39 changes: 39 additions & 0 deletions protocols/b4b1.c
Original file line number Diff line number Diff line change
@@ -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
};
43 changes: 37 additions & 6 deletions signal.c
Original file line number Diff line number Diff line change
Expand Up @@ -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. */
Expand Down Expand Up @@ -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;
Expand All @@ -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);
}

0 comments on commit 10227a4

Please sign in to comment.