/* * Copyright (C) 2015 Jared Boone, ShareBrained Technology, Inc. * Copyright (C) 2016 Furrtek * Copyright (C) 2020 Shao * * This file is part of PortaPack. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; see the file COPYING. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, * Boston, MA 02110-1301, USA. */ #include "proc_btlerx.hpp" #include "portapack_shared_memory.hpp" #include "event_m4.hpp" void BTLERxProcessor::execute(const buffer_c8_t& buffer) { if (!configured) return; // FM demodulation /*const auto decim_0_out = decim_0.execute(buffer, dst_buffer); const auto channel = decim_1.execute(decim_0_out, dst_buffer); feed_channel_stats(channel); auto audio_oversampled = demod.execute(channel, work_audio_buffer);*/ const auto decim_0_out = decim_0.execute(buffer, dst_buffer); feed_channel_stats(decim_0_out); auto audio_oversampled = demod.execute(decim_0_out, work_audio_buffer); /*std::fill(spectrum.begin(), spectrum.end(), 0); for(size_t i=0; i g_threshold) { for (int c = 0; c < 8; c++) { if (rb_buf[(rb_head + c) % RB_SIZE] > rb_buf[(rb_head + c + 1) % RB_SIZE]) transitions = transitions + 1; } } else { for (int c = 0; c < 8; c++) { if (rb_buf[(rb_head + c) % RB_SIZE] < rb_buf[(rb_head + c + 1) % RB_SIZE]) transitions = transitions + 1; } } bool packet_detected = false; // if ( transitions==4 && abs(g_threshold)<15500) if (transitions == 4) { uint8_t packet_data[500]; int packet_length; uint32_t packet_crc; // uint32_t calced_crc; // NOTE: restore when CRC is passing uint64_t packet_addr_l; // uint32_t result; // NOTE: restore when CRC is passing uint8_t crc[3]; uint8_t packet_header_arr[2]; packet_addr_l = 0; for (int i = 0; i < 4; i++) { bool current_bit; uint8_t byte = 0; for (int c = 0; c < 8; c++) { if (rb_buf[(rb_head + (i + 1) * 8 + c) % RB_SIZE] > g_threshold) current_bit = true; else current_bit = false; byte |= current_bit << (7 - c); } uint8_t byte_temp = (uint8_t)(((byte * 0x0802LU & 0x22110LU) | (byte * 0x8020LU & 0x88440LU)) * 0x10101LU >> 16); packet_addr_l |= ((uint64_t)byte_temp) << (8 * i); } channel_number = 38; for (int t = 0; t < 2; t++) { bool current_bit; uint8_t byte = 0; for (int c = 0; c < 8; c++) { if (rb_buf[(rb_head + 5 * 8 + t * 8 + c) % RB_SIZE] > g_threshold) current_bit = true; else current_bit = false; byte |= current_bit << (7 - c); } packet_header_arr[t] = byte; } uint8_t byte_temp2 = (uint8_t)(((channel_number * 0x0802LU & 0x22110LU) | (channel_number * 0x8020LU & 0x88440LU)) * 0x10101LU >> 16); uint8_t lfsr_1 = byte_temp2 | 2; int header_length = 2; int header_counter = 0; while (header_length--) { for (uint8_t i = 0x80; i; i >>= 1) { if (lfsr_1 & 0x80) { lfsr_1 ^= 0x11; (packet_header_arr[header_counter]) ^= i; } lfsr_1 <<= 1; } header_counter = header_counter + 1; } if (packet_addr_l == 0x8E89BED6) { uint8_t byte_temp3 = (uint8_t)(((packet_header_arr[1] * 0x0802LU & 0x22110LU) | (packet_header_arr[1] * 0x8020LU & 0x88440LU)) * 0x10101LU >> 16); packet_length = byte_temp3 & 0x3F; } else { packet_length = 0; } for (int t = 0; t < packet_length + 2 + 3; t++) { bool current_bit; uint8_t byte = 0; for (int c = 0; c < 8; c++) { if (rb_buf[(rb_head + 5 * 8 + t * 8 + c) % RB_SIZE] > g_threshold) current_bit = true; else current_bit = false; byte |= current_bit << (7 - c); } packet_data[t] = byte; } uint8_t byte_temp4 = (uint8_t)(((channel_number * 0x0802LU & 0x22110LU) | (channel_number * 0x8020LU & 0x88440LU)) * 0x10101LU >> 16); uint8_t lfsr_2 = byte_temp4 | 2; int pdu_crc_length = packet_length + 2 + 3; int pdu_crc_counter = 0; while (pdu_crc_length--) { for (uint8_t i = 0x80; i; i >>= 1) { if (lfsr_2 & 0x80) { lfsr_2 ^= 0x11; (packet_data[pdu_crc_counter]) ^= i; } lfsr_2 <<= 1; } pdu_crc_counter = pdu_crc_counter + 1; } if (packet_addr_l == 0x8E89BED6) { crc[0] = crc[1] = crc[2] = 0x55; } else { crc[0] = crc[1] = crc[2] = 0; } uint8_t v, t, d, crc_length; uint32_t crc_result = 0; crc_length = packet_length + 2; int counter = 0; while (crc_length--) { uint8_t byte_temp5 = (uint8_t)(((packet_data[counter] * 0x0802LU & 0x22110LU) | (packet_data[counter] * 0x8020LU & 0x88440LU)) * 0x10101LU >> 16); d = byte_temp5; for (v = 0; v < 8; v++, d >>= 1) { t = crc[0] >> 7; crc[0] <<= 1; if (crc[1] & 0x80) crc[0] |= 1; crc[1] <<= 1; if (crc[2] & 0x80) crc[1] |= 1; crc[2] <<= 1; if (t != (d & 1)) { crc[2] ^= 0x5B; crc[1] ^= 0x06; } } counter = counter + 1; } for (v = 0; v < 3; v++) crc_result = (crc_result << 8) | crc[v]; // calced_crc = crc_result; // NOTE: restore when CRC is passing packet_crc = 0; for (int c = 0; c < 3; c++) packet_crc = (packet_crc << 8) | packet_data[packet_length + 2 + c]; if (packet_addr_l == 0x8E89BED6) // if (packet_crc==calced_crc) // NOTE: restore when CRC is passing { uint8_t mac_data[6]; int counter = 0; for (int i = 7; i >= 2; i--) { uint8_t byte_temp6 = (uint8_t)(((packet_data[i] * 0x0802LU & 0x22110LU) | (packet_data[i] * 0x8020LU & 0x88440LU)) * 0x10101LU >> 16); // result = byte_temp6; // NOTE: restore when CRC is passing mac_data[counter] = byte_temp6; counter = counter + 1; } data_message.is_data = false; data_message.value = 'A'; shared_memory.application_queue.push(data_message); data_message.is_data = true; data_message.value = mac_data[0]; shared_memory.application_queue.push(data_message); data_message.is_data = true; data_message.value = mac_data[1]; shared_memory.application_queue.push(data_message); data_message.is_data = true; data_message.value = mac_data[2]; shared_memory.application_queue.push(data_message); data_message.is_data = true; data_message.value = mac_data[3]; shared_memory.application_queue.push(data_message); data_message.is_data = true; data_message.value = mac_data[4]; shared_memory.application_queue.push(data_message); data_message.is_data = true; data_message.value = mac_data[5]; shared_memory.application_queue.push(data_message); data_message.is_data = false; data_message.value = 'B'; shared_memory.application_queue.push(data_message); packet_detected = true; } else packet_detected = false; } if (packet_detected) { skipSamples = 20; } } } } void BTLERxProcessor::on_message(const Message* const message) { if (message->id == Message::ID::BTLERxConfigure) configure(*reinterpret_cast(message)); } void BTLERxProcessor::configure(const BTLERxConfigureMessage& message) { (void)message; // avoid warning decim_0.configure(taps_200k_wfm_decim_0.taps); decim_1.configure(taps_200k_wfm_decim_1.taps); demod.configure(audio_fs, 5000); configured = true; } int main() { EventDispatcher event_dispatcher{std::make_unique()}; event_dispatcher.run(); return 0; }