43 ESP_LOGD(TAG,
"Send Keeloq: address=%07" PRIx32
" command=%03x encrypted=%08" PRIx32
" suffix_bits=%u", data.address,
44 data.command, data.encrypted, data.suffix_bits);
45 ESP_LOGV(TAG,
"Send Keeloq: data bits (%d + %d)", NBITS_ENCRYPTED_DATA, NBITS_FIXED_DATA);
48 for (uint8_t cnt = NBITS_PREAMBLE; cnt; cnt--) {
49 dst->
space(BIT_TIME_US);
50 dst->
mark(BIT_TIME_US);
54 dst->
space(10 * BIT_TIME_US);
57 out_data = data.encrypted;
59 ESP_LOGV(TAG,
"Send Keeloq: Encrypted data %04" PRIx32, out_data);
61 for (
uint32_t mask = 1, cnt = 0; cnt < NBITS_ENCRYPTED_DATA; cnt++, mask <<= 1) {
62 if (out_data & mask) {
63 dst->
mark(1 * BIT_TIME_US);
64 dst->
space(2 * BIT_TIME_US);
66 dst->
mark(2 * BIT_TIME_US);
67 dst->
space(1 * BIT_TIME_US);
72 out_data = (data.command & 0x0f);
73 out_data <<= NBITS_SERIAL;
74 out_data |= data.address;
75 ESP_LOGV(TAG,
"Send Keeloq: Fixed data %04" PRIx32, out_data);
77 for (
uint32_t mask = 1, cnt = 0; cnt < (NBITS_FIXED_DATA - 2); cnt++, mask <<= 1) {
78 if (out_data & mask) {
79 dst->
mark(1 * BIT_TIME_US);
80 dst->
space(2 * BIT_TIME_US);
82 dst->
mark(2 * BIT_TIME_US);
83 dst->
space(1 * BIT_TIME_US);
89 dst->
mark(1 * BIT_TIME_US);
90 dst->
space(2 * BIT_TIME_US);
92 dst->
mark(2 * BIT_TIME_US);
93 dst->
space(1 * BIT_TIME_US);
98 dst->
mark(1 * BIT_TIME_US);
99 dst->
space(2 * BIT_TIME_US);
101 dst->
mark(2 * BIT_TIME_US);
102 dst->
space(1 * BIT_TIME_US);
105 const uint8_t extra = data.suffix_bits > NBITS_SUFFIX_MAX ? NBITS_SUFFIX_MAX : data.suffix_bits;
106 for (uint8_t i = 0; i < extra; i++) {
107 if (data.suffix & (1 << i)) {
108 dst->
mark(1 * BIT_TIME_US);
109 dst->
space(2 * BIT_TIME_US);
111 dst->
mark(2 * BIT_TIME_US);
112 dst->
space(1 * BIT_TIME_US);
117 dst->
space(39 * BIT_TIME_US);
131 if (
src.size() < (NBITS_PREAMBLE + NBITS_DATA) * 2) {
136 "%2" PRId32
": %" PRId32
" %" PRId32
" %" PRId32
" %" PRId32
" %" PRId32
" %" PRId32
" %" PRId32
" %" PRId32
137 " %" PRId32
" %" PRId32
" %" PRId32
" %" PRId32
" %" PRId32
" %" PRId32
" %" PRId32
" %" PRId32
" %" PRId32
138 " %" PRId32
" %" PRId32
" %" PRId32,
144 int8_t bit = NBITS_PREAMBLE - 1;
146 if (!
src.expect_mark(BIT_TIME_US) || !
src.expect_space(BIT_TIME_US)) {
147 ESP_LOGV(TAG,
"Decode KeeLoq: Fail 1, %d %" PRId32, bit + 1,
src.peek());
151 if (!
src.expect_mark(BIT_TIME_US) || !
src.expect_space(10 * BIT_TIME_US)) {
152 ESP_LOGV(TAG,
"Decode KeeLoq: Fail 1, %d %" PRId32, bit + 1,
src.peek());
158 for (bit = 0; bit < NBITS_ENCRYPTED_DATA; bit++) {
159 if (
src.expect_mark(2 * BIT_TIME_US) &&
src.expect_space(BIT_TIME_US)) {
160 out_data |= 0 << bit;
161 }
else if (
src.expect_mark(BIT_TIME_US) &&
src.expect_space(2 * BIT_TIME_US)) {
162 out_data |= 1 << bit;
164 ESP_LOGV(TAG,
"Decode KeeLoq: Fail 2, %" PRIu32
" %" PRId32,
src.get_index(),
src.peek());
168 ESP_LOGVV(TAG,
"Decode KeeLoq: Data, %d %08" PRIx32, bit, out_data);
169 out.encrypted = out_data;
173 for (bit = 0; bit < NBITS_SERIAL + NBITS_BUTTONS; bit++) {
174 if (
src.expect_mark(2 * BIT_TIME_US) &&
src.expect_space(BIT_TIME_US)) {
175 out_data |= 0 << bit;
176 }
else if (
src.expect_mark(BIT_TIME_US) &&
src.expect_space(2 * BIT_TIME_US)) {
177 out_data |= 1 << bit;
179 ESP_LOGV(TAG,
"Decode KeeLoq: Fail 3, %" PRIu32
" %" PRId32,
src.get_index(),
src.peek());
183 ESP_LOGVV(TAG,
"Decode KeeLoq: Data, %2d %08" PRIx32, bit, out_data);
184 out.command = (out_data >> 28) & 0xf;
185 out.address = out_data & 0xfffffff;
188 if (
src.expect_mark(2 * BIT_TIME_US) &&
src.expect_space(BIT_TIME_US)) {
190 }
else if (
src.expect_mark(BIT_TIME_US) &&
src.expect_space(2 * BIT_TIME_US)) {
193 ESP_LOGV(TAG,
"Decode KeeLoq: Fail 4, %" PRId32,
src.peek());
198 if (
src.expect_mark(2 * BIT_TIME_US) &&
src.peek_space_at_least(BIT_TIME_US)) {
200 }
else if (
src.expect_mark(BIT_TIME_US) &&
src.peek_space_at_least(2 * BIT_TIME_US)) {
203 ESP_LOGV(TAG,
"Decode KeeLoq: Fail 5, %" PRId32,
src.peek());
208 src.expect_space(2 * BIT_TIME_US);
210 src.expect_space(BIT_TIME_US);
213 while (
out.suffix_bits < NBITS_SUFFIX_MAX) {
215 if (
src.expect_mark(2 * BIT_TIME_US)) {
217 }
else if (
src.expect_mark(BIT_TIME_US)) {
223 if (!
src.expect_space(one ? 2 * BIT_TIME_US : BIT_TIME_US) &&
src.is_valid() &&
224 !
src.peek_space_at_least(GAP_TIME_US)) {
228 out.suffix |= 1 <<
out.suffix_bits;
233 if (
src.is_valid() && !
src.peek_space_at_least(GAP_TIME_US)) {
242 if (data.suffix_bits == 6) {
244 ESP_LOGD(TAG,
"Received Keeloq: address=0x%08" PRIx32
", command=0x%02x, encrypted=0x%08" PRIx32
", group=0x%02x",
245 data.address, data.command, data.encrypted, data.group());
248 ESP_LOGD(TAG,
"Received Keeloq: address=0x%08" PRIx32
", command=0x%02x, encrypted=0x%08" PRIx32
", suffix=0x%04x/%u",
249 data.address, data.command, data.encrypted, data.suffix, data.suffix_bits);