mirror of
https://github.com/portapack-mayhem/mayhem-firmware.git
synced 2024-12-14 20:18:13 +00:00
Bletx multi packet (#1547)
* Added multiple packet support * Fixed Issue where default was RAW and discovery needed toggle to work on init * Added random MAC toggle
This commit is contained in:
parent
b5c244a09b
commit
0681117af6
@ -90,15 +90,10 @@ uint32_t stringToUint32(const std::string& str) {
|
|||||||
pos++;
|
pos++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if there are any non-digit characters left
|
|
||||||
if (pos < str.size()) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void readUntilSpace(File& file, char* result, std::size_t maxBufferSize) {
|
void readUntil(File& file, char* result, std::size_t maxBufferSize, char delimiter) {
|
||||||
std::size_t bytesRead = 0;
|
std::size_t bytesRead = 0;
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
@ -106,7 +101,7 @@ void readUntilSpace(File& file, char* result, std::size_t maxBufferSize) {
|
|||||||
File::Result<File::Size> readResult = file.read(&ch, 1);
|
File::Result<File::Size> readResult = file.read(&ch, 1);
|
||||||
|
|
||||||
if (readResult.is_ok() && readResult.value() > 0) {
|
if (readResult.is_ok() && readResult.value() > 0) {
|
||||||
if (ch == ' ') {
|
if (ch == delimiter) {
|
||||||
// Found a space character, stop reading
|
// Found a space character, stop reading
|
||||||
break;
|
break;
|
||||||
} else if (bytesRead < maxBufferSize) {
|
} else if (bytesRead < maxBufferSize) {
|
||||||
@ -125,6 +120,17 @@ void readUntilSpace(File& file, char* result, std::size_t maxBufferSize) {
|
|||||||
result[bytesRead] = '\0';
|
result[bytesRead] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void generateRandomMacAddress(char* macAddress) {
|
||||||
|
const char hexDigits[] = "0123456789ABCDEF";
|
||||||
|
|
||||||
|
// Generate 12 random hexadecimal characters
|
||||||
|
for (int i = 0; i < 12; i++) {
|
||||||
|
int randomIndex = rand() % 16;
|
||||||
|
macAddress[i] = hexDigits[randomIndex];
|
||||||
|
}
|
||||||
|
macAddress[12] = '\0'; // Null-terminate the string
|
||||||
|
}
|
||||||
|
|
||||||
static std::uint64_t get_freq_by_channel_number(uint8_t channel_number) {
|
static std::uint64_t get_freq_by_channel_number(uint8_t channel_number) {
|
||||||
uint64_t freq_hz;
|
uint64_t freq_hz;
|
||||||
|
|
||||||
@ -174,6 +180,9 @@ void BLETxView::toggle() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void BLETxView::start() {
|
void BLETxView::start() {
|
||||||
|
// Generate new random Mac Address.
|
||||||
|
generateRandomMacAddress(randomMac);
|
||||||
|
|
||||||
if (!is_active()) {
|
if (!is_active()) {
|
||||||
// Check if file is present before continuing.
|
// Check if file is present before continuing.
|
||||||
File data_file;
|
File data_file;
|
||||||
@ -185,16 +194,18 @@ void BLETxView::start() {
|
|||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
// Send first or single packet.
|
// Send first or single packet.
|
||||||
progressbar.set_max(packet_count);
|
packet_counter = packets[current_packet].packet_count;
|
||||||
|
progressbar.set_max(packets[current_packet].packet_count);
|
||||||
button_play.set_bitmap(&bitmap_stop);
|
button_play.set_bitmap(&bitmap_stop);
|
||||||
baseband::set_btletx(channel_number, macAddress, advertisementData, pduType);
|
|
||||||
|
baseband::set_btletx(channel_number, random_mac ? randomMac : packets[current_packet].macAddress, packets[current_packet].advertisementData, pduType);
|
||||||
transmitter_model.enable();
|
transmitter_model.enable();
|
||||||
|
|
||||||
is_running = true;
|
is_running = true;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Send next packet.
|
// Send next packet.
|
||||||
baseband::set_btletx(channel_number, macAddress, advertisementData, pduType);
|
baseband::set_btletx(channel_number, random_mac ? randomMac : packets[current_packet].macAddress, packets[current_packet].advertisementData, pduType);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((packet_counter % 10) == 0) {
|
if ((packet_counter % 10) == 0) {
|
||||||
@ -203,7 +214,7 @@ void BLETxView::start() {
|
|||||||
|
|
||||||
packet_counter--;
|
packet_counter--;
|
||||||
|
|
||||||
progressbar.set_value(packet_count - packet_counter);
|
progressbar.set_value(packets[current_packet].packet_count - packet_counter);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BLETxView::stop() {
|
void BLETxView::stop() {
|
||||||
@ -211,16 +222,32 @@ void BLETxView::stop() {
|
|||||||
progressbar.set_value(0);
|
progressbar.set_value(0);
|
||||||
button_play.set_bitmap(&bitmap_play);
|
button_play.set_bitmap(&bitmap_play);
|
||||||
check_loop.set_value(false);
|
check_loop.set_value(false);
|
||||||
text_packets_sent.set(to_string_dec_uint(packet_count));
|
|
||||||
packet_counter = packet_count;
|
current_packet = 0;
|
||||||
|
text_packets_sent.set(to_string_dec_uint(packets[0].packet_count));
|
||||||
|
packet_counter = packets[0].packet_count;
|
||||||
|
update_packet_display(packets[0]);
|
||||||
|
|
||||||
is_running = false;
|
is_running = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BLETxView::on_tx_progress(const bool done) {
|
void BLETxView::on_tx_progress(const bool done) {
|
||||||
if (done) {
|
if (done) {
|
||||||
if (check_loop.value() && (packet_counter != 0) && is_active()) {
|
if (check_loop.value() && is_active()) {
|
||||||
if ((timer_count % timer_period) == 0) {
|
// Reached end of current packet repeats.
|
||||||
start();
|
if (packet_counter == 0) {
|
||||||
|
// Done sending all packets.
|
||||||
|
if (current_packet == (num_packets - 1)) {
|
||||||
|
stop();
|
||||||
|
} else {
|
||||||
|
current_packet++;
|
||||||
|
packet_counter = packets[current_packet].packet_count;
|
||||||
|
update_packet_display(packets[current_packet]);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if ((timer_count % timer_period) == 0) {
|
||||||
|
start();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (is_active()) {
|
if (is_active()) {
|
||||||
@ -239,6 +266,7 @@ BLETxView::BLETxView(NavigationView& nav)
|
|||||||
add_children({&button_open,
|
add_children({&button_open,
|
||||||
&text_filename,
|
&text_filename,
|
||||||
&progressbar,
|
&progressbar,
|
||||||
|
&check_rand_mac,
|
||||||
&field_frequency,
|
&field_frequency,
|
||||||
&tx_view, // now it handles previous rfgain, rfamp.
|
&tx_view, // now it handles previous rfgain, rfamp.
|
||||||
&check_loop,
|
&check_loop,
|
||||||
@ -247,6 +275,8 @@ BLETxView::BLETxView(NavigationView& nav)
|
|||||||
&options_speed,
|
&options_speed,
|
||||||
&options_channel,
|
&options_channel,
|
||||||
&options_adv_type,
|
&options_adv_type,
|
||||||
|
&label_packet_index,
|
||||||
|
&text_packet_index,
|
||||||
&label_packets_sent,
|
&label_packets_sent,
|
||||||
&text_packets_sent,
|
&text_packets_sent,
|
||||||
&label_mac_address,
|
&label_mac_address,
|
||||||
@ -275,6 +305,11 @@ BLETxView::BLETxView(NavigationView& nav)
|
|||||||
|
|
||||||
options_speed.set_selected_index(0);
|
options_speed.set_selected_index(0);
|
||||||
|
|
||||||
|
check_rand_mac.set_value(false);
|
||||||
|
check_rand_mac.on_select = [this](Checkbox&, bool v) {
|
||||||
|
random_mac = v;
|
||||||
|
};
|
||||||
|
|
||||||
button_open.on_select = [this, &nav](Button&) {
|
button_open.on_select = [this, &nav](Button&) {
|
||||||
auto open_view = nav.push<FileLoadView>(".TXT");
|
auto open_view = nav.push<FileLoadView>(".TXT");
|
||||||
open_view->on_changed = [this](std::filesystem::path new_file_path) {
|
open_view->on_changed = [this](std::filesystem::path new_file_path) {
|
||||||
@ -295,40 +330,38 @@ void BLETxView::on_file_changed(const fs::path& new_file_path) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
readUntilSpace(data_file, macAddress, mac_address_size_str);
|
do {
|
||||||
readUntilSpace(data_file, advertisementData, max_packet_size_str);
|
readUntil(data_file, packets[num_packets].macAddress, mac_address_size_str, ' ');
|
||||||
readUntilSpace(data_file, packetCount, max_packet_count_str);
|
readUntil(data_file, packets[num_packets].advertisementData, max_packet_size_str, ' ');
|
||||||
|
readUntil(data_file, packets[num_packets].packetCount, max_packet_repeat_str, '\n');
|
||||||
|
|
||||||
uint64_t macAddressSize = strlen(macAddress);
|
uint64_t macAddressSize = strlen(packets[num_packets].macAddress);
|
||||||
uint64_t advertisementDataSize = strlen(advertisementData);
|
uint64_t advertisementDataSize = strlen(packets[num_packets].advertisementData);
|
||||||
uint64_t packetCountSize = strlen(packetCount);
|
uint64_t packetCountSize = strlen(packets[num_packets].packetCount);
|
||||||
|
|
||||||
packet_count = stringToUint32(packetCount);
|
packets[num_packets].packet_count = stringToUint32(packets[num_packets].packetCount);
|
||||||
packet_counter = packet_count;
|
packet_counter = packets[num_packets].packet_count;
|
||||||
|
|
||||||
// Verify Data.
|
// Verify Data.
|
||||||
if ((macAddressSize == mac_address_size_str) && (advertisementDataSize < max_packet_size_str) && (packetCountSize < max_packet_count_str) &&
|
if ((macAddressSize == mac_address_size_str) && (advertisementDataSize < max_packet_size_str) && (packetCountSize < max_packet_repeat_str) &&
|
||||||
hasValidHexPairs(macAddress, macAddressSize / 2) && hasValidHexPairs(advertisementData, advertisementDataSize / 2) && (packet_count > 0) && (packet_count < UINT32_MAX)) {
|
hasValidHexPairs(packets[num_packets].macAddress, macAddressSize / 2) && hasValidHexPairs(packets[num_packets].advertisementData, advertisementDataSize / 2) && (packets[num_packets].packet_count > 0) && (packets[num_packets].packet_count < max_packet_repeat_count)) {
|
||||||
text_packets_sent.set(to_string_dec_uint(packet_count));
|
text_filename.set(truncate(file_path.filename().string(), 12));
|
||||||
|
|
||||||
std::string formattedMacAddress = to_string_formatted_mac_address(macAddress);
|
} else {
|
||||||
|
// Did not find any packets.
|
||||||
|
if (num_packets == 0) {
|
||||||
|
file_path = "";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
text_mac_address.set(formattedMacAddress);
|
break;
|
||||||
|
|
||||||
std::vector<std::string> strings = splitIntoStrings(advertisementData);
|
|
||||||
|
|
||||||
console.clear(true);
|
|
||||||
|
|
||||||
for (const std::string& str : strings) {
|
|
||||||
console.writeln(str);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
text_filename.set(truncate(file_path.filename().string(), 12));
|
num_packets++;
|
||||||
} else {
|
|
||||||
// file_error();
|
} while (num_packets < max_num_packets);
|
||||||
file_path = "";
|
|
||||||
return;
|
update_packet_display(packets[0]);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -342,6 +375,24 @@ void BLETxView::on_data(uint32_t value, bool is_data) {
|
|||||||
console.write(str_console);
|
console.write(str_console);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BLETxView::update_packet_display(BLETxPacket packet) {
|
||||||
|
std::string formattedMacAddress = to_string_formatted_mac_address(packet.macAddress);
|
||||||
|
|
||||||
|
std::vector<std::string> strings = splitIntoStrings(packet.advertisementData);
|
||||||
|
|
||||||
|
text_packet_index.set(to_string_dec_uint(current_packet));
|
||||||
|
|
||||||
|
text_packets_sent.set(to_string_dec_uint(packet.packet_count));
|
||||||
|
|
||||||
|
text_mac_address.set(formattedMacAddress);
|
||||||
|
|
||||||
|
console.clear(true);
|
||||||
|
|
||||||
|
for (const std::string& str : strings) {
|
||||||
|
console.writeln(str);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void BLETxView::set_parent_rect(const Rect new_parent_rect) {
|
void BLETxView::set_parent_rect(const Rect new_parent_rect) {
|
||||||
View::set_parent_rect(new_parent_rect);
|
View::set_parent_rect(new_parent_rect);
|
||||||
const Rect content_rect{0, header_height, new_parent_rect.width(), new_parent_rect.height() - header_height};
|
const Rect content_rect{0, header_height, new_parent_rect.width(), new_parent_rect.height() - header_height};
|
||||||
|
@ -74,10 +74,18 @@ class BLETxView : public View {
|
|||||||
|
|
||||||
std::string title() const override { return "BLE TX"; };
|
std::string title() const override { return "BLE TX"; };
|
||||||
|
|
||||||
|
struct BLETxPacket {
|
||||||
|
char macAddress[13];
|
||||||
|
char advertisementData[63];
|
||||||
|
char packetCount[11];
|
||||||
|
uint32_t packet_count;
|
||||||
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void on_data(uint32_t value, bool is_data);
|
void on_data(uint32_t value, bool is_data);
|
||||||
void on_tx_progress(const bool done);
|
void on_tx_progress(const bool done);
|
||||||
void on_file_changed(const std::filesystem::path& new_file_path);
|
void on_file_changed(const std::filesystem::path& new_file_path);
|
||||||
|
void update_packet_display(BLETxPacket packet);
|
||||||
|
|
||||||
NavigationView& nav_;
|
NavigationView& nav_;
|
||||||
TxRadioState radio_state_{
|
TxRadioState radio_state_{
|
||||||
@ -93,16 +101,17 @@ class BLETxView : public View {
|
|||||||
|
|
||||||
std::filesystem::path file_path{};
|
std::filesystem::path file_path{};
|
||||||
uint8_t channel_number = 37;
|
uint8_t channel_number = 37;
|
||||||
char macAddress[13] = "010203040506";
|
|
||||||
char advertisementData[63] = "00112233445566778899AABBCCDDEEFF";
|
char randomMac[13] = "010203040506";
|
||||||
char packetCount[11] = "0";
|
|
||||||
|
|
||||||
bool is_running = false;
|
bool is_running = false;
|
||||||
uint64_t timer_count{0};
|
uint64_t timer_count{0};
|
||||||
uint64_t timer_period{256};
|
uint64_t timer_period{256};
|
||||||
bool repeatLoop = false;
|
bool repeatLoop = false;
|
||||||
uint32_t packet_count{0};
|
|
||||||
uint32_t packet_counter{0};
|
uint32_t packet_counter{0};
|
||||||
|
uint32_t num_packets{0};
|
||||||
|
uint32_t current_packet{0};
|
||||||
|
bool random_mac = false;
|
||||||
|
|
||||||
enum PKT_TYPE {
|
enum PKT_TYPE {
|
||||||
INVALID_TYPE,
|
INVALID_TYPE,
|
||||||
@ -136,12 +145,15 @@ class BLETxView : public View {
|
|||||||
|
|
||||||
static constexpr uint8_t mac_address_size_str{12};
|
static constexpr uint8_t mac_address_size_str{12};
|
||||||
static constexpr uint8_t max_packet_size_str{62};
|
static constexpr uint8_t max_packet_size_str{62};
|
||||||
static constexpr uint8_t max_packet_count_str{10};
|
static constexpr uint8_t max_packet_repeat_str{10};
|
||||||
static constexpr uint32_t max_packet_count{UINT32_MAX};
|
static constexpr uint32_t max_packet_repeat_count{UINT32_MAX};
|
||||||
|
static constexpr uint32_t max_num_packets{256};
|
||||||
|
|
||||||
PKT_TYPE pduType = {RAW};
|
BLETxPacket packets[max_num_packets];
|
||||||
|
|
||||||
static constexpr auto header_height = 8 * 16;
|
PKT_TYPE pduType = {DISCOVERY};
|
||||||
|
|
||||||
|
static constexpr auto header_height = 9 * 16;
|
||||||
|
|
||||||
Button button_open{
|
Button button_open{
|
||||||
{0 * 8, 0 * 16, 10 * 8, 2 * 16},
|
{0 * 8, 0 * 16, 10 * 8, 2 * 16},
|
||||||
@ -152,7 +164,13 @@ class BLETxView : public View {
|
|||||||
"-"};
|
"-"};
|
||||||
|
|
||||||
ProgressBar progressbar{
|
ProgressBar progressbar{
|
||||||
{11 * 8, 1 * 16, 12 * 8, 16}};
|
{11 * 8, 1 * 16, 9 * 8, 16}};
|
||||||
|
|
||||||
|
Checkbox check_rand_mac{
|
||||||
|
{21 * 8, 1 * 16},
|
||||||
|
6,
|
||||||
|
"Random",
|
||||||
|
true};
|
||||||
|
|
||||||
TxFrequencyField field_frequency{
|
TxFrequencyField field_frequency{
|
||||||
{0 * 8, 2 * 16},
|
{0 * 8, 2 * 16},
|
||||||
@ -204,25 +222,32 @@ class BLETxView : public View {
|
|||||||
{"SCAN_RSP", SCAN_RSP},
|
{"SCAN_RSP", SCAN_RSP},
|
||||||
{"CONNECT_REQ", CONNECT_REQ}}};
|
{"CONNECT_REQ", CONNECT_REQ}}};
|
||||||
|
|
||||||
|
Labels label_packet_index{
|
||||||
|
{{0 * 8, 10 * 8}, "Packet Index:", Color::light_grey()}};
|
||||||
|
|
||||||
|
Text text_packet_index{
|
||||||
|
{13 * 8, 5 * 16, 12 * 8, 16},
|
||||||
|
"-"};
|
||||||
|
|
||||||
Labels label_packets_sent{
|
Labels label_packets_sent{
|
||||||
{{0 * 8, 10 * 8}, "Packets Left:", Color::light_grey()}};
|
{{0 * 8, 12 * 8}, "Packets Left:", Color::light_grey()}};
|
||||||
|
|
||||||
Text text_packets_sent{
|
Text text_packets_sent{
|
||||||
{13 * 8, 5 * 16, 10 * 8, 16},
|
{13 * 8, 6 * 16, 12 * 8, 16},
|
||||||
"-"};
|
"-"};
|
||||||
|
|
||||||
Labels label_mac_address{
|
Labels label_mac_address{
|
||||||
{{0 * 8, 12 * 8}, "Mac Address:", Color::light_grey()}};
|
{{0 * 8, 14 * 8}, "Mac Address:", Color::light_grey()}};
|
||||||
|
|
||||||
Text text_mac_address{
|
Text text_mac_address{
|
||||||
{12 * 8, 6 * 16, 20 * 8, 16},
|
{12 * 8, 7 * 16, 20 * 8, 16},
|
||||||
"-"};
|
"-"};
|
||||||
|
|
||||||
Labels label_data_packet{
|
Labels label_data_packet{
|
||||||
{{0 * 8, 14 * 8}, "Packet Data:", Color::light_grey()}};
|
{{0 * 8, 16 * 8}, "Packet Data:", Color::light_grey()}};
|
||||||
|
|
||||||
Console console{
|
Console console{
|
||||||
{0, 7 * 16, 240, 240}};
|
{0, 8 * 16, 240, 240}};
|
||||||
|
|
||||||
std::string str_log{""};
|
std::string str_log{""};
|
||||||
bool logging{true};
|
bool logging{true};
|
||||||
|
Loading…
Reference in New Issue
Block a user