portapack-mayhem/firmware/application/ook_file.cpp

159 lines
6.3 KiB
C++
Raw Permalink Normal View History

/*
* Copyright (C) 2024 gullradriel
*
* 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 "ook_file.hpp"
using namespace portapack;
namespace fs = std::filesystem;
/*
struct of an OOK file:
Frequency SampleRate SymbolRate Repeat PauseSymbolDuration Payload
-Frequency is in hertz
-SampleRate is one of 250k, 1M, 2M, 5M , 10M ,20M
-SymbolRate is the number of symbols /s
-Repeat is the number of times we will repeat the payload
-PauseSymbolDuration is the duration of the pause between repeat, in usec
-Payload is the payload in form of a string of 0 and 1
*/
bool read_ook_file(const std::filesystem::path& path, ook_file_data& ook_data) {
File data_file;
auto open_result = data_file.open(path);
if (open_result) {
return false;
}
FileLineReader reader(data_file);
for (const auto& line : reader) {
// Split the line into segments to extract each value
size_t first_space = line.find(' ');
size_t second_space = line.find(' ', first_space + 1);
size_t third_space = line.find(' ', second_space + 1);
size_t fourth_space = line.find(' ', third_space + 1);
size_t fifth_space = line.find(' ', fourth_space + 1);
// Extract each component of the line
std::string frequency_str = line.substr(0, first_space);
std::string sample_rate_str = line.substr(first_space + 1, second_space - first_space - 1);
std::string symbol_rate_str = line.substr(second_space + 1, third_space - second_space - 1);
std::string repeat_str = line.substr(third_space + 1, fourth_space - third_space - 1);
std::string pause_symbol_duration_str = line.substr(fourth_space + 1, fifth_space - fourth_space - 1);
std::string payload_data = line.substr(fifth_space + 1); // Extract binary payload as final value
// Convert and assign frequency
ook_data.frequency = std::stoull(frequency_str);
// Convert and assign symbol_rate
ook_data.symbol_rate = static_cast<unsigned int>(atoi(symbol_rate_str.c_str()));
// Convert and assign repeat count
ook_data.repeat = static_cast<unsigned int>(atoi(repeat_str.c_str()));
// Convert and assign pause_symbol_duration
ook_data.pause_symbol_duration = static_cast<unsigned int>(atoi(pause_symbol_duration_str.c_str()));
// Select sample rate based on value read from file
if (sample_rate_str == "250k") {
ook_data.sample_rate = 250000U;
} else if (sample_rate_str == "1M") {
ook_data.sample_rate = 1000000U;
} else if (sample_rate_str == "2M") {
ook_data.sample_rate = 2000000U;
} else if (sample_rate_str == "5M") {
ook_data.sample_rate = 5000000U;
} else if (sample_rate_str == "10M") {
ook_data.sample_rate = 10000000U;
} else if (sample_rate_str == "20M") {
ook_data.sample_rate = 20000000U;
} else {
return false;
}
// Update payload with binary data
ook_data.payload = std::move(payload_data);
// Process only the first line
break;
}
return true;
}
bool save_ook_file(ook_file_data& ook_data, const std::filesystem::path& path) {
// delete file if it exists
delete_file(path);
// Attempt to open, if it can't be opened. Create new.
auto src = std::make_unique<File>();
auto error = src->open(path, false, true);
if (error) {
return false;
}
std::string sample_rate_str;
if (ook_data.sample_rate == 250000U) {
sample_rate_str = "250k";
} else if (ook_data.sample_rate == 1000000U) {
sample_rate_str = "1M";
} else if (ook_data.sample_rate == 2000000U) {
sample_rate_str = "2M";
} else if (ook_data.sample_rate == 5000000U) {
sample_rate_str = "5M";
} else if (ook_data.sample_rate == 10000000U) {
sample_rate_str = "10M";
} else if (ook_data.sample_rate == 20000000U) {
sample_rate_str = "20M";
} else {
return false;
}
// write informations
src->write_line(to_string_dec_uint(ook_data.frequency) + " " +
sample_rate_str + " " +
to_string_dec_uint(ook_data.symbol_rate) + " " +
to_string_dec_uint(ook_data.repeat) + " " +
to_string_dec_uint(ook_data.pause_symbol_duration) + " " +
ook_data.payload);
// Close files
src.reset();
return true;
}
void start_ook_file_tx(ook_file_data& ook_data) {
size_t bitstream_length = encoders::make_bitstream(const_cast<std::string&>(ook_data.payload)); // Convert the message into a bitstream
transmitter_model.set_target_frequency(ook_data.frequency); // Set target frequency
transmitter_model.set_sampling_rate(ook_data.sample_rate); // Set the OOK sampling rate
transmitter_model.set_baseband_bandwidth(1750000); // Set the baseband bandwidth
transmitter_model.enable(); // Enable the transmitter
// Configure OOK data and transmission characteristics
baseband::set_ook_data(
bitstream_length, // Length of the bitstream to transmit
ook_data.sample_rate / ook_data.symbol_rate, // Calculate symbol period based on repetition rate
ook_data.repeat, // Set the number of times the whole bitstream is repeated
ook_data.pause_symbol_duration // Set the pause_symbol between reps
);
}
void stop_ook_file_tx() {
transmitter_model.disable(); // Disable the transmitter
}