Skip to content

Commit

Permalink
get rid of the annoying address packed warning (not an issue for us)
Browse files Browse the repository at this point in the history
  • Loading branch information
Consti10 committed Jan 7, 2024
1 parent b619969 commit 2084cdf
Show file tree
Hide file tree
Showing 5 changed files with 184 additions and 14 deletions.
3 changes: 3 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ target_link_libraries(example_pollute PRIVATE ${WB_TARGET_LINK_LIBRARIES})
add_executable(test_listen executables/test_listen.cpp)
target_link_libraries(test_listen PRIVATE ${WB_TARGET_LINK_LIBRARIES})

add_executable(test_dummy_link executables/test_dummy_link.cpp)
target_link_libraries(test_dummy_link PRIVATE ${WB_TARGET_LINK_LIBRARIES})

# When it is a static library, we don't need to install it.
# But if it is a shared library, we need to install it.
#install(TARGETS wifibroadcast DESTINATION lib)
Expand Down
38 changes: 38 additions & 0 deletions executables/test_dummy_link.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
//
// Created by consti10 on 07.01.24.
//

#include <iostream>

#include "../src/dummy_link/DummyLink.h"
#include "Helper.hpp"

static std::vector<std::shared_ptr<std::vector<uint8_t>>> pull_all_buffered_packets(DummyLink& dummyLink){
std::vector<std::shared_ptr<std::vector<uint8_t>>> rx_packets;
while (true){
auto packet=dummyLink.rx_radiotap();
if(!packet) break ;
rx_packets.push_back(packet);
}
return rx_packets;
}

int main(int argc, char *const *argv) {
auto dummy_air=std::make_shared<DummyLink>(true);
auto dummy_gnd=std::make_shared<DummyLink>(false);
auto dummy_packets1=GenericHelper::createRandomDataBuffers(20,1024,1024);
auto dummy_packets2=GenericHelper::createRandomDataBuffers(20,1024,1024);

for(auto& packet:dummy_packets1){
dummy_air->tx_radiotap(packet.data(),packet.size());
}
for(auto& packet:dummy_packets2){
dummy_gnd->tx_radiotap(packet.data(),packet.size());
}
auto rx_air= pull_all_buffered_packets(*dummy_air);
auto rx_gnd= pull_all_buffered_packets(*dummy_gnd);
GenericHelper::assertVectorsOfVectorsEqual(rx_gnd,dummy_packets1);
GenericHelper::assertVectorsOfVectorsEqual(rx_air,dummy_packets2);
std::cout<<"Done"<<std::endl;
return 0;
}
14 changes: 14 additions & 0 deletions src/HelperSources/Helper.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,20 @@ static void assertVectorsOfVectorsEqual(const std::vector<std::vector<uint8_t>>
assertVectorsEqual(sb,rb);
}
}
static std::vector<std::vector<uint8_t>> shared_to(const std::vector<std::shared_ptr<std::vector<uint8_t>>>& in){
std::vector<std::vector<uint8_t>> ret;
for(auto& element:in){
ret.emplace_back(element->begin(),element->end());
}
return ret;
}
static void assertVectorsOfVectorsEqual(const std::vector<std::shared_ptr<std::vector<uint8_t>>>& sbl, const std::vector<std::vector<uint8_t>> &rbl){
for(int i=0;i<sbl.size();i++){
const auto& sb=sbl[i];
const auto& rb=rbl[i];
assertVectorsEqual(*sb,rb);
}
}
template<std::size_t S>
static void assertArraysEqual(const std::array<uint8_t, S> &sb, const std::array<uint8_t, S> &rb) {
const int result = memcmp(sb.data(), rb.data(), sb.size());
Expand Down
122 changes: 110 additions & 12 deletions src/dummy_link/DummyLink.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,29 +3,127 @@
//

#include "DummyLink.h"

#include <fcntl.h>
#include <memory.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/un.h>
#include <unistd.h>

void* create_shared_memory(size_t size) {
// Our memory buffer will be readable and writable:
int protection = PROT_READ | PROT_WRITE;
#include <chrono>
#include <iostream>
#include <memory>
#include <string>
#include <vector>

// The buffer will be shared (meaning other processes can access it), but
// anonymous (meaning third-party processes cannot obtain an address for it),
// so only this process and its children will be able to use it:
int visibility = MAP_SHARED | MAP_ANONYMOUS;
// From http://www.atakansarioglu.com/linux-ipc-inter-process-messaging-linux-domain-socket-fifo-pipe-shared-memory-shm-example/

// The remaining parameters to `mmap()` are not important for this use case,
// but the manpage for `mmap` explains their purpose.
return mmap(NULL, size, protection, visibility, -1, 0);
static sockaddr_un create_adr(const std::string& name){
// Unix domain socket file address.
struct sockaddr_un address;
address.sun_family = AF_UNIX;
strcpy(address.sun_path, name.c_str());
return address;
}

static int create_socket_read(const std::string& name){
auto address= create_adr(name);
// Delete the old socket file.
unlink(name.c_str());
// Create a unix domain socket.
int fd;
if((fd = socket(AF_UNIX, SOCK_DGRAM, 0)) < 0) {
std::cout << "Receiver: Cannot create socket" << std::endl;
return -1;
}

void DummyLink::tx_radiotap(const uint8_t *packet_buff, int packet_size) {
// Bind the socket to the address.
if(bind(fd, (struct sockaddr *)&address, sizeof(sockaddr_un)) != 0) {
std::cout << "Receiver: Cannot bind socket" << std::endl;
return -1;
}
return fd;
}

static int create_socket_send(){
// Create a unix domain socket.
int fd;
if((fd = socket(AF_UNIX, SOCK_DGRAM, 0)) < 0) {
std::cout << "Sender: Cannot create socket" << std::endl;
return -1;
}
return fd;
}

static void send_data(int fd,const std::string& name,const uint8_t* data,int data_len){
auto address= create_adr(name);
if(sendto(fd, data,data_len, 0, (struct sockaddr *)&address, sizeof(sockaddr_un)) !=data_len) {
std::cout << "Client: Cannot send" << std::endl;
}
//std::cout<<"Sent:"<<data_len<<std::endl;
}

void DummyLink::rx_radiotap() {
static constexpr auto MAX_MTU_INCLUDING_HEADER=2000;

static std::shared_ptr<std::vector<uint8_t>> read_data(int fd){
auto buff=std::make_shared<std::vector<uint8_t>>();
buff->resize(MAX_MTU_INCLUDING_HEADER);
auto size=recvfrom(fd, buff->data(), buff->size(), MSG_DONTWAIT, NULL, NULL);
if(size>0){
buff->resize(size);
return buff;
}
return nullptr;
}

DummyLink::DummyLink(bool is_air):m_is_air(is_air) {
if(m_is_air){
m_fn_tx="air";
m_fn_rx="gnd";
//m_fn_rx="air";
}else{
m_fn_tx="gnd";
m_fn_rx="air";
}
m_fd_rx=create_socket_read(m_fn_rx);
m_fd_tx=create_socket_send();
m_keep_receiving= true;
m_receive_thread=std::make_unique<std::thread>(&DummyLink::loop_rx, this);
}

DummyLink::~DummyLink() {
m_keep_receiving= false;
m_receive_thread->join();
m_receive_thread= nullptr;
}

void DummyLink::tx_radiotap(const uint8_t *packet_buff, int packet_size) {
send_data(m_fd_tx,m_fn_tx,packet_buff,packet_size);
}

std::shared_ptr<std::vector<uint8_t>> DummyLink::rx_radiotap() {
std::lock_guard<std::mutex> guard(m_rx_mutex);
if(!m_rx_queue.empty()){
auto packet=m_rx_queue.front();
m_rx_queue.pop();
return packet;
}
return nullptr;
}

void DummyLink::loop_rx() {
while (m_keep_receiving){
auto packet= read_data(m_fd_rx);
if(packet!= nullptr){
//std::cout<<"Got packet"<<packet->size()<<std::endl;
std::lock_guard<std::mutex> guard(m_rx_mutex);
m_rx_queue.push(packet);
}
//std::cout<<"ARGH"<<std::endl;
}
}

21 changes: 19 additions & 2 deletions src/dummy_link/DummyLink.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,32 @@
#define OPENHD_DUMMYLINK_H

#include <cstdint>
#include <memory>
#include <mutex>
#include <string>
#include <thread>
#include <vector>
#include <queue>

// TODO: Write something that emulates a wb link (tx, rx)
// using linux shm or similar
class DummyLink {
public:
explicit DummyLink(bool is_air);
~DummyLink();
void tx_radiotap(const uint8_t* packet_buff, int packet_size);
void rx_radiotap();
std::shared_ptr<std::vector<uint8_t>> rx_radiotap();
private:
bool m_is_air;
const bool m_is_air;
int m_fd_tx;
int m_fd_rx;
std::string m_fn_tx;
std::string m_fn_rx;
std::queue<std::shared_ptr<std::vector<uint8_t>>> m_rx_queue;
std::mutex m_rx_mutex;
std::unique_ptr<std::thread> m_receive_thread;
void loop_rx();
bool m_keep_receiving= true;
};


Expand Down

0 comments on commit 2084cdf

Please sign in to comment.