Skip to content

Commit

Permalink
Squashed 'protoview/' changes from e0d6e97..66744dc
Browse files Browse the repository at this point in the history
66744dc fix catalog versions
bca1060 New naming fixes part 1
25842ee replace protoview pa table hotfix with proper code
2b62870 combine 1
98960dc move base pack here
REVERT: e0d6e97 Binary file updated.
REVERT: 7143455 Chat: use 300us short pulse for better reception.
REVERT: a7c8520 Binary file updated.
REVERT: df527db Chat: protocol changed a bit. Rationale added.
REVERT: 0bf9ff8 Binary file updated.
REVERT: 8e32ef6 Chat fixed, hopefully.
REVERT: 9352b0b General decoder improved.
REVERT: 79ef4f5 Replace decoded signal with one decoded by the "unknown" decoder.
REVERT: 911cb67 Initial work for a generic protocol decoder.
REVERT: 6456f39 Minor comment improvement.
REVERT: 705cbd1 Remove hardcoded limit from search_coherent_signal().
REVERT: cf4b75e Chat: Fix message len.
REVERT: 48fb26f ProtoView chat protocol description improved.
REVERT: 5945601 Binary file updated.
REVERT: 3f78a13 ProtoView chat protocol.
REVERT: d78079a Add copyright information.
REVERT: cc32c5e b4b1: more robust message detection.
REVERT: 32b3f76 Binary file updated.
REVERT: b07fd75 Icon updated.
REVERT: e7a81d1 Duration filter now changes according to preset data rate.
REVERT: 6a9baf2 Binary file updated.
REVERT: b060c50 Direct sampling: brand new implementation.
REVERT: da2f928 Update comments and function names in app_subghz.c
REVERT: d53188d Direct sampling fixes and ability to pause.
REVERT: 2a791b1 Protect screen refresh from switch_view() with a mutex.
REVERT: 05899c2 Direct sampling: different improvements.
REVERT: 7579471 Fix view switching calls order.
REVERT: 6b4be88 CC1101 custom presets updated.
REVERT: d1bcd09 Restore TPMS2 OOK setting, modified for error.
REVERT: d1c86b3 Fix direct sampling after subghz worker deletion.
REVERT: 63ea908 Subghz worker stuff removed. 50k of free memory won.
REVERT: 2f00397 Renault TPMS encoder.
REVERT: 8887f51 README: fix markdown.
REVERT: 5ec69f0 README updated.
REVERT: 873d638 Binary file updated.
REVERT: acd4329 Message builder: auto select decoder and current decoded values.
REVERT: de085c8 Message builder: < > to incr/decr fields.
REVERT: d19ffe6 Keeloq encoder: set default low battery to 0.
REVERT: 9f9115e Rename function to bitmap_reverse_bytes_bits() for clarity.
REVERT: 118af1a Keeloq encoder: clean data array.
REVERT: 9d020c0 Fix field_set_from_string() for binary type.
REVERT: 96a5e7d Keeloq signal building: a few details to fix.
REVERT: 9344e86 Fieldset: more fixes to bytes field type.
REVERT: 00819ac Message builder: Generate signal and decode it.
REVERT: f75067c Implement signal creation for PT remotes.
REVERT: 6d6c5e9 Fieldset: fix a few to/from string conversions.
REVERT: e38ad0f Message builder: User input progresses.
REVERT: baecc6c Message builder: Some more UI element.
REVERT: 7ed3614 Message builder: Decoder selection and basic text drawing.
REVERT: 23a8793 Build message view introduced.
REVERT: 6606d8c README: RX -> TX.
REVERT: 524a219 README improved a bit more.
REVERT: c750f33 Merge branch 'edit'
REVERT: 4fc3a4e README updated.
REVERT: b651d54 Binary file updated.
REVERT: bc8f8a2 Fix sending in custom presets: add PATABLE.
REVERT: 88a43ec Make keyboard able to be dismissed with back key.
REVERT: 0d11844 Multi page INFO. Long press to reset signal.
REVERT: 2a053c1 Conversion to field set: WIP 2.
REVERT: 6905385 Conversion to field set: WIP 1.
REVERT: 03f5656 Message building: fields types and functions.
REVERT: 4092d3f Merge pull request #5 from dopsi/main
REVERT: 8ef1f05 Use public header file
REVERT: c93ae3c UI alert + long press to exit.
REVERT: 86c5c71 Generalize app_switch_view() to switch to specific views.
REVERT: f2633b0 Binary file updated.
REVERT: 2bf380d Suppress charging to improve RF performances.
REVERT: 736421d Blink blue led while sending.
REVERT: cb88bdc Notification when receiving/sending.
REVERT: 2fe4ce3 Tx: data feeder of current signal refactored.
REVERT: 362ef7c Sending back messages.
REVERT: a04f4fb Merge branch 'save_subview'
REVERT: 9a31419 Save text to make UI more obvious.
REVERT: 0f8ef0a Fix start/len reporting in all the decoders.
REVERT: 8fe8d93 Remove useless debugging logs.
REVERT: 1076248 Saving signal now works.
REVERT: b9ece78 Random file name.
REVERT: 8ca076c Refactoring of code to show/hide the keyboard.
REVERT: 2f1327e Show text input when needed.
REVERT: 56b9689 Fix bitmap copy and oscilloscope view.
REVERT: 2459e55 View privdata. Oscilliscope alike view row change.
REVERT: f885491 Decoded signal square wave WIP.
REVERT: 004a457 Fix typo in comment.
REVERT: 56eb528 Public TODO removed. I change idea every 5 seconds.
REVERT: 25bc81a Copy signal representation in the info structure.
REVERT: b76b6d8 TODO: add roadmap.
REVERT: 47586fc Binary file updated.
REVERT: 2de5c2a Very basic subview system introduced.
REVERT: 1e4bbfa README updated.
REVERT: ea48c7f Microchip HCS series, Keeloq protocol.
REVERT: 21a2ef4 Put TPMS decoders under a separated directory.
REVERT: b1ce345 Buffers: use 2 bytes per sample instead of 5.
REVERT: 2fa23ee Improve Schrader EG53MA4 implementation.
REVERT: 67471e7 Schrader EG53MA4 TPMS.
REVERT: c1f3ee3 More custom presets comments fixed.
REVERT: 41a9259 Improve custom settings comments.
REVERT: 54eea1d CC1101 preset that works well with OOK TPMS.
REVERT: c25645a README: add Ford TPMS.
REVERT: 7f98052 Binary file updated.
REVERT: 10d17fe Pressing OK resets current signal in info view.
REVERT: a711ad1 Ford TPMS.
REVERT: a49ebe1 Binary file updated.
REVERT: bdcaa93 Add Citroen in README.
REVERT: 1fe8a7f Citroen TPMS.
REVERT: 86c9cdb README: update protocols list.
REVERT: b1477af Move one of the screenshot down. Makes more sense.
REVERT: 68b158c Screenshots updated.
REVERT: d57c733 rtl433 credits.
REVERT: 7ad07e9 Binary file updated.
REVERT: cf2fdc6 Check CRC for TPMS protocols.
REVERT: a631025 TODO updated.
REVERT: 0e85d13 Try to scan more often, but only scan if needed.
REVERT: 86ca7ff Check checksum in Schrader TPMS.
REVERT: 715661c Better raw view scale selection.
REVERT: 2a91ac8 Schrader TPMS implementation + CRC8 implementation.
REVERT: bcc3991 Merge pull request #3 from erjanmx/fix-readme-typo
REVERT: be08071 TODO updated.
REVERT: 80cb1d3 Binary file updated.
REVERT: a81a3f2 Enable/disable and explain direct sampling.
REVERT: ec5bae7 Readme updated.
REVERT: 65d7c70 Disable debug timer sampling mode.
REVERT: e84beb0 Improve signal substitution rules.
REVERT: 4435450 Show Renault TPMS tire ID.
REVERT: 9b6067b Toyota TPMS.
REVERT: 126f1f3 Differential Manchester encoding.
REVERT: 015ee09 Improve naming of two variables.
REVERT: 8f63eb4 Raise min length of pulses.
REVERT: 1269469 Allow for more time difference. Decode more bits than detected.
REVERT: 5174bf1 Reanult TPMS fixed.
REVERT: 0d62d89 Third TPMS custom preset. Start with subghz feeding.
REVERT: 616943a Remove busy loop DS. Timer is better.
REVERT: b61cbf6 Fix switching between direct sampling and subghz.
REVERT: 549f83a Direct sampling with timer working.
REVERT: 13fdeb1 Signal detection in DS.
REVERT: 1065de9 Setup timer.
REVERT: b879bb9 Allow switching between normal and debug DS mode.
REVERT: 06997d7 Apply frequency/modulation changes on view exit.
REVERT: 0cc1128 Direct sampling: kinda working.
REVERT: 5f29902 Fix readme typo
REVERT: 27edce5 Exit/enter view callbacks. Stop subghz worker in direct sampling mode.
REVERT: 6ba3702 Direct sampling mode, reading GDO0 directly.
REVERT: 4e36d03 TPMS2 preset changed. Few CC1101 registers documented.
REVERT: 811d8f3 Define to disable the subghz worker filter.
REVERT: a0c78b8 Invert settings up/down keys effect.
REVERT: f0a2607 Add a second TPMS-specific mode.
REVERT: 5fc223c Merge pull request #1 from Illogico/patch-1
REVERT: cafc169 Binary file updated.
REVERT: 79c9481 Update README.md
REVERT: 6da6c33 TPMS: comment about 2FSK / GFSK.
REVERT: be293ca Optimize preamble matching.
REVERT: 6ee7351 Log decoders latecy.
REVERT: 1d8ca65 Support for custom CC1101 presets.
REVERT: d373b5d Renault TPMS and other improvements.
REVERT: 341ceda Store bits in the same order they are received.
REVERT: a5f3ce4 Reduce min pulse length detected.
REVERT: 0da1b7a Oregon2: remove debugging messages.
REVERT: 24071c1 Signal info view.
REVERT: de4d3ee Show detected protocol in raw view.
REVERT: 864cb66 Oregon2: get humidity.
REVERT: 0f44252 Fixes, comments, Oregon2 basic protocol.
REVERT: 31fd6df Decoding: limit huge pulses. UI settings: long OK press sets defaults.
REVERT: 49a0bc4 PT/SC remote protocol working.
REVERT: 10227a4 Protocol decoding, work in progress 2.
REVERT: 4ce568a More robust short signal us guess.
REVERT: 630290f Protocol decoding, work in progress.
REVERT: 52e60b5 Binary file updated.
REVERT: 6cd2b34 Fix settings key press handling.
REVERT: 29d4a75 Initial signal processing code.
REVERT: 5464f99 Long press OK to center the signal again.
REVERT: 6c51715 Refactoring.
REVERT: 4635c8f Binary update script.
REVERT: 979bc84 Binary file updated.
REVERT: 9503bde Long press left/right for panning in raw view.
REVERT: 999cc48 A few more comments in app.c
REVERT: de3dee1 TODO updated.
REVERT: 9667d3d Binary distribution.
REVERT: 8062fb0 Avoid rescanning detected signal parts.
REVERT: e921036 duration_delta(): missing space in a one liner is too much.
REVERT: b116d43 Fix comment after code change.
REVERT: 22f22a6 README: fipper -> Flipper.
REVERT: b596a86 README improved.
REVERT: 1e6eaf5 README: added section about Flipper code quality.
REVERT: a173c53 README: more typos.
REVERT: 74943a7 Copyright notice added.
REVERT: bf9eeda README: typo.
REVERT: 69d4f86 README: specify we classify RF on/off separately.
REVERT: d7b2d63 README: typos.
REVERT: 8df0281 TODO updated.
REVERT: f26954d Screenshot added.
REVERT: 2e9a4c4 README updated.
REVERT: eea8b4e Set freq and modulation + other improvements.
REVERT: be41b40 View specific input handling.
REVERT: d750c80 Multi view handling.
REVERT: d57370e A few more comments here and there.
REVERT: 7026e42 README added.
REVERT: 2679be7 Skip almost empty classes in short pulse len calculation.
REVERT: bbe40ea Skip empty classes in pulse len calculation.
REVERT: 09990d6 Fix scale change.
REVERT: 863dc84 Reset sample history when OK is pressed.
REVERT: 860879e Up/down change scale. Better short pulse computation.
REVERT: a81c90b TODO: added pulse length improvement needed.
REVERT: bdaebc5 Display short pulse length.
REVERT: 04826a8 Move processing into timer.
REVERT: 4f8f7d8 Initial commit with working minimal app.

git-subtree-dir: protoview
git-subtree-split: 66744dc
  • Loading branch information
Willy-JL committed Nov 12, 2023
1 parent e0d6e97 commit 361e300
Show file tree
Hide file tree
Showing 37 changed files with 1,785 additions and 1,789 deletions.
154 changes: 12 additions & 142 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
ProtoView is a digital signal detection, visualization, editing and reply tool for the [Flipper Zero](https://flipperzero.one/). The Flipper default application, called Subghz, is able to identify certain RF protocols, but when the exact protocol is not implemented (and there are many undocumented and unimplemented ones, such as the ones in use in TPMS systems, car keys and many others), the curious person is left wondering what the device is sending at all. Using ProtoView she or he can visualize the high and low pulses like in the example image below (showing a TPMS signal produced by a Renault tire):

![ProtoView screenshot raw signal](/images/protoview_1.jpg)

ProtoView is a digital signal detection, visualization, editing and reply tool for the Flipper Zero. The Flipper default application, called Subghz, is able to identify certain RF protocols, but when the exact protocol is not implemented (and there are many undocumented and unimplemented ones, such as the ones in use in TPMS systems, car keys and many others), the curious person is left wondering what the device is sending at all. Using ProtoView she or he can visualize the high and low pulses
This is often enough to make an initial idea about the encoding used
and if the selected modulation is correct. For example, in the signal above
you can see a set of regular pulses and gaps used for synchronization, and then
a sequence of bits encoded in [Manchester](https://en.wikipedia.org/wiki/Manchester_code) line code. If you study these things for five minutes, you'll find yourself able to decode the bits with naked eyes.
a sequence of bits encoded in Manchester - https://en.wikipedia.org/wiki/Manchester_code line code. If you study these things for five minutes, you'll find yourself able to decode the bits with naked eyes.

## Decoding capabilities

Expand All @@ -15,13 +12,12 @@ Other than showing the raw signal, ProtoView is able to decode a few interesting
* Microchip HSC200/300/301 Keeloq protocol.
* Oregon thermometer protocol 2.
* PT2262, SC5262 based remotes.
* ... more will be implemented soon, hopefully. Send PRs :)
* ... more will be implemented soon, hopefully. Send PRs

![ProtoView screenshot Renault TPMS data](/images/protoview_2.jpg)

The app implements a framework that makes adding and experimenting with new
protocols very simple. Check the `protocols` directory to see how the
API works, or read the full documentation at the end of this `README` file.
protocols very simple. Check the (protocols) directory to see how the
API works, or read the full documentation at the end of (README) file.
The gist of it is that the decoder receives the signal already converted into
a bitmap, where each bit represents a short pulse duration. Then there are
functions to seek specific sync/preamble sequences inside the bitmap, to decode
Expand All @@ -44,9 +40,9 @@ values.
## A well-documented app for the Flipper

The secondary goal of ProtoView is to provide a well-documented application for the Flipper (even if ProtoView is a pretty atypical application: it doesn't make use of the standard widgets and other abstractions provided by the framework).
Most apps dealing with the *subghz subsystem* of the Flipper (the abstraction used to work with the [CC1101 chip](https://www.ti.com/product/CC1101)) tend to be complicated and completely undocumented.
Most apps dealing with the *subghz subsystem* of the Flipper (the abstraction used to work with the CC1101 chip - https://www.ti.com/product/CC1101) tend to be complicated and completely undocumented.
Unfortunately, this is also true for the firmware of the device.
It's a shame, because especially in the case of code that talks with hardware peripherals there are tons of assumptions and hard-gained lessons that can [only be captured by comments and are in the code only implicitly](http://antirez.com/news/124).
It's a shame, because especially in the case of code that talks with hardware peripherals there are tons of assumptions and hard-gained lessons that can only be captured by comments and are in the code only implicitly - http://antirez.com/news/124

However, the Flipper firmware source code is well written even if it
lacks comments and documentation (and sometimes makes use of abstractions more convoluted than needed), so it is possible to make some ideas of how things work just grepping inside. In order to develop this application, I ended reading most parts of the firmware of the device.
Expand Down Expand Up @@ -97,8 +93,8 @@ with the right arrow will show information about the decoded signal.
In the bottom-right corner the application displays an amount of time
in microseconds. This is the average length of the shortest pulse length
detected among the three classes. Usually the *data rate* of the protocol
is something like `1000000/this-number*2`, but it depends on the encoding
and could actually be `1000000/this-number*N` with `N > 2` (here 1000000
is something like (1000000/this-number*2), but it depends on the encoding
and could actually be (1000000/this-number*N) with (N > 2) (here 1000000
is the number of microseconds in one second, and N is the number of clock
cycles needed to represent a bit).

Expand All @@ -107,7 +103,7 @@ cycles needed to represent a bit).
If a signal was detected, the info view will show the details about the signal. If the signal has more data that a single screen can fit, pressing OK will show the next fields. Pressing DOWN will go to a sub-view with an oscilloscope-alike representation of the signal, from there you can:

1. Resend the signal, by pressing OK.
2. Save the signal as `.sub` file, by long pressing OK.
2. Save the signal as (.sub) file, by long pressing OK.

When resending, you can select a different frequency and modulation if you
wish.
Expand Down Expand Up @@ -144,132 +140,6 @@ RF chip, the CC1101, is receiving. This will makes very easy to understand
if a given frequency is targeted by something other than noise. This mode is
fun to watch, resembling an old CRT TV set.

# Installing the app from source

* Download the Flipper Zero dev kit and build it:
```
mkdir -p ~/flipperZero/official/
cd ~/flipperZero/official/
git clone --recursive https://github.com/flipperdevices/flipperzero-firmware.git ./
./fbt
```
* Copy this application folder in `official/applications_user`.
* Connect your Flipper via USB.
* Build and install with: `./fbt launch_app APPSRC=protoview`.

# Installing the binary file (no build needed)

Drop the `protoview.fap` file you can find in the `binaries` folder into the
following Flipper Zero location:

/ext/apps/Tools

The `ext` part means that we are in the SD card. So if you don't want
to use the Android (or other) application to upload the file,
you can just take out the SD card, insert it in your computer,
copy the fine into `apps/Tools`, and that's it.

# Protocols decoders API

Writing a protocol decoder is not hard, and requires to write three
different methods.

1. `decode()`. This is mandatory, and is used in order to turn a known signal into a set of fields containing certain informations. For instance for a thermometer sending data via RF, a raw message will be decoded into fields like temperature, humidity, station ID and so forth.
2. `get_fields()`. Optional, only needed if the protocol supports creating and editing signals. This method just returns the fields names, types and defaults. The app will use this list in order to allow the user to set values. The populated fields will be passed to the `build_message()` method later.
3. `build_message()`. This method gets a set of fields representing the parameters of the protocol, as set by the user, and will create a low level signal composed of pulses and gaps of specific durations.

## `decode()` method

bool decode(uint8_t *bits, uint32_t numbytes, uint32_t numbits, ProtoViewMsgInfo *info);

The method gets a bitmap `bits` long `numbytes` bytes but actually containing `bumbits` valid bits. Each bit represents a pulse of gap of the duration of the shortest time detected in the protocol (this is often called *te*, in the RF protocols jargon). So, for instance, if a signal is composed of pulses and gaps of around 500 and 1000 microseconds, each bit in the bitmap will represent 500 microseconds.

Continuing with the example above, if the received signal was composed of a 1000 microseconds gap, then a 500 microsecond pulse, then a 500 microsecond gap and finally a 1000 microseconds pulse, its bitmap representation will be:

001011

To access the bitmap, the decoder can use the following API:

bool bitmap_get(uint8_t *b, uint32_t blen, uint32_t bitpos);

The `blen` parameter will be set to what the decode method gets
as `numbytes`, and is used to prevent overflows. This way if `bitpos`
is out of range, nothing bad happens.

There are function to match and seek specific patterns inside the signal:

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, uint32_t maxbits, const char *bits);

Finally, there are functions to convert from different line codes:

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);
uint32_t convert_from_diff_manchester(uint8_t *buf, uint64_t buflen, uint8_t *bits, uint32_t len, uint32_t off, bool previous);

This method can also access the short pulse duration by inspecting the
`info->short_pulse_dur` field (in microseconds).

Please check the `b4b1.c` file for an easy to understand example of the decoder implementation.

If the decoder actually detected a message, it will return `true` and will return a set of fields, like thata:

fieldset_add_bytes(info->fieldset,"id",d,5);
fieldset_add_uint(info->fieldset,"button",d[2]&0xf,4);

## `get_fields()` method.

static void get_fields(ProtoViewFieldSet *fieldset);

This method will be basically a copy of the final part of `decode()`, as
it also needs to return the set of fields this protocol is composed of.
However instead of returning the values of an actual decoded message, it
will just provide their default values for the signal creator view.

Note that the `build_message()` method is guaranteed to receive the
same exact fields in the same exact order.

## `build_message()` method.

void build_message(RawSamplesBuffer *samples, ProtoViewFieldSet *fs);

This method is responsible of creating a signal from scratch, by
appending gaps and pulses of the specific duration into `samples`
using the following API:

raw_samples_add(RawSamplesBuffer *samples, bool level, uint32_t duration);

Level can be true (pules) or false (gap). Duration is in microseconds.
The method receives a set of fields in `fs`. Each field is accessible
directly accessing `fs->fields[... field index ...]`, where the field
index is 0, 1, 2, ... in the same order as `get_fields()` returned the
fields.

For now, you can access the fields in the raw way, by getting the
values directly from the data structure representing each field:

```
typedef struct {
ProtoViewFieldType type;
uint32_t len; // Depends on type:
// Bits for integers (signed,unsigned,binary,hex).
// Number of characters for strings.
// Number of nibbles for bytes (1 for each 4 bits).
// Number of digits after dot for floats.
char *name; // Field name.
union {
char *str; // String type.
int64_t value; // Signed integer type.
uint64_t uvalue; // Unsigned integer type.
uint8_t *bytes; // Raw bytes type.
float fvalue; // Float type.
};
} ProtoViewField;
```

However later the app will likely provide a set of macros to do it
in a more future-proof way.

# License

The code is released under the BSD license.
Expand All @@ -280,10 +150,10 @@ This application is only provided as an educational tool. The author is not liab

# Credits

A big thank you to the RTL433 author, [Benjamin Larsson](https://github.com/merbanan). I used the code and tools he developed in many ways:
A big thank you to the RTL433 author, Benjamin Larsson - https://github.com/merbanan I used the code and tools he developed in many ways:
* To capture TPMS data with rtl433 and save to a file, to later play the IQ files and speedup the development.
* As a sourve of documentation for protocols.
* As an awesome way to visualize and understand protocols, via [these great web tools](https://triq.org/).
* As an awesome way to visualize and understand protocols, via these great web tools - https://triq.org/
* To have tons of fun with RTLSDR in general, now and in the past.

The application icon was designed by Stefano Liuzzo.
Loading

0 comments on commit 361e300

Please sign in to comment.