forked from crankyoldgit/IRremoteESP8266
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcode_to_raw.cpp
148 lines (129 loc) · 4.38 KB
/
code_to_raw.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
// Quick and dirty tool to convert a protocol's (hex) codes to raw timings.
// Copyright 2021 David Conran
#include <errno.h>
#include <inttypes.h>
#include <stdio.h>
#include <string.h>
#include <string>
#include "IRac.h"
#include "IRsend.h"
#include "IRsend_test.h"
#include "IRutils.h"
void usage_error(char *name) {
std::cerr << "Usage: " << name
<< " --protocol PROTOCOL_NAME"
<< " --code <hexidecimal>"
<< " [--bits 1-" << kStateSizeMax * 8 << "]"
<< " [--timinginfo]"
<< std::endl;
}
int main(int argc, char *argv[]) {
int argv_offset = 1;
int repeats = 0;
uint64_t code = 0;
uint8_t state[kStateSizeMax] = {0}; // All array elements are set to 0.
decode_type_t input_type = decode_type_t::UNKNOWN;
bool timinginfo = false;
// Check the invocation/calling usage.
if (argc < 5 || argc > 8) {
usage_error(argv[0]);
return 1;
}
if (strncmp("--protocol", argv[argv_offset], 11) == 0) {
argv_offset++;
input_type = strToDecodeType(argv[argv_offset]);
switch (input_type) {
// Unsupported types
case decode_type_t::UNUSED:
case decode_type_t::UNKNOWN:
case decode_type_t::GLOBALCACHE:
case decode_type_t::PRONTO:
case decode_type_t::RAW:
std::cerr << "The protocol specified is not supported by this program."
<< std::endl;
return 1;
default:
break;
}
argv_offset++;
}
uint16_t nbits = IRsend::defaultBits(input_type);
uint16_t stateSize = nbits / 8;
if (strncmp("--code", argv[argv_offset], 7) == 0) {
argv_offset++;
String hexstr = String(argv[argv_offset]);
uint64_t strOffset = 0;
if (hexstr.rfind("0x", 0) || hexstr.rfind("0X", 0)) strOffset = 2;
// Calculate how many hexadecimal characters there are.
uint64_t hexstrlength = hexstr.length() - strOffset;
// Ptr to the least significant byte of the resulting state for this
// protocol.
uint8_t *statePtr = &state[stateSize - 1];
// Convert the string into a state array of the correct length.
for (uint16_t i = 0; i < hexstrlength; i++) {
// Grab the next least sigificant hexadecimal digit from the string.
uint8_t c = tolower(hexstr[hexstrlength + strOffset - i - 1]);
if (isxdigit(c)) {
if (isdigit(c))
c -= '0';
else
c = c - 'a' + 10;
} else {
std::cerr << "Code " << argv[argv_offset]
<< " contains non-hexidecimal characters." << std::endl;
return 3;
}
if (i % 2 == 1) { // Odd: Upper half of the byte.
*statePtr += (c << 4);
statePtr--; // Advance up to the next least significant byte of state.
} else { // Even: Lower half of the byte.
*statePtr = c;
}
}
if (!hasACState(input_type))
code = std::stoull(argv[argv_offset], nullptr, 16);
argv_offset++;
}
if (argc - argv_offset > 0 && strncmp("--bits", argv[argv_offset], 7) == 0) {
argv_offset++;
nbits = std::stoul(argv[argv_offset], nullptr, 10);
if (nbits == 0 && (nbits <= kStateSizeMax * 8)) {
std::cerr << "Nr. of bits " << argv[argv_offset]
<< " is invalid." << std::endl;
return 1;
}
stateSize = nbits / 8;
argv_offset++;
}
if (argc - argv_offset > 0 &&
strncmp("--timinginfo", argv[argv_offset], 13) == 0) {
argv_offset++;
timinginfo = true;
}
if (argc - argv_offset != 0) {
usage_error(argv[0]);
return 1;
}
IRsendTest irsend(kGpioUnused);
IRrecv irrecv(kGpioUnused);
irsend.begin();
irsend.reset();
if (hasACState(input_type)) // Is it larger than 64 bits?
irsend.send(input_type, state, stateSize);
else
irsend.send(input_type, code, nbits, repeats);
irsend.makeDecodeResult();
irrecv.decode(&irsend.capture);
std::cout << "Code type: " << irsend.capture.decode_type << " ("
<< typeToString(irsend.capture.decode_type) << ")" << std::endl
<< "Code bits: " << irsend.capture.bits << std::endl;
if (hasACState(irsend.capture.decode_type)) {
String description = IRAcUtils::resultAcToString(&irsend.capture);
if (description.length()) {
std::cout << "Description: " << description.c_str() << std::endl;
}
}
std::cout << std::endl << resultToSourceCode(&irsend.capture) << std::endl;
if (timinginfo) std::cout << resultToTimingInfo(&irsend.capture);
return 0;
}