Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
121 changes: 78 additions & 43 deletions src/ckernelwifi.cc
Original file line number Diff line number Diff line change
Expand Up @@ -44,24 +44,19 @@ void CKernelWifi::cout_mac_address(struct ether_addr *src)
std::cout << addr;
}

int CKernelWifi::send_tx_info_frame_nl(struct ether_addr *src, unsigned int flags, int signal, struct hwsim_tx_rate *tx_attempts, unsigned long cookie)
struct nl_msg *CKernelWifi::build_tx_info(struct ether_addr *src, unsigned int flags, int signal, struct hwsim_tx_rate *tx_attempts, unsigned long cookie)
{
struct nl_msg *msg = nullptr;

msg = nlmsg_alloc();

if (!msg) {

std::cerr << "Error allocating new message MSG !" << std::endl ;
nlmsg_free(msg);
return 0;
}
if (!msg)
return nullptr;

if (m_family_id < 0){

std::cerr << __func__ << "m_family_id < 0" << std::endl ;
nlmsg_free(msg);
return 0;
return nullptr;
}

genlmsg_put(msg, NL_AUTO_PID, NL_AUTO_SEQ, m_family_id, 0, NLM_F_REQUEST, HWSIM_CMD_TX_INFO_FRAME, VERSION_NR);
Expand All @@ -77,10 +72,21 @@ int CKernelWifi::send_tx_info_frame_nl(struct ether_addr *src, unsigned int flag
{
std::cerr << "Error filling payload" << std::endl;
nlmsg_free(msg);
return 0;
return NULL;
}

//nl_send_auto_complete(_netlink_socket, msg); //deprecated
return msg;
}

int CKernelWifi::send_tx_info_frame_nl(struct ether_addr *src, unsigned int flags, int signal, struct hwsim_tx_rate *tx_attempts, unsigned long cookie)
{
struct nl_msg *msg = build_tx_info(src, flags, signal, tx_attempts, cookie);

if (!msg) {
std::cerr << "Error allocating new message MSG !" << std::endl ;
nlmsg_free(msg);
return 0;
}

if (nl_send_auto(_netlink_socket, msg) < 0)
{
Expand Down Expand Up @@ -137,31 +143,6 @@ int CKernelWifi::process_messages(struct nl_msg *msg)
struct ether_addr macsrchwsim;
memcpy(&macsrchwsim,src,sizeof(macsrchwsim)); // backup the original mac src

/* Let's flag this frame as ACK'ed */
/* whatever that means... */
unsigned int flags = nla_get_u32(attrs[HWSIM_ATTR_FLAGS]);
flags |= HWSIM_TX_STAT_ACK;

/* this is the signal sent to the sender, not the receiver */
int signal = -10;

/* We get the tx_rates struct */
struct hwsim_tx_rate* tx_rates = (struct hwsim_tx_rate *)nla_data(attrs[HWSIM_ATTR_TX_INFO]);

u64 cookie = nla_get_u64(attrs[HWSIM_ATTR_COOKIE]);

/* this has to be an ack the driver expects */
/* what does the driver do with these values? can i remove them? */
send_tx_info_frame_nl(src, flags, signal, tx_rates, cookie);

/*
* no need to send a tx info frame indicating failure with a
* signal of 0 - that was done in the tx code i took this from
* if i check for ack messages than i could add a failure message
*/

/* we are now done with our code addition which sends the ack */

/* we get the attributes*/
char* data = (char *)nla_data(attrs[HWSIM_ATTR_FRAME]);
unsigned int data_len = nla_len(attrs[HWSIM_ATTR_FRAME]);
Expand Down Expand Up @@ -198,8 +179,10 @@ int CKernelWifi::process_messages(struct nl_msg *msg)
}

int value=_SendSignal(&power, (char*)nlh, msg_len);
if( value == SOCKET_ERROR )
if( value == SOCKET_ERROR ) {
printf("Error sending to server\n");
manage_server_crash();
}

// Send also on the others interfaces on the same VM :
// ------------------->
Expand Down Expand Up @@ -454,6 +437,7 @@ int CKernelWifi::send_cloned_frame_msg(struct ether_addr *dst, char *data, int d
}

void CKernelWifi::recv_from_server(){
uint8_t dropped;

if ( ! is_connected_to_server())
return ;
Expand All @@ -467,8 +451,10 @@ void CKernelWifi::recv_from_server(){
return ;

TPower power;
if( _RecvSignal(&power, &Buffer) == SOCKET_ERROR )
if( _RecvSignal(&power, &dropped, &Buffer) == SOCKET_ERROR ) {
printf("Error receiving from server\n");
manage_server_crash();
}

int signal = power ;

Expand All @@ -478,16 +464,41 @@ void CKernelWifi::recv_from_server(){
/* generic netlink header */
struct genlmsghdr* gnlh = (struct genlmsghdr*)nlmsg_data(nlh);

/* we get the attributes*/
struct nlattr *attrs[HWSIM_ATTR_MAX + 1];
genlmsg_parse(nlh, 0, attrs, HWSIM_ATTR_MAX, NULL);

struct hwsim_tx_rate* tx_rates = (struct hwsim_tx_rate *)nla_data(attrs[HWSIM_ATTR_TX_INFO]);
u64 cookie = nla_get_u64(attrs[HWSIM_ATTR_COOKIE]);
unsigned int flags = nla_get_u32(attrs[HWSIM_ATTR_FLAGS]);
if (gnlh->cmd == HWSIM_CMD_TX_INFO_FRAME) {
// TX_INFO receved from server, send to kernel
std::vector<WirelessDevice> &inets = _list_winterfaces.list_devices();

for (auto & inet : inets)
{
struct ether_addr macdsthwsim = inet.getMachwsim();

send_tx_info_frame_nl(&macdsthwsim,
flags,
(int)signal,
tx_rates,
cookie);
}

delete &inets;

return;
}

/* exit if the message does not contain frame data */
if (gnlh->cmd != HWSIM_CMD_FRAME) {

std::cerr << "Error - received no frame data in message" << std::endl;
return ;
}

/* we get the attributes*/
struct nlattr *attrs[HWSIM_ATTR_MAX + 1];
genlmsg_parse(nlh, 0, attrs, HWSIM_ATTR_MAX, NULL);


/* we get frequence */
TFrequency freq;
Expand Down Expand Up @@ -526,8 +537,31 @@ void CKernelWifi::recv_from_server(){
#endif

/* copy mac dst address from frame */
struct ether_addr framedst;
memcpy(&framedst, data + 4, ETH_ALEN);
struct ether_addr framesrc;
memcpy(&framesrc, data + 10, ETH_ALEN);

if (!dropped)
flags |= HWSIM_TX_STAT_ACK;

#if 0
struct nl_msg *tx_info = build_tx_info(&framesrc, flags,
(int)signal,
tx_rates,
cookie);
struct nlmsghdr *hdr = nlmsg_hdr(tx_info);

// Send TX_Info back to server
int value=_SendSignal(&power, (char*)hdr, hdr->nlmsg_len);

nlmsg_free(tx_info);
if( value == SOCKET_ERROR ) {
printf("Error sending tx info to server\n");
manage_server_crash();
}
#endif

if (dropped)
return;

#ifdef _DEBUG
std::cout << "frame dst: "; cout_mac_address(&framedst);std::cout<<std::endl ;
Expand Down Expand Up @@ -900,6 +934,7 @@ bool CKernelWifi::is_connected_to_server(){

void CKernelWifi::manage_server_crash(){

printf("MANAGE SERVER CRASH");
connected_to_server(false) ;

}
Expand Down
5 changes: 4 additions & 1 deletion src/ckernelwifi.h
Original file line number Diff line number Diff line change
Expand Up @@ -228,12 +228,15 @@ class CKernelWifi : public intthread::AsyncTask {
*/
void manage_server_crash();

struct nl_msg *build_tx_info(struct ether_addr *src, unsigned int flags, int signal, struct hwsim_tx_rate *tx_attempts, unsigned long cookie);


// virtual :

virtual bool _Connect(int* id) = 0;

virtual ssize_t _SendSignal(TPower* power, const char* buffer, int sizeOfBuffer) = 0;
virtual ssize_t _RecvSignal(TPower* power, CDynBuffer* buffer) = 0;
virtual ssize_t _RecvSignal(TPower* power, uint8_t *dropped, CDynBuffer* buffer) = 0;

virtual void _Close() = 0;

Expand Down
4 changes: 3 additions & 1 deletion src/csocket.cc
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,10 @@ ssize_t CSocket::SendBigData(TDescriptor descriptor, const char* data, TMinimalS
ssize_t CSocket::Read(TDescriptor descriptor, char* data, ssize_t sizeOfData)
{
ssize_t ret = recv(descriptor , data, sizeOfData, 0);
if ( ret <= 0 )
if ( ret <= 0 ) {
printf("Recv failed with %ld\n", errno);
return SOCKET_ERROR ;
}

return ret;
}
Expand Down
29 changes: 23 additions & 6 deletions src/cwifi.cc
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
const double ConstanteC=92.45;
const TFrequency DEFAULT_FREQUENCY=2412; // Hz

const int MTU=1640; // Maximum Transmission Unit : 1640 is an experimental value
const int MTU=4096; // Maximum Transmission Unit : 1640 is an experimental value

TFrequency CWifi::GetFrequency(struct nlmsghdr* nlh)
{
Expand Down Expand Up @@ -62,36 +62,53 @@ bool CWifi::PacketIsLost(TPower signalLevel)
return true;
}

ssize_t CWifi::SendSignalWithSocket(CSocket* socket, TDescriptor descriptor, TPower* power, const char* buffer, int sizeOfBuffer)
ssize_t CWifi::SendSignalWithSocket(CSocket* socket, TDescriptor descriptor, TPower* power, uint8_t *dropped, const char* buffer, int sizeOfBuffer)
{
// cout<<"send power : "<<power<<endl;
int val=socket->Send(descriptor, (char*)power, sizeof(TPower));
if( val <= 0 )
return val;

val=socket->Send(descriptor, (char*)dropped, sizeof(uint8_t));
if( val <= 0 )
return val;

// std::cout<<"send big data of size : "<<sizeOfBuffer<<std::endl;
return socket->Send(descriptor, buffer, sizeOfBuffer);
}

ssize_t CWifi::RecvSignalWithSocket(CSocket* socket, TDescriptor descriptor, TPower* power, CDynBuffer* buffer)
ssize_t CWifi::RecvSignalWithSocket(CSocket* socket, TDescriptor descriptor, TPower* power, uint8_t *dropped, CDynBuffer* buffer)
{
int valread;

// read the power
valread = socket->Read(descriptor, (char*)power, sizeof(TPower));
if ( valread <= 0 )
if ( valread <= 0 ) {
printf("cannot read power %d\n", valread);
return valread;
}

// read dropped
valread = socket->Read(descriptor, (char*)dropped, sizeof(uint8_t));
if ( valread <= 0 ) {
printf("cannot read dropped %d\n", valread);
return valread;
}

// read the signal
// "nlmsg_len" (type "uint32_t") is the first attribut of the "struct nlmsghdr" in "libnl3/netlink/netlink-kernel.h"
ssize_t sizeRead = socket->ReadEqualSize(descriptor, buffer, 0, sizeof(struct nlmsghdr));
if( sizeRead == SOCKET_ERROR )
if( sizeRead == SOCKET_ERROR ) {
printf("Cannot read nlmsg_len\n");
return SOCKET_ERROR;
}

int sizeTotal=((struct nlmsghdr *)(buffer->GetBuffer()))->nlmsg_len;

if( sizeTotal > MTU ) // to avoid that a error packet overfulls the memory
if( sizeTotal > MTU ) { // to avoid that a error packet overfulls the memory
printf("Size greater than MTU %d\n", sizeTotal);
return SOCKET_ERROR;
}

return socket->ReadEqualSize(descriptor, buffer, sizeRead, sizeTotal);
}
4 changes: 2 additions & 2 deletions src/cwifi.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ class CWifi

bool PacketIsLost(TPower signalLevel);

ssize_t SendSignalWithSocket(CSocket* socket, TDescriptor descriptor, TPower* power, const char* buffer, int sizeOfBuffer);
ssize_t RecvSignalWithSocket(CSocket* socket, TDescriptor descriptor, TPower* power, CDynBuffer* buffer);
ssize_t SendSignalWithSocket(CSocket* socket, TDescriptor descriptor, TPower* power, uint8_t *dropped, const char* buffer, int sizeOfBuffer);
ssize_t RecvSignalWithSocket(CSocket* socket, TDescriptor descriptor, TPower* power, uint8_t *dropped, CDynBuffer* buffer);
};

#endif
9 changes: 6 additions & 3 deletions src/cwificlient.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,13 @@ class CWifiClient : public CKernelWifi, public CWifi, public TypeCSocketClient
}

ssize_t _SendSignal(TPower* power, const char* buffer, int sizeOfBuffer) override
{ return SendSignalWithSocket(this, this->GetDescriptor(), power, buffer, sizeOfBuffer); }
{
uint8_t dropped = 0;
return SendSignalWithSocket(this, this->GetDescriptor(), power, &dropped, buffer, sizeOfBuffer);
}

ssize_t _RecvSignal(TPower* power, CDynBuffer* buffer) override
{ return RecvSignalWithSocket(this, this->GetDescriptor(), power, buffer); }
ssize_t _RecvSignal(TPower* power, uint8_t *dropped, CDynBuffer* buffer) override
{ return RecvSignalWithSocket(this, this->GetDescriptor(), power, dropped, buffer); }

void _Close() override { TypeCSocketClient::Close(); };
};
Expand Down
22 changes: 13 additions & 9 deletions src/cwifiserver.cc
Original file line number Diff line number Diff line change
Expand Up @@ -180,14 +180,14 @@ void CWifiServer::CloseAllClient()
CloseClient(0); // we can Close the 0 because we use the shift
}

ssize_t CWifiServer::SendSignal(TDescriptor descriptor, TPower* power, const char* buffer, int sizeOfBuffer)
ssize_t CWifiServer::SendSignal(TDescriptor descriptor, TPower* power, uint8_t *dropped, const char* buffer, int sizeOfBuffer)
{
return SendSignalWithSocket(this, descriptor, power, buffer, sizeOfBuffer);
return SendSignalWithSocket(this, descriptor, power, dropped, buffer, sizeOfBuffer);
}

ssize_t CWifiServer::RecvSignal(TDescriptor descriptor, TPower* power, CDynBuffer* buffer)
ssize_t CWifiServer::RecvSignal(TDescriptor descriptor, TPower* power, uint8_t *dropped, CDynBuffer* buffer)
{
return RecvSignalWithSocket(this, descriptor, power, buffer);
return RecvSignalWithSocket(this, descriptor, power, dropped, buffer);
}

void CWifiServer::SendAllOtherClients(TIndex index,TPower power, const char* data, ssize_t sizeOfData)
Expand All @@ -202,30 +202,34 @@ void CWifiServer::SendAllOtherClients(TIndex index,TPower power, const char* dat
{
TFrequency frequency=GetFrequency((struct nlmsghdr*)data);
TPower signalLevel=BoundedPower(power-Attenuation(coo.DistanceWith((*InfoWifis)[i]),frequency));
uint8_t dropped = CanLostPackets && PacketIsLost(signalLevel);

if( ! CanLostPackets || ! PacketIsLost(signalLevel) )
if( SendSignal((*InfoSockets)[i].GetDescriptor(), &signalLevel, data, sizeOfData) < 0 )
(*InfoSockets)[i].DisableIt();
if( SendSignal((*InfoSockets)[i].GetDescriptor(), &signalLevel, &dropped, data, sizeOfData) < 0 )
(*InfoSockets)[i].DisableIt();
}
}
}

void CWifiServer::SendAllOtherClientsWithoutLoss(TIndex index, TPower power, const char* data, ssize_t sizeOfData)
{
uint8_t dropped = 0;

for (TIndex i = 0; i < GetNumberClient(); i++)
{
if( i != index )
if( IsEnable(i) )
if( SendSignal((*InfoSockets)[i].GetDescriptor(), &power, data, sizeOfData) < 0 )
if( SendSignal((*InfoSockets)[i].GetDescriptor(), &power, &dropped, data, sizeOfData) < 0 )
(*InfoSockets)[i].DisableIt();
}
}

void CWifiServer::SendAllClientsWithoutLoss(TPower power, const char* data, ssize_t sizeOfData)
{
uint8_t dropped = 0;

for (TIndex i = 0; i < GetNumberClient(); i++)
if( IsEnable(i) )
if( SendSignal((*InfoSockets)[i].GetDescriptor(), &power, data, sizeOfData) < 0 )
if( SendSignal((*InfoSockets)[i].GetDescriptor(), &power, &dropped, data, sizeOfData) < 0 )
(*InfoSockets)[i].DisableIt();
}

Expand Down
4 changes: 2 additions & 2 deletions src/cwifiserver.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,9 @@ class CWifiServer : public CSocketServer, public CWifi

void CloseAllClient();

ssize_t SendSignal(TDescriptor descriptor, TPower* power, const char* buffer, int sizeOfBuffer);
ssize_t SendSignal(TDescriptor descriptor, TPower* power, uint8_t *dropped, const char* buffer, int sizeOfBuffer);

ssize_t RecvSignal(TDescriptor descriptor, TPower* power, CDynBuffer* buffer);
ssize_t RecvSignal(TDescriptor descriptor, TPower* power, uint8_t *dropped, CDynBuffer* buffer);

void SendAllOtherClients(TIndex index,TPower power, const char* data, ssize_t sizeOfData);

Expand Down
Loading