Skip to content

Commit

Permalink
Add get_fec and get_radio into wfb_tx_cmd
Browse files Browse the repository at this point in the history
  • Loading branch information
svpcom committed Sep 1, 2024
1 parent 050f03b commit fe85e64
Show file tree
Hide file tree
Showing 5 changed files with 310 additions and 64 deletions.
120 changes: 86 additions & 34 deletions src/tx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ void RawSocketTransmitter::set_mark(uint32_t idx)


RawSocketTransmitter::RawSocketTransmitter(int k, int n, const string &keypair, uint64_t epoch, uint32_t channel_id, uint32_t fec_delay,
vector<tags_item_t> &tags, const vector<string> &wlans, vector<uint8_t> &radiotap_header,
vector<tags_item_t> &tags, const vector<string> &wlans, radiotap_header_t &radiotap_header,
uint8_t frame_type, bool use_qdisc, uint32_t fwmark) : \
Transmitter(k, n, keypair, epoch, channel_id, fec_delay, tags),
channel_id(channel_id),
Expand Down Expand Up @@ -284,8 +284,8 @@ void RawSocketTransmitter::inject_packet(const uint8_t *buf, size_t size)
struct iovec iov[3] = \
{
// radiotap header
{ .iov_base = (void*)&radiotap_header[0],
.iov_len = radiotap_header.size()
{ .iov_base = (void*)&radiotap_header.header[0],
.iov_len = radiotap_header.header.size()
},
// ieee80211 header
{ .iov_base = (void*)ieee_hdr,
Expand Down Expand Up @@ -580,8 +580,8 @@ void data_source(shared_ptr<Transmitter> &t, vector<int> &rx_fd, int control_fd,

for(;;)
{
cmd_req_t req;
cmd_resp_t resp;
cmd_req_t req = {};
cmd_resp_t resp = {};
ssize_t rsize;
struct sockaddr_in from_addr;
socklen_t addr_size = sizeof(from_addr);
Expand All @@ -604,7 +604,7 @@ void data_source(shared_ptr<Transmitter> &t, vector<int> &rx_fd, int control_fd,
if (rsize != offsetof(cmd_req_t, u) + sizeof(req.u.cmd_set_fec))
{
resp.rc = htonl(EINVAL);
sendto(fd, &resp, sizeof(resp), MSG_DONTWAIT, (sockaddr*)&from_addr, addr_size);
sendto(fd, &resp, offsetof(cmd_resp_t, u), MSG_DONTWAIT, (sockaddr*)&from_addr, addr_size);
continue;
}

Expand All @@ -614,7 +614,7 @@ void data_source(shared_ptr<Transmitter> &t, vector<int> &rx_fd, int control_fd,
if(!(fec_k <= fec_n && fec_k >=1 && fec_n >= 1 && fec_n < 256))
{
resp.rc = htonl(EINVAL);
sendto(fd, &resp, sizeof(resp), MSG_DONTWAIT, (sockaddr*)&from_addr, addr_size);
sendto(fd, &resp, offsetof(cmd_resp_t, u), MSG_DONTWAIT, (sockaddr*)&from_addr, addr_size);
fprintf(stderr, "Rejecting new FEC settings");
continue;
}
Expand All @@ -630,7 +630,7 @@ void data_source(shared_ptr<Transmitter> &t, vector<int> &rx_fd, int control_fd,
t->send_session_key();
}

sendto(fd, &resp, sizeof(resp), MSG_DONTWAIT, (sockaddr*)&from_addr, addr_size);
sendto(fd, &resp, offsetof(cmd_resp_t, u), MSG_DONTWAIT, (sockaddr*)&from_addr, addr_size);
fprintf(stderr, "Session restarted with FEC %d/%d\n", fec_k, fec_n);
}
break;
Expand All @@ -640,7 +640,7 @@ void data_source(shared_ptr<Transmitter> &t, vector<int> &rx_fd, int control_fd,
if (rsize != offsetof(cmd_req_t, u) + sizeof(req.u.cmd_set_radio))
{
resp.rc = htonl(EINVAL);
sendto(fd, &resp, sizeof(resp), MSG_DONTWAIT, (sockaddr*)&from_addr, addr_size);
sendto(fd, &resp, offsetof(cmd_resp_t, u), MSG_DONTWAIT, (sockaddr*)&from_addr, addr_size);
continue;
}

Expand All @@ -658,12 +658,12 @@ void data_source(shared_ptr<Transmitter> &t, vector<int> &rx_fd, int control_fd,
catch(runtime_error &e)
{
resp.rc = htonl(EINVAL);
sendto(fd, &resp, sizeof(resp), MSG_DONTWAIT, (sockaddr*)&from_addr, addr_size);
sendto(fd, &resp, offsetof(cmd_resp_t, u), MSG_DONTWAIT, (sockaddr*)&from_addr, addr_size);
fprintf(stderr, "Rejecting new radiotap header: %s\n", e.what());
continue;
}

sendto(fd, &resp, sizeof(resp), MSG_DONTWAIT, (sockaddr*)&from_addr, addr_size);
sendto(fd, &resp, offsetof(cmd_resp_t, u), MSG_DONTWAIT, (sockaddr*)&from_addr, addr_size);
fprintf(stderr,
"Radiotap updated with stbc=%d, ldpc=%d, short_gi=%d, bandwidth=%d, mcs_index=%d, vht_mode=%d, vht_nss=%d\n",
req.u.cmd_set_radio.stbc,
Expand All @@ -676,10 +676,53 @@ void data_source(shared_ptr<Transmitter> &t, vector<int> &rx_fd, int control_fd,
}
break;

case CMD_GET_FEC:
{
int fec_k = 0, fec_n = 0;

if (rsize != offsetof(cmd_req_t, u))
{
resp.rc = htonl(EINVAL);
sendto(fd, &resp, offsetof(cmd_resp_t, u), MSG_DONTWAIT, (sockaddr*)&from_addr, addr_size);
continue;
}

t->get_fec(fec_k, fec_n);

resp.u.cmd_get_fec.k = fec_k;
resp.u.cmd_get_fec.n = fec_n;

sendto(fd, &resp, offsetof(cmd_resp_t, u) + sizeof(resp.u.cmd_get_fec), MSG_DONTWAIT, (sockaddr*)&from_addr, addr_size);
}
break;

case CMD_GET_RADIO:
{
if (rsize != offsetof(cmd_req_t, u))
{
resp.rc = htonl(EINVAL);
sendto(fd, &resp, offsetof(cmd_resp_t, u), MSG_DONTWAIT, (sockaddr*)&from_addr, addr_size);
continue;
}

radiotap_header_t hdr = t->get_radiotap_header();

resp.u.cmd_get_radio.stbc = hdr.stbc;
resp.u.cmd_get_radio.ldpc = hdr.ldpc;
resp.u.cmd_get_radio.short_gi = hdr.short_gi;
resp.u.cmd_get_radio.bandwidth = hdr.bandwidth;
resp.u.cmd_get_radio.mcs_index = hdr.mcs_index;
resp.u.cmd_get_radio.vht_mode = hdr.vht_mode;
resp.u.cmd_get_radio.vht_nss = hdr.vht_nss;

sendto(fd, &resp, offsetof(cmd_resp_t, u) + sizeof(resp.u.cmd_get_radio), MSG_DONTWAIT, (sockaddr*)&from_addr, addr_size);
}
break;

default:
{
resp.rc = htonl(ENOTSUP);
sendto(fd, &resp, sizeof(resp), MSG_DONTWAIT, (sockaddr*)&from_addr, addr_size);
sendto(fd, &resp, offsetof(cmd_resp_t, u), MSG_DONTWAIT, (sockaddr*)&from_addr, addr_size);
continue;
}
break;
Expand Down Expand Up @@ -790,15 +833,24 @@ void data_source(shared_ptr<Transmitter> &t, vector<int> &rx_fd, int control_fd,
}


vector<uint8_t> init_radiotap_header(uint8_t stbc,
bool ldpc,
bool short_gi,
uint8_t bandwidth,
uint8_t mcs_index,
bool vht_mode,
uint8_t vht_nss)
radiotap_header_t init_radiotap_header(uint8_t stbc,
bool ldpc,
bool short_gi,
uint8_t bandwidth,
uint8_t mcs_index,
bool vht_mode,
uint8_t vht_nss)
{
vector<uint8_t> radiotap_header;
radiotap_header_t res = {
.header = {},
.stbc = stbc,
.ldpc = ldpc,
.short_gi = short_gi,
.bandwidth = bandwidth,
.mcs_index = mcs_index,
.vht_mode = vht_mode,
.vht_nss = vht_nss,
};

if (!vht_mode)
{
Expand Down Expand Up @@ -847,17 +899,17 @@ vector<uint8_t> init_radiotap_header(uint8_t stbc,
flags |= IEEE80211_RADIOTAP_MCS_FEC_LDPC;
}

copy(radiotap_header_ht, radiotap_header_ht + sizeof(radiotap_header_ht), back_inserter(radiotap_header));
copy(radiotap_header_ht, radiotap_header_ht + sizeof(radiotap_header_ht), back_inserter(res.header));

radiotap_header[MCS_FLAGS_OFF] = flags;
radiotap_header[MCS_IDX_OFF] = mcs_index;
res.header[MCS_FLAGS_OFF] = flags;
res.header[MCS_IDX_OFF] = mcs_index;
}
else
{
// Set flags in VHT radiotap header
uint8_t flags = 0;

copy(radiotap_header_vht, radiotap_header_vht + sizeof(radiotap_header_vht), back_inserter(radiotap_header));
copy(radiotap_header_vht, radiotap_header_vht + sizeof(radiotap_header_vht), back_inserter(res.header));

if (short_gi)
{
Expand All @@ -872,35 +924,35 @@ vector<uint8_t> init_radiotap_header(uint8_t stbc,
switch(bandwidth)
{
case 10:
radiotap_header[VHT_BW_OFF] = IEEE80211_RADIOTAP_VHT_BW_20M;
res.header[VHT_BW_OFF] = IEEE80211_RADIOTAP_VHT_BW_20M;
break;
case 20:
radiotap_header[VHT_BW_OFF] = IEEE80211_RADIOTAP_VHT_BW_20M;
res.header[VHT_BW_OFF] = IEEE80211_RADIOTAP_VHT_BW_20M;
break;
case 40:
radiotap_header[VHT_BW_OFF] = IEEE80211_RADIOTAP_VHT_BW_40M;
res.header[VHT_BW_OFF] = IEEE80211_RADIOTAP_VHT_BW_40M;
break;
case 80:
radiotap_header[VHT_BW_OFF] = IEEE80211_RADIOTAP_VHT_BW_80M;
res.header[VHT_BW_OFF] = IEEE80211_RADIOTAP_VHT_BW_80M;
break;
case 160:
radiotap_header[VHT_BW_OFF] = IEEE80211_RADIOTAP_VHT_BW_160M;
res.header[VHT_BW_OFF] = IEEE80211_RADIOTAP_VHT_BW_160M;
break;
default:
throw runtime_error(string_format("Unsupported VHT bandwidth: %d", bandwidth));
}

if (ldpc)
{
radiotap_header[VHT_CODING_OFF] = IEEE80211_RADIOTAP_VHT_CODING_LDPC_USER0;
res.header[VHT_CODING_OFF] = IEEE80211_RADIOTAP_VHT_CODING_LDPC_USER0;
}

radiotap_header[VHT_FLAGS_OFF] = flags;
radiotap_header[VHT_MCSNSS0_OFF] |= ((mcs_index << IEEE80211_RADIOTAP_VHT_MCS_SHIFT) & IEEE80211_RADIOTAP_VHT_MCS_MASK);
radiotap_header[VHT_MCSNSS0_OFF] |= ((vht_nss << IEEE80211_RADIOTAP_VHT_NSS_SHIFT) & IEEE80211_RADIOTAP_VHT_NSS_MASK);
res.header[VHT_FLAGS_OFF] = flags;
res.header[VHT_MCSNSS0_OFF] |= ((mcs_index << IEEE80211_RADIOTAP_VHT_MCS_SHIFT) & IEEE80211_RADIOTAP_VHT_MCS_MASK);
res.header[VHT_MCSNSS0_OFF] |= ((vht_nss << IEEE80211_RADIOTAP_VHT_NSS_SHIFT) & IEEE80211_RADIOTAP_VHT_NSS_MASK);
}

return radiotap_header;
return res;
}


Expand Down
56 changes: 44 additions & 12 deletions src/tx.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,19 @@ typedef struct {
} tags_item_t;


typedef struct {
std::vector<uint8_t> header;

// header info
uint8_t stbc;
bool ldpc;
bool short_gi;
uint8_t bandwidth;
uint8_t mcs_index;
bool vht_mode;
uint8_t vht_nss;
} radiotap_header_t;

class Transmitter
{
public:
Expand All @@ -47,9 +60,11 @@ class Transmitter
bool send_packet(const uint8_t *buf, size_t size, uint8_t flags);
void send_session_key(void);
void init_session(int k, int n);
void get_fec(int &k, int &n) { k = fec_k; n = fec_n; }
virtual void select_output(int idx) = 0;
virtual void dump_stats(FILE *fp, uint64_t ts, uint32_t &injected_packets, uint32_t &dropped_packets, uint32_t &injected_bytes) = 0;
virtual void update_radiotap_header(std::vector<uint8_t> &radiotap_header) {}
virtual void update_radiotap_header(radiotap_header_t &radiotap_header) = 0;
virtual radiotap_header_t get_radiotap_header(void) = 0;
protected:
virtual void inject_packet(const uint8_t *buf, size_t size) = 0;
virtual void set_mark(uint32_t idx) = 0;
Expand Down Expand Up @@ -124,7 +139,7 @@ class RawSocketTransmitter : public Transmitter
{
public:
RawSocketTransmitter(int k, int n, const std::string &keypair, uint64_t epoch, uint32_t channel_id, uint32_t fec_delay, std::vector<tags_item_t> &tags,
const std::vector<std::string> &wlans, std::vector<uint8_t> &radiotap_header,
const std::vector<std::string> &wlans, radiotap_header_t &radiotap_header,
uint8_t frame_type, bool use_qdisc, uint32_t fwmark);
virtual ~RawSocketTransmitter();
virtual void select_output(int idx)
Expand All @@ -139,11 +154,16 @@ class RawSocketTransmitter : public Transmitter
}
}
virtual void dump_stats(FILE *fp, uint64_t ts, uint32_t &injected_packets, uint32_t &dropped_packets, uint32_t &injected_bytes);
virtual void update_radiotap_header(std::vector<uint8_t> &radiotap_header)
virtual void update_radiotap_header(radiotap_header_t &radiotap_header)
{
this->radiotap_header = radiotap_header;
}

virtual radiotap_header_t get_radiotap_header(void)
{
return radiotap_header;
}

private:
virtual void inject_packet(const uint8_t *buf, size_t size);
virtual void set_mark(uint32_t idx);
Expand All @@ -152,7 +172,7 @@ class RawSocketTransmitter : public Transmitter
uint16_t ieee80211_seq;
std::vector<int> sockfds;
tx_antenna_stat_t antenna_stat;
std::vector<uint8_t> radiotap_header;
radiotap_header_t radiotap_header;
const uint8_t frame_type;
const bool use_qdisc;
const uint32_t fwmark;
Expand All @@ -164,7 +184,7 @@ class UdpTransmitter : public Transmitter
public:
UdpTransmitter(int k, int n, const std::string &keypair, const std::string &client_addr, int base_port, uint64_t epoch, uint32_t channel_id,
uint32_t fec_delay, std::vector<tags_item_t> &tags, bool use_qdisc, uint32_t fwmark): \
Transmitter(k, n, keypair, epoch, channel_id, fec_delay, tags), base_port(base_port), use_qdisc(use_qdisc), fwmark(fwmark)
Transmitter(k, n, keypair, epoch, channel_id, fec_delay, tags), radiotap_header({}), base_port(base_port), use_qdisc(use_qdisc), fwmark(fwmark)
{
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if (sockfd < 0) throw std::runtime_error(string_format("Error opening socket: %s", strerror(errno)));
Expand Down Expand Up @@ -202,6 +222,17 @@ class UdpTransmitter : public Transmitter
}
}

virtual void update_radiotap_header(radiotap_header_t &radiotap_header)
{
this->radiotap_header = radiotap_header;
}

virtual radiotap_header_t get_radiotap_header(void)
{
return radiotap_header;
}


private:
virtual void inject_packet(const uint8_t *buf, size_t size)
{
Expand Down Expand Up @@ -235,17 +266,18 @@ class UdpTransmitter : public Transmitter
sendmsg(sockfd, &msghdr, MSG_DONTWAIT);
}

radiotap_header_t radiotap_header;
int sockfd;
int base_port;
struct sockaddr_in saddr;
const bool use_qdisc;
const uint32_t fwmark;
};

std::vector<uint8_t> init_radiotap_header(uint8_t stbc,
bool ldpc,
bool short_gi,
uint8_t bandwidth,
uint8_t mcs_index,
bool vht_mode,
uint8_t vht_nss);
radiotap_header_t init_radiotap_header(uint8_t stbc,
bool ldpc,
bool short_gi,
uint8_t bandwidth,
uint8_t mcs_index,
bool vht_mode,
uint8_t vht_nss);
Loading

0 comments on commit fe85e64

Please sign in to comment.