Skip to content

Commit

Permalink
Merge pull request #79 from natnaely91/master
Browse files Browse the repository at this point in the history
python binding for tx using pybind11
  • Loading branch information
nrwahl2 authored Nov 21, 2023
2 parents 95c3e5e + 47eeff9 commit 89f996a
Show file tree
Hide file tree
Showing 6 changed files with 285 additions and 39 deletions.
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ cmake_minimum_required(VERSION 3.10)
# Define Test Variants
set(CMAKE_C_FLAGS_TESTDEBUG "-Wall -Werror -g -DDXWIFI_TESTS")
set(CMAKE_C_FLAGS_TESTREL "-Wall -Werror -O3 -DNDEBUG -DDXWIFI_TESTS")
set(CMAKE_POSITION_INDEPENDENT_CODE ON)

# Cross-Compilation support, only supports armhf at the moment
if(PLATFORM STREQUAL "armhf")
Expand Down
23 changes: 22 additions & 1 deletion dxwifi/tx/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,10 +1,31 @@
find_package(PythonLibs REQUIRED)
find_package(pybind11 REQUIRED)

file(GLOB tx_cpp_sources ./*)
file(GLOB tx_sources ./*)

include_directories(${PYTHON_INCLUDE_DIRS})
include_directories(${CMAKE_SOURCE_DIR}libdxwifi/details)

set(TX_DESCRIPTION "OreSat Live DxWiFi transmission program")


add_library(tx_cpp_lib STATIC ${tx_cpp_sources})
target_include_directories(tx_cpp_lib PUBLIC ${PYTHON_INCLUDE_DIRS} ${CMAKE_SOURCE_DIR}libdxwifi/details)
target_link_libraries(tx_cpp_lib ${PYTHON_LIBRARIES} dxwifi)

add_executable(tx ${tx_sources})
target_link_libraries(tx dxwifi tx_cpp_lib)


pybind11_add_module(tx_module tx_wrapper.cpp)
target_link_libraries(tx_module PRIVATE pybind11::module ${PYTHON_LIBRARIES} dxwifi tx_cpp_lib)

target_link_libraries(tx dxwifi)
set_target_properties(tx_module PROPERTIES PREFIX ""
SUFFIX ".so"
OUTPUT_NAME "tx_module"
LIBRARY_OUTPUT_DIRECTORY ${DXWIFI_RUNTIME_OUTPUT_DIRECTORY}
)

set_target_properties( tx
PROPERTIES
Expand Down
44 changes: 7 additions & 37 deletions dxwifi/tx/tx.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,50 +7,22 @@
*
*/

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#include <poll.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <signal.h>
#include <dirent.h>
#include <fnmatch.h>

#include <arpa/inet.h>
#include <linux/limits.h>

#include <dxwifi/tx/cli.h>

#include <libdxwifi/dxwifi.h>
#include <libdxwifi/transmitter.h>
#include <libdxwifi/details/utils.h>
#include <libdxwifi/details/daemon.h>
#include <libdxwifi/details/logging.h>
#include <libdxwifi/details/dirwatch.h>
#include <libdxwifi/details/syslogger.h>

//Syscalls for Memory Mapping
#include <sys/mman.h>

#include "tx.h"

typedef struct {
float packet_loss_rate;
unsigned count;
} packet_loss_stats;

dirwatch* dirwatch_handle = NULL;
dxwifi_transmitter* transmitter = NULL;

static dirwatch* dirwatch_handle = NULL;
static dxwifi_transmitter* transmitter = NULL;

// Forward declare
void terminate(int signum);
void transmit(cli_args* args, dxwifi_transmitter* tx);

int main(int argc, char** argv) {
exit(main_worker(argc, argv));
}

int main_worker(int argc, char** argv) {
cli_args args = DEFAULT_CLI_ARGS;
transmitter = &args.tx;

Expand Down Expand Up @@ -84,7 +56,7 @@ int main(int argc, char** argv) {
stop_daemon(args.pid_file);
}

exit(0);
return 0;
}

/**
Expand Down Expand Up @@ -523,12 +495,10 @@ void transmit_test_sequence(dxwifi_transmitter* tx, int retransmit) {
*
*/
void transmit(cli_args* args, dxwifi_transmitter* tx) {

packet_loss_stats plstats = {
.packet_loss_rate = args->packet_loss,
.count = 0
};

if(args->tx_delay > 0 ) {
attach_preinject_handler(transmitter, delay_transmission, &args->tx_delay);
}
Expand Down
54 changes: 54 additions & 0 deletions dxwifi/tx/tx.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
#ifndef TX_H
#define TX_H

#include <stdbool.h>


#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#include <poll.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <signal.h>
#include <dirent.h>
#include <fnmatch.h>

#include <arpa/inet.h>
#include <linux/limits.h>

#include <dxwifi/tx/cli.h>

#include <libdxwifi/dxwifi.h>
#include <libdxwifi/transmitter.h>
#include <libdxwifi/details/utils.h>
#include <libdxwifi/details/daemon.h>
#include <libdxwifi/details/logging.h>
#include <libdxwifi/details/dirwatch.h>
#include <libdxwifi/details/syslogger.h>

//Syscalls for Memory Mapping
#include <sys/mman.h>

// Function declarations
void terminate(int signum);
void transmit(cli_args* args, dxwifi_transmitter* tx);
void tx_sigint_handler(int signum);
void watchdir_sigint_handler(int signum);
void log_tx_stats(dxwifi_tx_stats stats);
bool log_frame_stats(dxwifi_tx_frame* frame, dxwifi_tx_stats stats, void* user);
bool delay_transmission(dxwifi_tx_frame* frame, dxwifi_tx_stats stats, void* user);
bool packet_loss_sim(dxwifi_tx_frame* frame, dxwifi_tx_stats stats, void* user);
bool bit_error_rate_sim(dxwifi_tx_frame* frame, dxwifi_tx_stats stats, void* user);
bool attach_frame_number(dxwifi_tx_frame* frame, dxwifi_tx_stats stats, void* user);
dxwifi_tx_state_t setup_handlers_and_transmit(dxwifi_transmitter* tx, int fd);
dxwifi_tx_state_t transmit_files(dxwifi_transmitter* tx, char** files, size_t num_files, unsigned delay, int retransmit_count, float coderate);
void transmit_directory_contents(dxwifi_transmitter* tx, const char* filter, const char* dirname, unsigned delay, int retransmit_count, float coderate);
static void transmit_new_file(const dirwatch_event* event, void* user);
void transmit_directory(cli_args* args, dxwifi_transmitter* tx);
void transmit_test_sequence(dxwifi_transmitter* tx, int retransmit);
int main_worker(int argc, char** argv);

#endif // TX_H
193 changes: 193 additions & 0 deletions dxwifi/tx/tx_wrapper.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,193 @@
#include <cassert>
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
#include <iostream>

extern "C" {
#include "tx.h"
}

void dxwifi_transmitter_init_default(dxwifi_transmitter& tx) {
tx.transmit_timeout = -1;
tx.redundant_ctrl_frames = 0;
tx.enable_pa = false;
tx.rtap_flags = 0x00;
tx.rtap_rate_mbps = 1;
tx.rtap_tx_flags = IEEE80211_RADIOTAP_F_TX_NOACK;

uint8_t default_address[] = DXWIFI_DFLT_SENDER_ADDR;
memcpy(tx.address, default_address, sizeof(default_address));

tx.fctl.protocol_version = IEEE80211_PROTOCOL_VERSION;
tx.fctl.type = IEEE80211_FTYPE_DATA;
tx.fctl.stype.data = IEEE80211_STYPE_DATA;
tx.fctl.to_ds = false;
tx.fctl.from_ds = true;
tx.fctl.more_frag = false;
tx.fctl.retry = false;
tx.fctl.power_mgmt = false;
tx.fctl.more_data = true;
tx.fctl.wep = false;
tx.fctl.order = false;

tx.__activated = false;
tx.__handle = NULL;

#if defined(DXWIFI_TESTS)
tx.savefile = NULL;
tx.dumper = NULL;
#endif
}

void cli_init_default(cli_args& args) {
args.tx_mode = TX_STREAM_MODE;
args.daemon = DAEMON_UNKNOWN_CMD;
args.pid_file = TX_DEFAULT_PID_FILE;
args.verbosity = DXWIFI_LOG_INFO;
args.quiet = false;
args.use_syslog = false;
args.file_count = 0,
args.file_filter = "*",
args.retransmit_count = 0;
args.transmit_current_files = false;
args.listen_for_new_files = true;
args.dirwatch_timeout = -1;
args.tx_delay = 0;
args.error_rate = 0;
args.packet_loss = 0;
dxwifi_transmitter_init_default(args.tx);
args.coderate = 0.667;
}

void init_transmitter_wrapper(dxwifi_transmitter* tx, const std::string& device_name) {
init_transmitter(tx, device_name.c_str());
}

int main_wrapper(pybind11::list args) {
int argc = pybind11::len(args);
char** argv = new char*[argc];
for (int i = 0; i < argc; ++i) {
std::string arg = pybind11::cast<std::string>(args[i]);
argv[i] = strdup(arg.c_str());
}

int result = main_worker(argc, argv);

for (int i = 0; i < argc; ++i) {
free(argv[i]);
}
delete[] argv;
return result;
}

std::vector<unsigned char> get_address(const dxwifi_transmitter& tx) {
return std::vector<unsigned char>(tx.address, tx.address + sizeof(tx.address));
}

void set_address(dxwifi_transmitter& tx, const std::vector<unsigned char>& addr) {
std::copy(addr.begin(), addr.end(), tx.address);
}

const char* get_device(const cli_args& args) {
return args.device;
}

void set_device(cli_args& args, const std::string& device) {
args.device = strdup(device.c_str());
}

const char* get_file_filter(const cli_args& args) {
return args.file_filter;
}

void set_file_filter(cli_args& args, const std::string& file_filter) {
free(const_cast<char*>(args.file_filter));
args.file_filter = strdup(file_filter.c_str());
}

std::vector<std::string> get_files(const cli_args& args) {
std::vector<std::string> files;
for (int i = 0; i < args.file_count; ++i) {
files.push_back(std::string(args.files[i]));
}
return files;
}

void set_files(cli_args& args, const std::vector<std::string>& files) {
for (size_t i = 0; i < files.size() && i < TX_CLI_FILE_MAX; ++i) {
free(args.files[i]);
args.files[i] = strdup(files[i].c_str());
}
args.file_count = files.size();
}

void transmit_wrapper(cli_args& args, dxwifi_transmitter& tx) {
transmit(&args, &tx);
}

PYBIND11_MODULE(tx_module, m) {
m.doc() = "controls transmission";

m.def("main_wrapper", &main_wrapper, "main main");

m.def("transmit", &transmit_wrapper, "Determine the transmission mode and transmit files");

m.def("terminate", &terminate, "SIGTERM handler for daemonized process. Ensures transmitter is closed.");

m.def("init_transmitter", &init_transmitter_wrapper, "See transmitter.h for description of non-static functions");

m.def("default", &cli_init_default, "inits cli_args with default values");

m.def("close_transmitter", &close_transmitter, "closes transmitter");

pybind11::class_<dxwifi_transmitter>(m, "DxWifiTransmitter")
.def(pybind11::init<>())
.def_readwrite("transmit_timeout", &dxwifi_transmitter::transmit_timeout)
.def_readwrite("redundant_ctrl_frames", &dxwifi_transmitter::redundant_ctrl_frames)
.def_readwrite("enable_pa", &dxwifi_transmitter::enable_pa)
.def("get_address", &get_address)
.def("set_address", &set_address)
.def_readwrite("rtap_flags", &dxwifi_transmitter::rtap_flags)
.def_readwrite("rtap_rate_mbps", &dxwifi_transmitter::rtap_rate_mbps)
.def_readwrite("rtap_tx_flags", &dxwifi_transmitter::rtap_tx_flags);

pybind11::enum_<tx_mode_t>(m, "TxMode")
.value("TX_TEST_MODE", TX_TEST_MODE)
.value("TX_FILE_MODE", TX_FILE_MODE)
.value("TX_STREAM_MODE", TX_STREAM_MODE)
.value("TX_DIRECTORY_MODE", TX_DIRECTORY_MODE)
.export_values();

pybind11::enum_<dxwifi_daemon_cmd_t>(m, "DaemonCommand")
.value("UNKNOWN_CMD", DAEMON_UNKNOWN_CMD)
.value("START", DAEMON_START)
.value("STOP", DAEMON_STOP)
.export_values();

pybind11::class_<cli_args>(m, "CliArgs")
.def(pybind11::init<>())
.def_readwrite("tx_mode", &cli_args::tx_mode)
.def_readwrite("daemon", &cli_args::daemon)
.def_readwrite("pid_file", &cli_args::pid_file)
.def("get_files", &get_files)
.def("set_files", &set_files)
.def("get_file_filter", &get_file_filter)
.def("set_file_filter", &set_file_filter)
.def_readwrite("file_filter", &cli_args::file_filter)
.def_readwrite("retransmit_count", &cli_args::retransmit_count)
.def_readwrite("transmit_current_files", &cli_args::transmit_current_files)
.def_readwrite("listen_for_new_files", &cli_args::listen_for_new_files)
.def_readwrite("dirwatch_timeout", &cli_args::dirwatch_timeout)
.def_readwrite("verbosity", &cli_args::verbosity)
.def_readwrite("quiet", &cli_args::quiet)
.def_readwrite("use_syslog", &cli_args::use_syslog)
.def_readwrite("tx_delay", &cli_args::tx_delay)
.def_readwrite("file_delay", &cli_args::file_delay)
.def_readwrite("device", &cli_args::device)
.def("get_device", &get_device)
.def("set_device", &set_device)
.def_readwrite("packet_loss", &cli_args::packet_loss)
.def_readwrite("error_rate", &cli_args::error_rate)
.def_readwrite("tx", &cli_args::tx)
.def_readwrite("coderate", &cli_args::coderate);
}
9 changes: 8 additions & 1 deletion libdxwifi/details/assert.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,11 @@
#include <libdxwifi/details/logging.h>


#define compiler_assert(expr, msg) _Static_assert(expr, msg)
#ifdef __cplusplus
#define compiler_assert(expr, msg)
#else
#define compiler_assert(expr, msg) _Static_assert(expr, msg)
#endif

#define DXWIFI_ASSERT_MSG_MAX_LEN 256

Expand Down Expand Up @@ -67,6 +71,9 @@
}))


#ifdef assert
#undef assert
#endif
#define assert(expr) assert_M(expr, "")


Expand Down

0 comments on commit 89f996a

Please sign in to comment.