1 //-----------------------------------------------------------------------------
2 // Copyright (C) 2010 iZsh <izsh at fail0verflow.com>
4 // This code is licensed to you under the terms of the GNU GPL, version 2 or,
5 // at your option, any later version. See the LICENSE.txt file for the text of
7 //-----------------------------------------------------------------------------
9 //-----------------------------------------------------------------------------
15 #include "util.h" //param_get32ex
17 #include "cmddata.h" //for g_debugmode
20 int GraphBuffer
[MAX_GRAPH_TRACE_LEN
];
23 /* write a manchester bit to the graph
24 TODO, verfy that this doesn't overflow buffer (iceman)
26 void AppendGraph(bool redraw
, uint16_t clock
, int bit
) {
27 uint8_t half
= clock
/ 2;
29 //set first half the clock bit (all 1's or 0's for a 0 or 1 bit)
30 for (i
= 0; i
< half
; ++i
)
31 GraphBuffer
[GraphTraceLen
++] = bit
;
33 //set second half of the clock bit (all 0's or 1's for a 0 or 1 bit)
34 for (; i
< clock
; ++i
)
35 GraphBuffer
[GraphTraceLen
++] = bit
^ 1;
41 // clear out our graph window
42 size_t ClearGraph(bool redraw
) {
43 size_t gtl
= GraphTraceLen
;
44 memset(GraphBuffer
, 0x00, GraphTraceLen
);
50 // option '1' to save GraphBuffer any other to restore
51 void save_restoreGB(uint8_t saveOpt
) {
52 static int SavedGB
[MAX_GRAPH_TRACE_LEN
];
53 static size_t SavedGBlen
= 0;
54 static bool GB_Saved
= false;
55 static int SavedGridOffsetAdj
= 0;
57 if (saveOpt
== GRAPH_SAVE
) { //save
58 memcpy(SavedGB
, GraphBuffer
, sizeof(GraphBuffer
));
59 SavedGBlen
= GraphTraceLen
;
61 SavedGridOffsetAdj
= GridOffset
;
62 } else if (GB_Saved
) { //restore
63 memcpy(GraphBuffer
, SavedGB
, sizeof(GraphBuffer
));
64 GraphTraceLen
= SavedGBlen
;
65 GridOffset
= SavedGridOffsetAdj
;
70 void setGraphBuf(uint8_t *buff
, size_t size
) {
71 if (buff
== NULL
) return;
75 if (size
> MAX_GRAPH_TRACE_LEN
)
76 size
= MAX_GRAPH_TRACE_LEN
;
78 for (size_t i
= 0; i
< size
; ++i
)
79 GraphBuffer
[i
] = buff
[i
] - 128;
85 size_t getFromGraphBuf(uint8_t *buff
) {
86 if (buff
== NULL
) return 0;
87 if (GraphTraceLen
== 0) return 0;
90 for (i
= 0; i
< GraphTraceLen
; ++i
) {
92 if (GraphBuffer
[i
] > 127) GraphBuffer
[i
] = 127;
93 if (GraphBuffer
[i
] < -127) GraphBuffer
[i
] = -127;
94 buff
[i
] = (uint8_t)(GraphBuffer
[i
] + 128);
99 // A simple test to see if there is any data inside Graphbuffer.
100 bool HasGraphData(void) {
101 if (GraphTraceLen
== 0) {
102 PrintAndLogEx(NORMAL
, "No data available, try reading something first");
108 bool isGraphBitstream(void) {
109 // convert to bitstream if necessary
110 for (int i
= 0; i
< GraphTraceLen
; i
++) {
111 if (GraphBuffer
[i
] > 1 || GraphBuffer
[i
] < 0) {
118 void convertGraphFromBitstream(void) {
119 convertGraphFromBitstreamEx(1, 0);
122 void convertGraphFromBitstreamEx(int hi
, int low
) {
123 for (int i
= 0; i
< GraphTraceLen
; i
++) {
124 if (GraphBuffer
[i
] == hi
)
125 GraphBuffer
[i
] = 127;
126 else if (GraphBuffer
[i
] == low
)
127 GraphBuffer
[i
] = -127;
132 uint8_t *bits
= calloc(GraphTraceLen
, sizeof(uint8_t));
134 PrintAndLogEx(DEBUG
, "ERR: convertGraphFromBitstreamEx, failed to allocate memory");
138 size_t size
= getFromGraphBuf(bits
);
140 PrintAndLogEx(WARNING
, "Failed to copy from graphbuffer");
145 // set signal properties low/high/mean/amplitude and is_noise detection
146 computeSignalProperties(bits
, size
);
148 RepaintGraphWindow();
151 // Get or auto-detect ask clock rate
152 int GetAskClock(const char *str
, bool verbose
) {
153 if (getSignalProperties()->isnoise
)
156 int clock1
= param_get32ex(str
, 0, 0, 10);
162 uint8_t *bits
= calloc(MAX_GRAPH_TRACE_LEN
, sizeof(uint8_t));
164 PrintAndLogEx(WARNING
, "Failed to allocate memory");
168 size_t size
= getFromGraphBuf(bits
);
170 PrintAndLogEx(WARNING
, "Failed to copy from graphbuffer");
175 size_t ststart
= 0, stend
= 0;
176 bool st
= DetectST(bits
, &size
, &clock1
, &ststart
, &stend
);
179 idx
= DetectASKClock(bits
, size
, &clock1
, 20);
183 setClockGrid(clock1
, idx
);
185 // Only print this message if we're not looping something
186 if (verbose
|| g_debugMode
)
187 PrintAndLogEx(SUCCESS
, "Auto-detected clock rate: %d, Best Starting Position: %d", clock1
, idx
);
193 int GetPskCarrier(bool verbose
) {
194 if (getSignalProperties()->isnoise
)
197 uint8_t *bits
= calloc(MAX_GRAPH_TRACE_LEN
, sizeof(uint8_t));
199 PrintAndLogEx(WARNING
, "Failed to allocate memory");
203 size_t size
= getFromGraphBuf(bits
);
205 PrintAndLogEx(WARNING
, "Failed to copy from graphbuffer");
210 uint16_t fc
= countFC(bits
, size
, false);
213 uint8_t carrier
= fc
& 0xFF;
214 if (carrier
!= 2 && carrier
!= 4 && carrier
!= 8) return 0;
215 if ((fc
>> 8) == 10 && carrier
== 8) return 0;
216 // Only print this message if we're not looping something
218 PrintAndLogEx(SUCCESS
, "Auto-detected PSK carrier rate: %d", carrier
);
223 int GetPskClock(const char *str
, bool verbose
) {
225 if (getSignalProperties()->isnoise
)
228 int clock1
= param_get32ex(str
, 0, 0, 10);
233 uint8_t *bits
= calloc(MAX_GRAPH_TRACE_LEN
, sizeof(uint8_t));
235 PrintAndLogEx(WARNING
, "Failed to allocate memory");
239 size_t size
= getFromGraphBuf(bits
);
241 PrintAndLogEx(WARNING
, "Failed to copy from graphbuffer");
246 size_t firstPhaseShiftLoc
= 0;
247 uint8_t curPhase
= 0, fc
= 0;
248 clock1
= DetectPSKClock(bits
, size
, 0, &firstPhaseShiftLoc
, &curPhase
, &fc
);
251 setClockGrid(clock1
, firstPhaseShiftLoc
);
253 // Only print this message if we're not looping something
255 PrintAndLogEx(SUCCESS
, "Auto-detected clock rate: %d", clock1
);
261 int GetNrzClock(const char *str
, bool verbose
) {
263 if (getSignalProperties()->isnoise
)
266 int clock1
= param_get32ex(str
, 0, 0, 10);
271 uint8_t *bits
= calloc(MAX_GRAPH_TRACE_LEN
, sizeof(uint8_t));
273 PrintAndLogEx(WARNING
, "Failed to allocate memory");
277 size_t size
= getFromGraphBuf(bits
);
279 PrintAndLogEx(WARNING
, "Failed to copy from graphbuffer");
284 size_t clkStartIdx
= 0;
285 clock1
= DetectNRZClock(bits
, size
, 0, &clkStartIdx
);
286 setClockGrid(clock1
, clkStartIdx
);
287 // Only print this message if we're not looping something
289 PrintAndLogEx(SUCCESS
, "Auto-detected clock rate: %d", clock1
);
296 //attempt to detect the field clock and bit clock for FSK
297 int GetFskClock(const char *str
, bool verbose
) {
299 int clock1
= param_get32ex(str
, 0, 0, 10);
303 uint8_t fc1
= 0, fc2
= 0, rf1
= 0;
304 int firstClockEdge
= 0;
306 if (fskClocks(&fc1
, &fc2
, &rf1
, &firstClockEdge
) == false)
309 if ((fc1
== 10 && fc2
== 8) || (fc1
== 8 && fc2
== 5)) {
311 PrintAndLogEx(SUCCESS
, "Detected Field Clocks: FC/%d, FC/%d - Bit Clock: RF/%d", fc1
, fc2
, rf1
);
313 setClockGrid(rf1
, firstClockEdge
);
317 PrintAndLogEx(DEBUG
, "DEBUG: unknown fsk field clock detected");
318 PrintAndLogEx(DEBUG
, "Detected Field Clocks: FC/%d, FC/%d - Bit Clock: RF/%d", fc1
, fc2
, rf1
);
322 bool fskClocks(uint8_t *fc1
, uint8_t *fc2
, uint8_t *rf1
, int *firstClockEdge
) {
324 if (getSignalProperties()->isnoise
)
327 uint8_t *bits
= calloc(MAX_GRAPH_TRACE_LEN
, sizeof(uint8_t));
329 PrintAndLogEx(WARNING
, "Failed to allocate memory");
333 size_t size
= getFromGraphBuf(bits
);
335 PrintAndLogEx(WARNING
, "Failed to copy from graphbuffer");
340 uint16_t ans
= countFC(bits
, size
, true);
342 PrintAndLogEx(DEBUG
, "DEBUG: No data found");
347 *fc1
= (ans
>> 8) & 0xFF;
349 *rf1
= detectFSKClk(bits
, size
, *fc1
, *fc2
, firstClockEdge
);
354 PrintAndLogEx(DEBUG
, "DEBUG: Clock detect error");