1
1
/* *
2
2
* @file SignalParser.cpp
3
- *
3
+ *
4
4
* This file is part of the RFCodes library that implements receiving an sending
5
5
* RF and IR protocols.
6
- *
6
+ *
7
7
* @copyright Copyright (c) by Matthias Hertel, https://www.mathertel.de.
8
8
*
9
9
* This work is licensed under a BSD 3-Clause style license,
10
10
* https://www.mathertel.de/License.aspx.
11
- *
11
+ *
12
12
* @brief
13
13
* This signal parser recognizes patterns in timing code sequences that are
14
14
* defined by declarative tables.
15
- *
15
+ *
16
16
* Change History see SignalParser.h
17
17
*/
18
18
25
25
26
26
27
27
/* * find protocol by name */
28
- SignalParser::Protocol *SignalParser::_findProt (char *name)
29
- {
28
+ SignalParser::Protocol *SignalParser::_findProt (char *name) {
30
29
Protocol *p = nullptr ;
31
30
32
31
for (int n = 0 ; n < _protocolCount; n++) {
@@ -35,12 +34,11 @@ SignalParser::Protocol *SignalParser::_findProt(char *name)
35
34
break ;
36
35
}
37
36
return (p);
38
- } // _findProt()
37
+ } // _findProt()
39
38
40
39
41
40
/* * find code by name */
42
- SignalParser::Code *SignalParser::_findCode (Protocol *p, char codeName)
43
- {
41
+ SignalParser::Code *SignalParser::_findCode (Protocol *p, char codeName) {
44
42
Code *c = p->codes ;
45
43
int cnt = p->codeLength ;
46
44
@@ -51,50 +49,48 @@ SignalParser::Code *SignalParser::_findCode(Protocol *p, char codeName)
51
49
cnt--;
52
50
}
53
51
return (cnt ? c : nullptr );
54
- } // _findCode()
52
+ } // _findCode()
55
53
56
54
57
55
/* * reset all codes in a protocol */
58
- void SignalParser::_resetCodes (Protocol *p)
59
- {
56
+ void SignalParser::_resetCodes (Protocol *p) {
60
57
Code *c = p->codes ;
61
58
int cCnt = p->codeLength ;
62
59
while (c && cCnt) {
63
60
c->valid = true ;
64
61
c->cnt = 0 ;
62
+ c->total = 0 ;
65
63
66
64
c++;
67
65
cCnt--;
68
66
}
69
- } // _resetCodes()
67
+ } // _resetCodes()
70
68
71
69
72
70
/* * reset the whole protocol to start capturing from scratch. */
73
- void SignalParser::_resetProtocol (Protocol *p)
74
- {
71
+ void SignalParser::_resetProtocol (Protocol *p) {
75
72
TRACE_MSG (" reset prot: %s" , p->name );
76
73
p->seqLen = 0 ;
77
74
p->seq [0 ] = NUL;
78
75
_resetCodes (p);
79
- } // _resetProtocol()
76
+ _recalcProtocol (p, p->baseTime );
77
+ } // _resetProtocol()
80
78
81
79
82
80
/* * use the callback function when registered using format <protocolname> <sequence> */
83
- void SignalParser::_useCallback (Protocol *p)
84
- {
81
+ void SignalParser::_useCallback (Protocol *p) {
85
82
if (p && _callbackFunc) {
86
83
String code;
87
84
code += p->name ;
88
85
code += ' ' ;
89
86
code += p->seq ;
90
87
_callbackFunc (code.c_str ());
91
88
}
92
- } // _useCallback()
89
+ } // _useCallback()
93
90
94
91
95
92
/* * check if the duration fits for the protocol */
96
- void SignalParser::_parseProtocol (Protocol *p, CodeTime duration)
97
- {
93
+ void SignalParser::_parseProtocol (Protocol *p, CodeTime duration) {
98
94
Code *c = p->codes ;
99
95
int cCnt = p->codeLength ;
100
96
bool anyValid = false ;
@@ -106,7 +102,7 @@ void SignalParser::_parseProtocol(Protocol *p, CodeTime duration)
106
102
// check if timing fits into this code
107
103
int8_t i = c->cnt ;
108
104
CodeType type = c->type ;
109
- bool matched = false ; // until found that the new duration fits
105
+ bool matched = false ; // until found that the new duration fits
110
106
111
107
TRACE_MSG (" check: %c" , c->name );
112
108
@@ -129,8 +125,10 @@ void SignalParser::_parseProtocol(Protocol *p, CodeTime duration)
129
125
}
130
126
131
127
} else {
132
- matched = true ; // this code matches
133
- } // if
128
+ matched = true ; // this code matches
129
+ c->total += duration;
130
+
131
+ } // if
134
132
135
133
// write back to code
136
134
c->valid = matched;
@@ -150,11 +148,21 @@ void SignalParser::_parseProtocol(Protocol *p, CodeTime duration)
150
148
151
149
if (i == c->timeLength ) {
152
150
// all timings received so add code-character.
151
+ if (p->seqLen == 0 ) {
152
+ TRACE_MSG (" start: %s %d" , p->name , c->total );
153
+ int allTimes = 0 ;
154
+ for (int tl = 0 ; tl < c->timeLength ; tl++) {
155
+ allTimes += c->time [tl];
156
+ }
157
+ _recalcProtocol (p, c->total / allTimes);
158
+ }
159
+
153
160
p->seq [p->seqLen ++] = c->name ;
154
161
p->seq [p->seqLen ] = NUL;
155
162
// DEBUG_ESP_PORT.print(c->name);
156
163
TRACE_MSG (" add '%s'" , p->seq );
157
- _resetCodes (p); // reset all codes but not the protocol
164
+
165
+ _resetCodes (p); // reset all codes but not the protocol
158
166
159
167
if ((type == END) && (p->seqLen < p->minCodeLen )) {
160
168
// End packet found but sequence was not started early enough
@@ -171,10 +179,10 @@ void SignalParser::_parseProtocol(Protocol *p, CodeTime duration)
171
179
_useCallback (p);
172
180
_resetProtocol (p);
173
181
}
174
- break ; // no more code checking in this protocol
175
- } // if
182
+ break ; // no more code checking in this protocol
183
+ } // if
176
184
}
177
- } // if (c->valid)
185
+ } // if (c->valid)
178
186
179
187
if (retryCandidate) {
180
188
// only loop once
@@ -184,50 +192,46 @@ void SignalParser::_parseProtocol(Protocol *p, CodeTime duration)
184
192
c++;
185
193
cCnt--;
186
194
}
187
- } // while
195
+ } // while
188
196
189
197
if (!anyValid) {
190
198
TRACE_MSG (" no codes." );
191
199
_resetProtocol (p);
192
200
}
193
- } // _parseProtocol()
201
+ } // _parseProtocol()
194
202
195
203
196
204
// ===== public functions =====
197
205
198
206
199
207
/* * attach a callback function that will get passed any new code. */
200
- void SignalParser::attachCallback (CallbackFunction newFunction)
201
- {
208
+ void SignalParser::attachCallback (CallbackFunction newFunction) {
202
209
_callbackFunc = newFunction;
203
- } // attachCallback()
210
+ } // attachCallback()
204
211
205
212
206
213
// return the number of send repeats that should occure.
207
- int SignalParser::getSendRepeat (char *name)
208
- {
214
+ int SignalParser::getSendRepeat (char *name) {
209
215
Protocol *p = _findProt (name);
210
216
return (p ? p->sendRepeat : 0 );
211
217
}
212
218
213
219
/* * parse a single duration.
214
220
* @param duration check if this duration fits to any definitions.
215
221
*/
216
- void SignalParser::parse (CodeTime duration)
217
- {
222
+ void SignalParser::parse (CodeTime duration) {
218
223
TRACE_MSG (" (%d)" , duration);
219
224
220
225
for (int n = 0 ; n < _protocolCount; n++) {
221
226
_parseProtocol (_protocol[n], duration);
222
227
}
223
- } // parse()
228
+ } // parse()
224
229
225
230
226
231
/* * compose the timings of a sequence by using the code table.
227
232
* @param sequence textual representation using "<protocolname> <codes>".
228
233
*/
229
- void SignalParser::compose (const char *sequence, CodeTime *timings, int len)
230
- {
234
+ void SignalParser::compose (const char *sequence, CodeTime *timings, int len) {
231
235
char protname[PROTNAME_LEN];
232
236
233
237
char *s = strchr (sequence, ' ' );
@@ -244,27 +248,47 @@ void SignalParser::compose(const char *sequence, CodeTime *timings, int len)
244
248
}
245
249
Protocol *p = _findProt (protname);
246
250
247
- s++; // to start of code characters
251
+ s++; // to start of code characters
248
252
249
253
if (p && timings) {
250
254
while (*s && len) {
251
255
Code *c = _findCode (p, *s);
252
256
if (c) {
253
257
for (int i = 0 ; i < c->timeLength ; i++) {
254
258
*timings++ = (c->minTime [i] + c->maxTime [i]) / 2 ;
255
- } // for
259
+ } // for
256
260
}
257
261
s++;
258
262
len--;
259
263
}
260
264
*timings = 0 ;
261
- } // if
265
+ } // if
266
+ }
267
+ } // compose()
268
+
269
+
270
+ void SignalParser::_recalcProtocol (Protocol *protocol, CodeTime baseTime) {
271
+ // calc min and max and codesLength
272
+ if (protocol->baseTime != baseTime) {
273
+ TRACE_MSG (" recalc %d" , baseTime);
262
274
}
263
- } // compose()
275
+
276
+ for (int cl = 0 ; cl < protocol->codeLength ; cl++) {
277
+ Code *c = &(protocol->codes [cl]);
278
+
279
+ for (int tl = 0 ; tl < c->timeLength ; tl++) {
280
+ CodeTime t = baseTime * c->time [tl];
281
+ int radius = (t * protocol->tolerance ) / 100 ;
282
+ c->minTime [tl] = t - radius;
283
+ c->maxTime [tl] = t + radius;
284
+ }
285
+ }
286
+ } // _recalcProtocol()
287
+
264
288
265
289
/* * Load a protocol to be used. */
266
- void SignalParser::load (Protocol *protocol)
267
- {
290
+ // @param otherBaseTime not in use yet.
291
+ void SignalParser::load (Protocol *protocol, CodeTime otherBaseTime) {
268
292
if (protocol) {
269
293
TRACE_MSG (" loading protocol %s" , protocol->name );
270
294
@@ -282,36 +306,29 @@ void SignalParser::load(Protocol *protocol)
282
306
283
307
CodeTime baseTime = protocol->baseTime ;
284
308
285
- // calc min and max and codesLength
309
+ // calc c->timeLength and p->codeLength
286
310
int cl = 0 ;
287
311
while ((cl < MAX_CODELENGTH) && (protocol->codes [cl].name )) {
288
312
Code *c = &(protocol->codes [cl]);
289
313
290
- // calculate # of durations and absolute timing boundaries
291
314
int tl = 0 ;
292
315
while ((tl < MAX_TIMELENGTH) && (c->time [tl])) {
293
- CodeTime t = baseTime * c->time [tl];
294
- int radius = (t * protocol->tolerance ) / 100 ;
295
- TRACE_MSG (" == %d %d %d %d " , baseTime, c->time [tl], t, radius);
296
-
297
- c->minTime [tl] = t - radius;
298
- c->maxTime [tl] = t + radius;
299
316
tl++;
300
- } // while
317
+ } // while
301
318
c->timeLength = tl;
302
-
303
319
cl++;
304
- } // while
305
- protocol->codeLength = cl; // no need to specify codeLength
320
+ } // while
321
+ protocol->codeLength = cl; // no need to specify codeLength
306
322
323
+ _recalcProtocol (protocol, baseTime);
307
324
_resetProtocol (protocol);
308
325
309
326
for (int n = 0 ; n < _protocolCount; n++) {
310
327
TRACE_MSG (" reg[%d] = %08x" , n, _protocol[n]);
311
- } // for
328
+ } // for
312
329
313
330
314
- } // if
315
- } // load()
331
+ } // if
332
+ } // load()
316
333
317
334
// End.
0 commit comments