app.h 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. /* Copyright (C) 2022-2023 Salvatore Sanfilippo -- All Rights Reserved
  2. * See the LICENSE file for information about the license. */
  3. #pragma once
  4. #include <furi.h>
  5. #include <furi_hal.h>
  6. #include <input/input.h>
  7. #include <gui/gui.h>
  8. #include <stdlib.h>
  9. #include <gui/gui.h>
  10. #include <gui/view_dispatcher.h>
  11. #include <gui/scene_manager.h>
  12. #include <gui/modules/submenu.h>
  13. #include <gui/modules/variable_item_list.h>
  14. #include <gui/modules/widget.h>
  15. #include <notification/notification_messages.h>
  16. #include <lib/subghz/subghz_setting.h>
  17. #include <lib/subghz/subghz_worker.h>
  18. #include <lib/subghz/receiver.h>
  19. #include <lib/subghz/transmitter.h>
  20. #include <lib/subghz/registry.h>
  21. #include "app_buffer.h"
  22. #define TAG "ProtoView"
  23. #define PROTOVIEW_RAW_VIEW_DEFAULT_SCALE 100
  24. #define BITMAP_SEEK_NOT_FOUND UINT32_MAX
  25. #define DEBUG_MSG 1
  26. typedef struct ProtoViewApp ProtoViewApp;
  27. /* Subghz system state */
  28. typedef enum {
  29. TxRxStateIDLE,
  30. TxRxStateRx,
  31. TxRxStateSleep,
  32. } TxRxState;
  33. /* Currently active view. */
  34. typedef enum {
  35. ViewRawPulses,
  36. ViewInfo,
  37. ViewFrequencySettings,
  38. ViewModulationSettings,
  39. ViewDirectSampling,
  40. ViewLast, /* Just a sentinel to wrap around. */
  41. } ProtoViewCurrentView;
  42. /* Used by app_switch_view() */
  43. typedef enum {
  44. AppNextView,
  45. AppPrevView
  46. } SwitchViewDirection;
  47. typedef struct {
  48. const char *name;
  49. FuriHalSubGhzPreset preset;
  50. uint8_t *custom;
  51. } ProtoViewModulation;
  52. extern ProtoViewModulation ProtoViewModulations[]; /* In app_subghz.c */
  53. /* This is the context of our subghz worker and associated thread.
  54. * It receives data and we get our protocol "feed" callback called
  55. * with the level (1 or 0) and duration. */
  56. struct ProtoViewTxRx {
  57. bool freq_mod_changed; /* The user changed frequency and/or modulation
  58. from the interface. There is to restart the
  59. radio with the right parameters. */
  60. SubGhzWorker* worker; /* Our background worker. */
  61. SubGhzEnvironment* environment;
  62. SubGhzReceiver* receiver;
  63. TxRxState txrx_state; /* Receiving, idle or sleeping? */
  64. /* Timer sampling mode state. */
  65. bool debug_timer_sampling; /* Read data from GDO0 in a busy loop. Only
  66. for testing. */
  67. uint32_t last_g0_change_time; /* Last high->low (or reverse) switch. */
  68. bool last_g0_value; /* Current value (high or low): we are
  69. checking the duration in the timer
  70. handler. */
  71. };
  72. typedef struct ProtoViewTxRx ProtoViewTxRx;
  73. /* This stucture is filled by the decoder for specific protocols with the
  74. * informations about the message. ProtoView will display such information
  75. * in the message info view. */
  76. #define PROTOVIEW_MSG_STR_LEN 32
  77. typedef struct ProtoViewMsgInfo {
  78. char name[PROTOVIEW_MSG_STR_LEN]; /* Protocol name and version. */
  79. char raw[PROTOVIEW_MSG_STR_LEN]; /* Protocol specific raw representation.*/
  80. /* The following is what the decoder wants to show to user. Each decoder
  81. * can use the number of fileds it needs. */
  82. char info1[PROTOVIEW_MSG_STR_LEN]; /* Protocol specific info line 1. */
  83. char info2[PROTOVIEW_MSG_STR_LEN]; /* Protocol specific info line 2. */
  84. char info3[PROTOVIEW_MSG_STR_LEN]; /* Protocol specific info line 3. */
  85. char info4[PROTOVIEW_MSG_STR_LEN]; /* Protocol specific info line 4. */
  86. /* Low level information of the detected signal: the following are filled
  87. * by the protocol decoding function: */
  88. uint32_t start_off; /* Pulses start offset in the bitmap. */
  89. uint32_t pulses_len; /* Number of pulses of the full message. */
  90. /* The following are passed already filled to the decoder. */
  91. uint32_t short_pulse_dur; /* Microseconds duration of the short pulse. */
  92. /* The following are filled by ProtoView core after the decoder returned
  93. * success. */
  94. uint8_t *bits; /* Bitmap with the signal. */
  95. uint32_t bits_bytes; /* Number of full bytes in the bitmap, that
  96. is 'pulses_len/8' rounded to the next
  97. integer. */
  98. } ProtoViewMsgInfo;
  99. struct ProtoViewApp {
  100. /* GUI */
  101. Gui *gui;
  102. ViewPort *view_port; /* We just use a raw viewport and we render
  103. everything into the low level canvas. */
  104. ProtoViewCurrentView current_view; /* Active left-right view ID. */
  105. int current_subview[ViewLast]; /* Active up-down subview ID. */
  106. FuriMessageQueue *event_queue; /* Keypress events go here. */
  107. /* Radio related. */
  108. ProtoViewTxRx *txrx; /* Radio state. */
  109. SubGhzSetting *setting; /* A list of valid frequencies. */
  110. /* Generic app state. */
  111. int running; /* Once false exists the app. */
  112. uint32_t signal_bestlen; /* Longest coherent signal observed so far. */
  113. uint32_t signal_last_scan_idx; /* Index of the buffer last time we
  114. performed the scan. */
  115. bool signal_decoded; /* Was the current signal decoded? */
  116. ProtoViewMsgInfo signal_info; /* Decoded message, if signal_decoded true. */
  117. bool direct_sampling_enabled; /* This special view needs an explicit
  118. acknowledge to work. */
  119. /* Raw view apps state. */
  120. uint32_t us_scale; /* microseconds per pixel. */
  121. uint32_t signal_offset; /* Long press left/right panning in raw view. */
  122. /* Configuration view app state. */
  123. uint32_t frequency; /* Current frequency. */
  124. uint8_t modulation; /* Current modulation ID, array index in the
  125. ProtoViewModulations table. */
  126. };
  127. typedef struct ProtoViewDecoder {
  128. const char *name; /* Protocol name. */
  129. /* The decode function takes a buffer that is actually a bitmap, with
  130. * high and low levels represented as 0 and 1. The number of high/low
  131. * pulses represented by the bitmap is passed as the 'numbits' argument,
  132. * while 'numbytes' represents the total size of the bitmap pointed by
  133. * 'bits'. So 'numbytes' is mainly useful to pass as argument to other
  134. * functions that perform bit extraction with bound checking, such as
  135. * bitmap_get() and so forth. */
  136. bool (*decode)(uint8_t *bits, uint32_t numbytes, uint32_t numbits, ProtoViewMsgInfo *info);
  137. } ProtoViewDecoder;
  138. extern RawSamplesBuffer *RawSamples, *DetectedSamples;
  139. /* app_radio.c */
  140. void radio_begin(ProtoViewApp* app);
  141. uint32_t radio_rx(ProtoViewApp* app);
  142. void radio_idle(ProtoViewApp* app);
  143. void radio_rx_end(ProtoViewApp* app);
  144. void radio_sleep(ProtoViewApp* app);
  145. void raw_sampling_worker_start(ProtoViewApp *app);
  146. void raw_sampling_worker_stop(ProtoViewApp *app);
  147. /* signal.c */
  148. uint32_t duration_delta(uint32_t a, uint32_t b);
  149. void reset_current_signal(ProtoViewApp *app);
  150. void scan_for_signal(ProtoViewApp *app);
  151. bool bitmap_get(uint8_t *b, uint32_t blen, uint32_t bitpos);
  152. void bitmap_set(uint8_t *b, uint32_t blen, uint32_t bitpos, bool val);
  153. void bitmap_copy(uint8_t *d, uint32_t dlen, uint32_t doff, uint8_t *s, uint32_t slen, uint32_t soff, uint32_t count);
  154. void bitmap_set_pattern(uint8_t *b, uint32_t blen, const char *pat);
  155. void bitmap_reverse_bytes(uint8_t *p, uint32_t len);
  156. bool bitmap_match_bits(uint8_t *b, uint32_t blen, uint32_t bitpos, const char *bits);
  157. uint32_t bitmap_seek_bits(uint8_t *b, uint32_t blen, uint32_t startpos, uint32_t maxbits, const char *bits);
  158. 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);
  159. uint32_t convert_from_diff_manchester(uint8_t *buf, uint64_t buflen, uint8_t *bits, uint32_t len, uint32_t off, bool previous);
  160. /* view_*.c */
  161. void render_view_raw_pulses(Canvas *const canvas, ProtoViewApp *app);
  162. void process_input_raw_pulses(ProtoViewApp *app, InputEvent input);
  163. void render_view_settings(Canvas *const canvas, ProtoViewApp *app);
  164. void process_input_settings(ProtoViewApp *app, InputEvent input);
  165. void render_view_info(Canvas *const canvas, ProtoViewApp *app);
  166. void process_input_info(ProtoViewApp *app, InputEvent input);
  167. void render_view_direct_sampling(Canvas *const canvas, ProtoViewApp *app);
  168. void process_input_direct_sampling(ProtoViewApp *app, InputEvent input);
  169. void view_enter_direct_sampling(ProtoViewApp *app);
  170. void view_exit_direct_sampling(ProtoViewApp *app);
  171. void view_exit_settings(ProtoViewApp *app);
  172. /* ui.c */
  173. void show_available_subviews(Canvas *canvas, ProtoViewApp *app, int last_subview);
  174. bool process_subview_updown(ProtoViewApp *app, InputEvent input, int last_subview);
  175. void canvas_draw_str_with_border(Canvas* canvas, uint8_t x, uint8_t y, const char* str, Color text_color, Color border_color);
  176. /* crc.c */
  177. uint8_t crc8(const uint8_t *data, size_t len, uint8_t init, uint8_t poly);