Upstream vwifi v7.0 (Raizo62/vwifi @ 4a9842e)
Unmodified upstream source from https://github.com/Raizo62/vwifi Commit: 4a9842e "CMakeLists.txt : VERSION = 7.0" Simulator of WiFi (802.11) interfaces to communicate between several Virtual Machines via mac80211_hwsim + TCP relay. License: Apache-2.0
This commit is contained in:
+25
@@ -0,0 +1,25 @@
|
|||||||
|
# Old build artifacts
|
||||||
|
# vwifi-server
|
||||||
|
# vwifi-client
|
||||||
|
# vwifi-ctrl
|
||||||
|
# vwifi-add-interfaces
|
||||||
|
# obj/
|
||||||
|
|
||||||
|
# CMake build artifacts
|
||||||
|
build/
|
||||||
|
CMakeCache.txt
|
||||||
|
CMakeFiles/
|
||||||
|
cmake_install.cmake
|
||||||
|
compile_commands.json
|
||||||
|
Makefile
|
||||||
|
*.a
|
||||||
|
*.so
|
||||||
|
|
||||||
|
# For cppcheck
|
||||||
|
vwifi-cppcheck.xml
|
||||||
|
# For eclipse :
|
||||||
|
.project
|
||||||
|
.cproject
|
||||||
|
.settings
|
||||||
|
# For Visual Studio Code :
|
||||||
|
.vscode
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
Raizo62 (David Ansart / https://github.com/Raizo62)
|
||||||
|
SecurityLab (Boussad Ait-Salem / https://securitylab.fr/home)
|
||||||
+162
@@ -0,0 +1,162 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.10)
|
||||||
|
|
||||||
|
project(vwifi VERSION 7.0 LANGUAGES CXX)
|
||||||
|
|
||||||
|
set(CMAKE_CXX_STANDARD 14)
|
||||||
|
set(CMAKE_CXX_STANDARD_REQUIRED True)
|
||||||
|
|
||||||
|
# --- Compiler Flags ---
|
||||||
|
# Add flags similar to the Makefile's MODE settings
|
||||||
|
# Using Release build type for optimizations by default
|
||||||
|
if(NOT CMAKE_BUILD_TYPE)
|
||||||
|
set(CMAKE_BUILD_TYPE Release CACHE STRING "Choose build type: Debug Release RelWithDebInfo MinSizeRel" FORCE)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
option(ENABLE_VHOST "Enable vhost support" ON)
|
||||||
|
if(NOT ENABLE_VHOST)
|
||||||
|
add_definitions(-DDISABLE_VHOST)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Common flags (add more as needed based on Makefile MODE)
|
||||||
|
add_compile_options(-Wall -Wextra -pedantic)
|
||||||
|
if(CMAKE_BUILD_TYPE STREQUAL "Release")
|
||||||
|
add_compile_options(-O3 -s)
|
||||||
|
# add_definitions(-DNDEBUG) # Uncomment if asserts should be disabled in release
|
||||||
|
elseif(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||||
|
add_compile_options(-g)
|
||||||
|
add_definitions(-D_DEBUG)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Add version definition
|
||||||
|
# Check if this is a git repository and get the commit hash
|
||||||
|
find_package(Git QUIET)
|
||||||
|
if(GIT_FOUND AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/.git")
|
||||||
|
execute_process(
|
||||||
|
COMMAND "${GIT_EXECUTABLE}" log --pretty=format:%h -n 1
|
||||||
|
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
|
||||||
|
OUTPUT_VARIABLE GIT_COMMIT_HASH
|
||||||
|
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||||
|
ERROR_QUIET
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(GIT_COMMIT_HASH)
|
||||||
|
set(FULL_VERSION "${PROJECT_VERSION}-${GIT_COMMIT_HASH}")
|
||||||
|
message(STATUS "Building Git version: ${FULL_VERSION}")
|
||||||
|
else()
|
||||||
|
set(FULL_VERSION "${PROJECT_VERSION}")
|
||||||
|
message(STATUS "Building version: ${FULL_VERSION} (Not a Git repo or git error)")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
add_definitions(-DVERSION=\"${FULL_VERSION}\")
|
||||||
|
|
||||||
|
# --- Find Dependencies ---
|
||||||
|
find_package(Threads REQUIRED)
|
||||||
|
find_package(PkgConfig REQUIRED)
|
||||||
|
pkg_check_modules(LIBNL3 REQUIRED IMPORTED_TARGET libnl-genl-3.0 libnl-3.0)
|
||||||
|
|
||||||
|
# --- Include Directories ---
|
||||||
|
include_directories(src)
|
||||||
|
include_directories(${LIBNL3_INCLUDE_DIRS})
|
||||||
|
|
||||||
|
# --- Common Static Library ---
|
||||||
|
# List all .cc files EXCEPT the main files for the executables
|
||||||
|
set(COMMON_SOURCES
|
||||||
|
src/ccoordinate.cc
|
||||||
|
src/cctrlserver.cc
|
||||||
|
src/cdynbuffer.cc
|
||||||
|
src/cinfosocket.cc
|
||||||
|
src/cinfowifi.cc
|
||||||
|
src/ckernelwifi.cc
|
||||||
|
src/cmonwirelessdevice.cc
|
||||||
|
src/cselect.cc
|
||||||
|
src/csocket.cc
|
||||||
|
src/csocketclient.cc
|
||||||
|
src/csocketclientitcp.cc
|
||||||
|
src/csocketclientvtcp.cc
|
||||||
|
src/csocketserver.cc
|
||||||
|
src/csocketserverfunctionitcp.cc
|
||||||
|
src/csocketserverfunctionvtcp.cc
|
||||||
|
src/cthread.cc
|
||||||
|
src/cwifi.cc
|
||||||
|
src/cwificlient.cc
|
||||||
|
src/cwifiserver.cc
|
||||||
|
src/cwifiserveritcp.cc
|
||||||
|
src/cwifiservervtcp.cc
|
||||||
|
src/cwirelessdevice.cc
|
||||||
|
src/cwirelessdevicelist.cc
|
||||||
|
src/tools.cc
|
||||||
|
src/addinterfaces.cc
|
||||||
|
)
|
||||||
|
|
||||||
|
add_library(vwifi_common STATIC ${COMMON_SOURCES})
|
||||||
|
# Link common library dependencies once
|
||||||
|
target_link_libraries(vwifi_common PUBLIC Threads::Threads PkgConfig::LIBNL3)
|
||||||
|
|
||||||
|
|
||||||
|
# --- Executables ---
|
||||||
|
add_executable(vwifi-server src/vwifi-server.cc)
|
||||||
|
target_link_libraries(vwifi-server PRIVATE vwifi_common)
|
||||||
|
|
||||||
|
add_executable(vwifi-client src/vwifi-client.cc)
|
||||||
|
target_link_libraries(vwifi-client PRIVATE vwifi_common)
|
||||||
|
|
||||||
|
add_executable(vwifi-ctrl src/vwifi-ctrl.cc)
|
||||||
|
target_link_libraries(vwifi-ctrl PRIVATE vwifi_common)
|
||||||
|
|
||||||
|
add_executable(vwifi-add-interfaces src/vwifi-add-interfaces.cc)
|
||||||
|
# vwifi-add-interfaces seems to only need addinterfaces.o, which is in vwifi_common
|
||||||
|
target_link_libraries(vwifi-add-interfaces PRIVATE vwifi_common)
|
||||||
|
|
||||||
|
# Optional: vwifi-inet-monitor (based on commented out Makefile line)
|
||||||
|
# add_executable(vwifi-inet-monitor src/vwifi-inet-monitor.cc)
|
||||||
|
# target_link_libraries(vwifi-inet-monitor PRIVATE vwifi_common) # Check its specific dependencies if uncommenting
|
||||||
|
|
||||||
|
# --- Installation ---
|
||||||
|
include(GNUInstallDirs)
|
||||||
|
install(TARGETS vwifi-server vwifi-client vwifi-ctrl vwifi-add-interfaces
|
||||||
|
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
|
||||||
|
|
||||||
|
# Optional: Install man pages if needed (requires CMake code)
|
||||||
|
# install(FILES man/vwifi.1 DESTINATION ${CMAKE_INSTALL_MANDIR}/man1 RENAME vwifi.1)
|
||||||
|
|
||||||
|
# --- Optional: Add tests ---
|
||||||
|
# enable_testing()
|
||||||
|
# add_subdirectory(tests) # If tests have their own CMakeLists.txt
|
||||||
|
|
||||||
|
# --- Custom Target for Cppcheck ---
|
||||||
|
find_program(CPPCHECK_EXECUTABLE cppcheck)
|
||||||
|
if(CPPCHECK_EXECUTABLE)
|
||||||
|
file(GLOB_RECURSE ALL_CC_SOURCES "src/*.cc")
|
||||||
|
|
||||||
|
get_property(GLOBAL_DEFINITIONS DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY COMPILE_DEFINITIONS)
|
||||||
|
set(CPPCHECK_DEFS "")
|
||||||
|
foreach(DEF ${GLOBAL_DEFINITIONS})
|
||||||
|
if(DEF MATCHES "^-D")
|
||||||
|
set(CPPCHECK_DEFS "${CPPCHECK_DEFS} ${DEF}")
|
||||||
|
else()
|
||||||
|
set(CPPCHECK_DEFS "${CPPCHECK_DEFS} -D${DEF}")
|
||||||
|
endif()
|
||||||
|
endforeach()
|
||||||
|
set(CPPCHECK_DEFS "${CPPCHECK_DEFS} -D_DEBUG")
|
||||||
|
|
||||||
|
get_property(COMMON_COMPILE_OPTIONS DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY COMPILE_OPTIONS)
|
||||||
|
set(CPPCHECK_CFLAGS "")
|
||||||
|
foreach(OPT ${COMMON_COMPILE_OPTIONS})
|
||||||
|
set(CPPCHECK_CFLAGS "${CPPCHECK_CFLAGS} ${OPT}")
|
||||||
|
endforeach()
|
||||||
|
|
||||||
|
# Définition du chemin de sortie du fichier XML
|
||||||
|
# CMAKE_CURRENT_BINARY_DIR pointe vers le répertoire de construction
|
||||||
|
set(CPPCHECK_OUTPUT_FILE "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-cppcheck.xml")
|
||||||
|
|
||||||
|
add_custom_target(
|
||||||
|
cppcheck
|
||||||
|
COMMAND ${CPPCHECK_EXECUTABLE} --verbose --enable=all --enable=style --xml
|
||||||
|
${CPPCHECK_CFLAGS} ${CPPCHECK_DEFS} ${ALL_CC_SOURCES} 2> ${CPPCHECK_OUTPUT_FILE}
|
||||||
|
# WORKING_DIRECTORY reste le répertoire source pour que cppcheck trouve les fichiers
|
||||||
|
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||||
|
COMMENT "Running Cppcheck static analysis and generating XML report in build directory."
|
||||||
|
BYPRODUCTS ${CPPCHECK_OUTPUT_FILE}
|
||||||
|
)
|
||||||
|
endif()
|
||||||
+165
@@ -0,0 +1,165 @@
|
|||||||
|
GNU LESSER GENERAL PUBLIC LICENSE
|
||||||
|
Version 3, 29 June 2007
|
||||||
|
|
||||||
|
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
|
||||||
|
Everyone is permitted to copy and distribute verbatim copies
|
||||||
|
of this license document, but changing it is not allowed.
|
||||||
|
|
||||||
|
|
||||||
|
This version of the GNU Lesser General Public License incorporates
|
||||||
|
the terms and conditions of version 3 of the GNU General Public
|
||||||
|
License, supplemented by the additional permissions listed below.
|
||||||
|
|
||||||
|
0. Additional Definitions.
|
||||||
|
|
||||||
|
As used herein, "this License" refers to version 3 of the GNU Lesser
|
||||||
|
General Public License, and the "GNU GPL" refers to version 3 of the GNU
|
||||||
|
General Public License.
|
||||||
|
|
||||||
|
"The Library" refers to a covered work governed by this License,
|
||||||
|
other than an Application or a Combined Work as defined below.
|
||||||
|
|
||||||
|
An "Application" is any work that makes use of an interface provided
|
||||||
|
by the Library, but which is not otherwise based on the Library.
|
||||||
|
Defining a subclass of a class defined by the Library is deemed a mode
|
||||||
|
of using an interface provided by the Library.
|
||||||
|
|
||||||
|
A "Combined Work" is a work produced by combining or linking an
|
||||||
|
Application with the Library. The particular version of the Library
|
||||||
|
with which the Combined Work was made is also called the "Linked
|
||||||
|
Version".
|
||||||
|
|
||||||
|
The "Minimal Corresponding Source" for a Combined Work means the
|
||||||
|
Corresponding Source for the Combined Work, excluding any source code
|
||||||
|
for portions of the Combined Work that, considered in isolation, are
|
||||||
|
based on the Application, and not on the Linked Version.
|
||||||
|
|
||||||
|
The "Corresponding Application Code" for a Combined Work means the
|
||||||
|
object code and/or source code for the Application, including any data
|
||||||
|
and utility programs needed for reproducing the Combined Work from the
|
||||||
|
Application, but excluding the System Libraries of the Combined Work.
|
||||||
|
|
||||||
|
1. Exception to Section 3 of the GNU GPL.
|
||||||
|
|
||||||
|
You may convey a covered work under sections 3 and 4 of this License
|
||||||
|
without being bound by section 3 of the GNU GPL.
|
||||||
|
|
||||||
|
2. Conveying Modified Versions.
|
||||||
|
|
||||||
|
If you modify a copy of the Library, and, in your modifications, a
|
||||||
|
facility refers to a function or data to be supplied by an Application
|
||||||
|
that uses the facility (other than as an argument passed when the
|
||||||
|
facility is invoked), then you may convey a copy of the modified
|
||||||
|
version:
|
||||||
|
|
||||||
|
a) under this License, provided that you make a good faith effort to
|
||||||
|
ensure that, in the event an Application does not supply the
|
||||||
|
function or data, the facility still operates, and performs
|
||||||
|
whatever part of its purpose remains meaningful, or
|
||||||
|
|
||||||
|
b) under the GNU GPL, with none of the additional permissions of
|
||||||
|
this License applicable to that copy.
|
||||||
|
|
||||||
|
3. Object Code Incorporating Material from Library Header Files.
|
||||||
|
|
||||||
|
The object code form of an Application may incorporate material from
|
||||||
|
a header file that is part of the Library. You may convey such object
|
||||||
|
code under terms of your choice, provided that, if the incorporated
|
||||||
|
material is not limited to numerical parameters, data structure
|
||||||
|
layouts and accessors, or small macros, inline functions and templates
|
||||||
|
(ten or fewer lines in length), you do both of the following:
|
||||||
|
|
||||||
|
a) Give prominent notice with each copy of the object code that the
|
||||||
|
Library is used in it and that the Library and its use are
|
||||||
|
covered by this License.
|
||||||
|
|
||||||
|
b) Accompany the object code with a copy of the GNU GPL and this license
|
||||||
|
document.
|
||||||
|
|
||||||
|
4. Combined Works.
|
||||||
|
|
||||||
|
You may convey a Combined Work under terms of your choice that,
|
||||||
|
taken together, effectively do not restrict modification of the
|
||||||
|
portions of the Library contained in the Combined Work and reverse
|
||||||
|
engineering for debugging such modifications, if you also do each of
|
||||||
|
the following:
|
||||||
|
|
||||||
|
a) Give prominent notice with each copy of the Combined Work that
|
||||||
|
the Library is used in it and that the Library and its use are
|
||||||
|
covered by this License.
|
||||||
|
|
||||||
|
b) Accompany the Combined Work with a copy of the GNU GPL and this license
|
||||||
|
document.
|
||||||
|
|
||||||
|
c) For a Combined Work that displays copyright notices during
|
||||||
|
execution, include the copyright notice for the Library among
|
||||||
|
these notices, as well as a reference directing the user to the
|
||||||
|
copies of the GNU GPL and this license document.
|
||||||
|
|
||||||
|
d) Do one of the following:
|
||||||
|
|
||||||
|
0) Convey the Minimal Corresponding Source under the terms of this
|
||||||
|
License, and the Corresponding Application Code in a form
|
||||||
|
suitable for, and under terms that permit, the user to
|
||||||
|
recombine or relink the Application with a modified version of
|
||||||
|
the Linked Version to produce a modified Combined Work, in the
|
||||||
|
manner specified by section 6 of the GNU GPL for conveying
|
||||||
|
Corresponding Source.
|
||||||
|
|
||||||
|
1) Use a suitable shared library mechanism for linking with the
|
||||||
|
Library. A suitable mechanism is one that (a) uses at run time
|
||||||
|
a copy of the Library already present on the user's computer
|
||||||
|
system, and (b) will operate properly with a modified version
|
||||||
|
of the Library that is interface-compatible with the Linked
|
||||||
|
Version.
|
||||||
|
|
||||||
|
e) Provide Installation Information, but only if you would otherwise
|
||||||
|
be required to provide such information under section 6 of the
|
||||||
|
GNU GPL, and only to the extent that such information is
|
||||||
|
necessary to install and execute a modified version of the
|
||||||
|
Combined Work produced by recombining or relinking the
|
||||||
|
Application with a modified version of the Linked Version. (If
|
||||||
|
you use option 4d0, the Installation Information must accompany
|
||||||
|
the Minimal Corresponding Source and Corresponding Application
|
||||||
|
Code. If you use option 4d1, you must provide the Installation
|
||||||
|
Information in the manner specified by section 6 of the GNU GPL
|
||||||
|
for conveying Corresponding Source.)
|
||||||
|
|
||||||
|
5. Combined Libraries.
|
||||||
|
|
||||||
|
You may place library facilities that are a work based on the
|
||||||
|
Library side by side in a single library together with other library
|
||||||
|
facilities that are not Applications and are not covered by this
|
||||||
|
License, and convey such a combined library under terms of your
|
||||||
|
choice, if you do both of the following:
|
||||||
|
|
||||||
|
a) Accompany the combined library with a copy of the same work based
|
||||||
|
on the Library, uncombined with any other library facilities,
|
||||||
|
conveyed under the terms of this License.
|
||||||
|
|
||||||
|
b) Give prominent notice with the combined library that part of it
|
||||||
|
is a work based on the Library, and explaining where to find the
|
||||||
|
accompanying uncombined form of the same work.
|
||||||
|
|
||||||
|
6. Revised Versions of the GNU Lesser General Public License.
|
||||||
|
|
||||||
|
The Free Software Foundation may publish revised and/or new versions
|
||||||
|
of the GNU Lesser General Public License from time to time. Such new
|
||||||
|
versions will be similar in spirit to the present version, but may
|
||||||
|
differ in detail to address new problems or concerns.
|
||||||
|
|
||||||
|
Each version is given a distinguishing version number. If the
|
||||||
|
Library as you received it specifies that a certain numbered version
|
||||||
|
of the GNU Lesser General Public License "or any later version"
|
||||||
|
applies to it, you have the option of following the terms and
|
||||||
|
conditions either of that published version or of any later version
|
||||||
|
published by the Free Software Foundation. If the Library as you
|
||||||
|
received it does not specify a version number of the GNU Lesser
|
||||||
|
General Public License, you may choose any version of the GNU Lesser
|
||||||
|
General Public License ever published by the Free Software Foundation.
|
||||||
|
|
||||||
|
If the Library as you received it specifies that a proxy can decide
|
||||||
|
whether future versions of the GNU Lesser General Public License shall
|
||||||
|
apply, that proxy's public statement of acceptance of any version is
|
||||||
|
permanent authorization for you to choose that version for the
|
||||||
|
Library.
|
||||||
@@ -0,0 +1,384 @@
|
|||||||
|
# What is this ?
|
||||||
|
|
||||||
|
Simulate Wi-Fi (802.11) between Linux Virtual Machines on Qemu/VirtualBox/...
|
||||||
|
|
||||||
|
* It can be used in Hypervisors (GNS3, QEmu, Virtualbox, VMware, Hyper-V, ...)
|
||||||
|
* The Wireless emulator uses the `mac80211_hwsim` linux driver
|
||||||
|
* Implements the packet loss simulation based on distance
|
||||||
|
* Emulates the node mobility in GNS3
|
||||||
|
|
||||||
|
* Tested:
|
||||||
|
* with `hostapd` and `wpa_supplicant` with these configurations:
|
||||||
|
* Open
|
||||||
|
* WEP
|
||||||
|
* WPA2
|
||||||
|
* WPA-EAP
|
||||||
|
* in the context of WPA2 attack with `Aircrack-NG` (Kali / Parrot-OS)
|
||||||
|
* with OpenWRT
|
||||||
|
|
||||||
|
* Remaining features to be implemented:
|
||||||
|
|
||||||
|
* Integrate to other OS (Windows...)
|
||||||
|
* Add obstacle models
|
||||||
|
* Etc.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
# Explanations
|
||||||
|
|
||||||
|
* With the parameter "-h" (or "--help"), all programs display help and their parameters
|
||||||
|
|
||||||
|
* ***vwifi-client*** should be started on the VMs, and ***vwifi-server*** on the Host.
|
||||||
|
* ***vwifi-client*** and ***vwifi-server*** can communicate either with the VHOST protocol (by default), or with the TCP protocol.
|
||||||
|
* With the option "-s" (or "--spy"), ***vwifi-client*** :
|
||||||
|
* receives always all communications, even if the loss of packets is enable ;
|
||||||
|
* works only with TCP ;
|
||||||
|
* connects to 127.0.0.1, by default ;
|
||||||
|
* ***vwifi-client*** uses the `mac80211_hwsim` kernel module to have the wifi interfaces.
|
||||||
|
* To use TCP protocol, ***vwifi-server*** and ***vwifi-client*** must be connected to a different IP network than that of the wifi.
|
||||||
|
* ***vwifi-add-interfaces*** is used to create the wlan interfaces to the module `mac80211_hwsim`. ***vwifi-client*** controls only these interfaces. ***vwifi-add-interfaces*** can be run several times.
|
||||||
|
* ***vwifi-ctrl*** is used to interact with ***vwifi-server***.
|
||||||
|
* ***vwifi-server*** can directly enable packet loss with the parameter "-l" (or "--lost-packets")
|
||||||
|
* If ***vwifi-server*** detects the same IP for several ***vwifi-client*** (due to PAT/NPAT/...), use the option "-u" ("-- use-port-in-hash") on ***vwifi-server*** to add the network port to create the ID for each client, instead of just using the IP. Attention, the display of ID by ***vwifi-server*** and ***vwifi-client*** will no longer be the same.
|
||||||
|
|
||||||
|
* You can change the defaults IP and ports with parameters (see the parameter "-h" to help)
|
||||||
|
|
||||||
|
# Install
|
||||||
|
|
||||||
|
## On Debian-based Linux distributions
|
||||||
|
|
||||||
|
### Dependencies
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get install cmake make g++ pkg-config
|
||||||
|
sudo apt-get install libnl-3-dev libnl-genl-3-dev
|
||||||
|
```
|
||||||
|
|
||||||
|
### Building
|
||||||
|
|
||||||
|
* Optional: To download and update the file `mac80211_hwsim.h` (if needed, requires wget) :
|
||||||
|
|
||||||
|
```bash
|
||||||
|
wget -q -N https://raw.githubusercontent.com/torvalds/linux/master/drivers/net/wireless/virtual/mac80211_hwsim.h -P src
|
||||||
|
```
|
||||||
|
* To change the default ports and IP, edit: `src/config.h`
|
||||||
|
|
||||||
|
* To configure :
|
||||||
|
|
||||||
|
```bash
|
||||||
|
mkdir build
|
||||||
|
cd build
|
||||||
|
cmake ..
|
||||||
|
```
|
||||||
|
* To Customize the build :
|
||||||
|
* For a debug build : Add `-DCMAKE_BUILD_TYPE=Debug`
|
||||||
|
* To disable VHOST protocol : Add `-DENABLE_VHOST=OFF`
|
||||||
|
|
||||||
|
* To build : `make`
|
||||||
|
|
||||||
|
* To install : `sudo make install`
|
||||||
|
|
||||||
|
## On OpenWRT
|
||||||
|
|
||||||
|
* See the wiki : [Install-vwifi-on-OpenWRT-X86_64](https://github.com/Raizo62/vwifi/wiki/Install-on-OpenWRT-X86_64)
|
||||||
|
|
||||||
|
# Configuration
|
||||||
|
|
||||||
|
## Method 1 : With VHOST
|
||||||
|
|
||||||
|
### Host
|
||||||
|
|
||||||
|
* Shell :
|
||||||
|
* Load the module VHOST :
|
||||||
|
```bash
|
||||||
|
# sudo modprobe -r vhost_vsock vmw_vsock_virtio_transport_common vsock # if necessary
|
||||||
|
|
||||||
|
sudo modprobe vhost_vsock
|
||||||
|
sudo chmod a+rw /dev/vhost-vsock
|
||||||
|
```
|
||||||
|
* Start the ***vwifi-server*** :
|
||||||
|
```bash
|
||||||
|
vwifi-server
|
||||||
|
```
|
||||||
|
|
||||||
|
* Hypervisor
|
||||||
|
* QEmu : add the option : `-device vhost-vsock-pci,id=vwifi0,guest-cid=NUM` with NUM an identifier greater than 2
|
||||||
|
* GNS3 (>= 2.2) : QEmu : add the option : `-device vhost-vsock-pci,id=vwifi0,guest-cid=%guest-cid%`
|
||||||
|
|
||||||
|
### Each Guest
|
||||||
|
|
||||||
|
* Load the necessary module mac80211_hwsim with 0 radios :
|
||||||
|
```bash
|
||||||
|
sudo modprobe mac80211_hwsim radios=0
|
||||||
|
```
|
||||||
|
|
||||||
|
* Create the wlan interfaces (on this example, 2 interfaces) :
|
||||||
|
* Without parameters, the MAC address is preset with the default value "74:F8:F6", and the 4th byte is randomized
|
||||||
|
* ***vwifi-client*** can do the same with the parameters "--number" and "--mac"
|
||||||
|
```bash
|
||||||
|
sudo vwifi-add-interfaces 2 0a:0b:0c:03:02
|
||||||
|
```
|
||||||
|
|
||||||
|
* Connect all these wlan interfaces to the ***vwifi-server*** :
|
||||||
|
```bash
|
||||||
|
sudo vwifi-client
|
||||||
|
```
|
||||||
|
|
||||||
|
* ***vwifi-client*** displays the CID of the VM in the Hypervisor. It is used by ***vwifi-server*** to identify this guest.
|
||||||
|
|
||||||
|
## Method 2 : With TCP
|
||||||
|
|
||||||
|
* ***vwifi-server*** and ***vwifi-client*** must be connected to a different IP network than that of the wifi (for example : 172.16.0.0/16)
|
||||||
|
|
||||||
|
### Host
|
||||||
|
|
||||||
|
* Start the ***vwifi-server*** :
|
||||||
|
|
||||||
|
```bash
|
||||||
|
vwifi-server
|
||||||
|
```
|
||||||
|
|
||||||
|
* We will suppose that the Host have the IP address : 172.16.0.1
|
||||||
|
|
||||||
|
### Each Guest
|
||||||
|
|
||||||
|
* Load the necessary module mac80211_hwsim with 0 radios :
|
||||||
|
```bash
|
||||||
|
sudo modprobe mac80211_hwsim radios=0
|
||||||
|
```
|
||||||
|
|
||||||
|
* Create the wlan interfaces (on this example, 2 interfaces) :
|
||||||
|
* Without parameters, the MAC address is preset with the default value "74:F8:F6", and the 4th byte is randomized
|
||||||
|
* ***vwifi-client*** can do the same with the parameters "--number" and "--mac"
|
||||||
|
```bash
|
||||||
|
sudo vwifi-add-interfaces 2 0a:0b:0c:03:02
|
||||||
|
```
|
||||||
|
|
||||||
|
* Connect all these wlan interfaces to the ***vwifi-server*** :
|
||||||
|
```bash
|
||||||
|
sudo vwifi-client 172.16.0.1
|
||||||
|
```
|
||||||
|
|
||||||
|
* ***vwifi-client*** displays an ID which is an hashsum of the IP. It is used by ***vwifi-server*** to identify this guest.
|
||||||
|
|
||||||
|
# Capture packets from Host
|
||||||
|
|
||||||
|
## Configure the Spy
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo modprobe mac80211_hwsim radios=0
|
||||||
|
sudo vwifi-client -s -n 1
|
||||||
|
```
|
||||||
|
|
||||||
|
## Capture
|
||||||
|
|
||||||
|
* Configure wlan0 to monitor mode :
|
||||||
|
```bash
|
||||||
|
sudo ip link set wlan0 down
|
||||||
|
sudo iw wlan0 set monitor control
|
||||||
|
sudo ip link set wlan0 up
|
||||||
|
```
|
||||||
|
|
||||||
|
### With tcpdump
|
||||||
|
|
||||||
|
* Capture from wlan0 :
|
||||||
|
```bash
|
||||||
|
sudo tcpdump -n -i wlan0
|
||||||
|
```
|
||||||
|
|
||||||
|
### With wireshark
|
||||||
|
|
||||||
|
* Start Wireshark and capture from wlan0 :
|
||||||
|
```bash
|
||||||
|
sudo wireshark
|
||||||
|
```
|
||||||
|
|
||||||
|
# Control
|
||||||
|
|
||||||
|
## Host
|
||||||
|
|
||||||
|
* Show the list of connected guest (display : cid and coordinate x, y z) :
|
||||||
|
```bash
|
||||||
|
vwifi-ctrl ls
|
||||||
|
```
|
||||||
|
|
||||||
|
* Set the new coordinate (11, 12, 13) of the guest with the cid 10 :
|
||||||
|
```bash
|
||||||
|
vwifi-ctrl set 10 11 12 13
|
||||||
|
```
|
||||||
|
|
||||||
|
* Set the name "AP" of the guest with the cid 10 :
|
||||||
|
```bash
|
||||||
|
vwifi-ctrl setname 10 AP
|
||||||
|
```
|
||||||
|
|
||||||
|
* Enable the lost of packets :
|
||||||
|
```bash
|
||||||
|
vwifi-ctrl loss yes
|
||||||
|
```
|
||||||
|
|
||||||
|
* Disable the lost of packets :
|
||||||
|
```bash
|
||||||
|
vwifi-ctrl loss no
|
||||||
|
```
|
||||||
|
|
||||||
|
* Display the config of ***vwifi-server*** :
|
||||||
|
```bash
|
||||||
|
vwifi-ctrl status
|
||||||
|
```
|
||||||
|
|
||||||
|
* Display the distance in meters between the guest with the cid 10 and the guest with the cid 20 :
|
||||||
|
```bash
|
||||||
|
vwifi-ctrl distance 10 20
|
||||||
|
```
|
||||||
|
|
||||||
|
* Set the scale of the distances between the clients to 0.005
|
||||||
|
```bash
|
||||||
|
vwifi-ctrl scale 0.005
|
||||||
|
```
|
||||||
|
|
||||||
|
# Examples of commands to test Wifi
|
||||||
|
|
||||||
|
## Test 1 : WPA
|
||||||
|
|
||||||
|
### Packages needed on the guests for this test
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo apt install hostapd wpasupplicant
|
||||||
|
```
|
||||||
|
|
||||||
|
### Guests
|
||||||
|
|
||||||
|
* Guest Wifi 1 :
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo ip a a 10.0.0.1/8 dev wlan0
|
||||||
|
|
||||||
|
sudo hostapd tests/hostapd_wpa.conf
|
||||||
|
```
|
||||||
|
|
||||||
|
* Guest Wifi 2 :
|
||||||
|
```bash
|
||||||
|
sudo wpa_supplicant -Dnl80211 -iwlan0 -c tests/wpa_supplicant.conf
|
||||||
|
|
||||||
|
sudo ip a a 10.0.0.2/8 dev wlan0
|
||||||
|
ping 10.0.0.1
|
||||||
|
```
|
||||||
|
|
||||||
|
* Guest Wifi 3 :
|
||||||
|
```bash
|
||||||
|
sudo wpa_supplicant -Dnl80211 -iwlan0 -c tests/wpa_supplicant.conf
|
||||||
|
|
||||||
|
sudo ip a a 10.0.0.3/8 dev wlan0
|
||||||
|
ping 10.0.0.2
|
||||||
|
```
|
||||||
|
|
||||||
|
## Test 2 : Open
|
||||||
|
|
||||||
|
### Packages needed on the guests for this test
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo apt install hostapd iw tcpdump
|
||||||
|
```
|
||||||
|
|
||||||
|
### Guests
|
||||||
|
|
||||||
|
* Guest Wifi 1 :
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo ip a a 10.0.0.1/8 dev wlan0
|
||||||
|
|
||||||
|
sudo hostapd tests/hostapd_open.conf
|
||||||
|
```
|
||||||
|
|
||||||
|
* Guest Wifi 2 :
|
||||||
|
```bash
|
||||||
|
sudo ip link set up wlan0
|
||||||
|
sudo iw dev wlan0 connect mac80211_open
|
||||||
|
|
||||||
|
sudo ip a a 10.0.0.2/8 dev wlan0
|
||||||
|
ping 10.0.0.1
|
||||||
|
```
|
||||||
|
|
||||||
|
* Guest Wifi 3 :
|
||||||
|
```bash
|
||||||
|
sudo ip link set up wlan0
|
||||||
|
sudo tcpdump -n -e -I -i wlan0 -w /hosthome/projects/vwifi_capture_wlan0.pcap
|
||||||
|
```
|
||||||
|
|
||||||
|
### Host
|
||||||
|
|
||||||
|
```bash
|
||||||
|
tail -f -c +0b /home/user/projects/vwifi_capture_wlan0.pcap | wireshark -k -i -
|
||||||
|
```
|
||||||
|
|
||||||
|
## Test 3 : Ad-Hoc
|
||||||
|
|
||||||
|
### Packages needed on the guests for this test
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo apt install iw
|
||||||
|
```
|
||||||
|
|
||||||
|
### Guests
|
||||||
|
|
||||||
|
* Guest Wifi 1 :
|
||||||
|
```bash
|
||||||
|
sudo ip link set up wlan0
|
||||||
|
sudo iw wlan0 set type ibss
|
||||||
|
sudo iw wlan0 ibss join MYNETWORK 2412 # frequency 2412 is channel 1
|
||||||
|
|
||||||
|
sudo ip a a 10.0.0.1/8 dev wlan0
|
||||||
|
```
|
||||||
|
|
||||||
|
* Guest Wifi 2 :
|
||||||
|
```bash
|
||||||
|
sudo ip link set up wlan0
|
||||||
|
sudo iw wlan0 set type ibss
|
||||||
|
sudo iw wlan0 ibss join MYNETWORK 2412 # frequency 2412 is channel 1
|
||||||
|
|
||||||
|
sudo ip a a 10.0.0.2/8 dev wlan0
|
||||||
|
ping 10.0.0.1
|
||||||
|
```
|
||||||
|
|
||||||
|
## Test 4 : WEP
|
||||||
|
|
||||||
|
### Packages needed on the guests for this test
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo apt install hostapd
|
||||||
|
```
|
||||||
|
|
||||||
|
### Guests
|
||||||
|
|
||||||
|
* Guest Wifi 1 :
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo ip a a 10.0.0.1/8 dev wlan0
|
||||||
|
|
||||||
|
sudo hostapd tests/hostapd_wep.conf
|
||||||
|
```
|
||||||
|
|
||||||
|
* Guest Wifi 2 :
|
||||||
|
```bash
|
||||||
|
cat << EOF | sudo tee -a /etc/network/interfaces > /dev/null
|
||||||
|
|
||||||
|
iface wlan0 inet static
|
||||||
|
wireless-essid AP_WEP
|
||||||
|
wireless-key s:12345
|
||||||
|
address 10.0.0.2
|
||||||
|
netmask 255.255.255.0
|
||||||
|
|
||||||
|
EOF
|
||||||
|
sudo ifup wlan0
|
||||||
|
|
||||||
|
ping 10.0.0.1
|
||||||
|
```
|
||||||
|
|
||||||
|
# Others Tools
|
||||||
|
|
||||||
|
* start-vwifi-client.sh : do all the commands necessary to start ***vwifi-client*** on a Guest
|
||||||
|
* fast-vwifi-update.sh : set with ***vwifi-ctrl*** the coordinates of each VMs which has the option `guest-cid=`, found in the open project of GNS3
|
||||||
|
* client.sh : configure the client wifi with Open or WPA
|
||||||
|
* Makefile.dependency.sh : generate automatically the file "Makefile.in", include in "Makefile", which contains dependencies for "make"
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 13 KiB |
@@ -0,0 +1,152 @@
|
|||||||
|
/*
|
||||||
|
From : https://android.googlesource.com/device/generic/goldfish/+/refs/heads/master/wifi/mac80211_create_radios/main.cpp
|
||||||
|
Licence http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <netlink/genl/ctrl.h>
|
||||||
|
#include <netlink/genl/genl.h>
|
||||||
|
#include <netlink/netlink.h>
|
||||||
|
#include <net/ethernet.h>
|
||||||
|
|
||||||
|
#include <climits>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <unistd.h> // getuid
|
||||||
|
|
||||||
|
#include "addinterfaces.h"
|
||||||
|
#include "config_hwsim.h"
|
||||||
|
|
||||||
|
const char* nlErrStr(const int e)
|
||||||
|
{
|
||||||
|
return (e < 0) ? nl_geterror(e) : "";
|
||||||
|
}
|
||||||
|
|
||||||
|
#define RETURN(R) return (R);
|
||||||
|
|
||||||
|
#define RETURN_ERROR(C, R) \
|
||||||
|
do { \
|
||||||
|
fprintf(stderr,"%s:%d '%s' failed\n", __func__, __LINE__, C); \
|
||||||
|
return (R); \
|
||||||
|
} while (false);
|
||||||
|
|
||||||
|
#define RETURN_NL_ERROR(C, NLR, R) \
|
||||||
|
do { \
|
||||||
|
fprintf(stderr,"%s:%d '%s' failed with '%s'\n", __func__, __LINE__, C, nlErrStr((NLR))); \
|
||||||
|
return (R); \
|
||||||
|
} while (false);
|
||||||
|
|
||||||
|
struct nl_sock_deleter
|
||||||
|
{
|
||||||
|
void operator()(struct nl_sock* x) const
|
||||||
|
{
|
||||||
|
nl_socket_free(x);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct nl_msg_deleter
|
||||||
|
{
|
||||||
|
void operator()(struct nl_msg* x) const
|
||||||
|
{
|
||||||
|
nlmsg_free(x);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
int ParseAddress(const char* str, TByte addr[ETH_ALEN])
|
||||||
|
{
|
||||||
|
return sscanf(str, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx",
|
||||||
|
&addr[0], &addr[1], &addr[2],&addr[3], &addr[4], &addr[5]);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<struct nl_msg, nl_msg_deleter> CreateNlMessage(
|
||||||
|
const int family,
|
||||||
|
const int cmd)
|
||||||
|
{
|
||||||
|
std::unique_ptr<struct nl_msg, nl_msg_deleter> msg(nlmsg_alloc());
|
||||||
|
if (!msg)
|
||||||
|
{
|
||||||
|
RETURN_ERROR("nlmsg_alloc", nullptr);
|
||||||
|
}
|
||||||
|
void* user = genlmsg_put(msg.get(), NL_AUTO_PORT, NL_AUTO_SEQ, family, 0,
|
||||||
|
NLM_F_REQUEST, cmd, VERSION_NR);
|
||||||
|
if (!user)
|
||||||
|
{
|
||||||
|
RETURN_ERROR("genlmsg_put", nullptr);
|
||||||
|
}
|
||||||
|
RETURN(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<struct nl_msg, nl_msg_deleter>
|
||||||
|
BuildCreateRadioMessage(const int family, const TByte mac[ETH_ALEN])
|
||||||
|
{
|
||||||
|
std::unique_ptr<struct nl_msg, nl_msg_deleter> msg =
|
||||||
|
CreateNlMessage(family, HWSIM_CMD_NEW_RADIO);
|
||||||
|
if (!msg)
|
||||||
|
{
|
||||||
|
RETURN(nullptr);
|
||||||
|
}
|
||||||
|
int ret;
|
||||||
|
ret = nla_put(msg.get(), HWSIM_ATTR_PERM_ADDR, ETH_ALEN, mac);
|
||||||
|
if (ret)
|
||||||
|
{
|
||||||
|
RETURN_NL_ERROR("nla_put(HWSIM_ATTR_PERM_ADDR)", ret, nullptr);
|
||||||
|
}
|
||||||
|
ret = nla_put_flag(msg.get(), HWSIM_ATTR_SUPPORT_P2P_DEVICE);
|
||||||
|
if (ret)
|
||||||
|
{
|
||||||
|
RETURN_NL_ERROR("nla_put(HWSIM_ATTR_SUPPORT_P2P_DEVICE)", ret, nullptr);
|
||||||
|
}
|
||||||
|
RETURN(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
int CreateRadios(struct nl_sock* socket, const int netlinkFamily,
|
||||||
|
const int nRadios, TByte* mac)
|
||||||
|
{
|
||||||
|
for (int idx = 0; idx < nRadios; ++idx)
|
||||||
|
{
|
||||||
|
if( nRadios != 1 ) // if i set only 1 interface, the mac address is not modified : the user can choose all the mac address
|
||||||
|
mac[5] = idx;
|
||||||
|
std::unique_ptr<struct nl_msg, nl_msg_deleter> msg =
|
||||||
|
BuildCreateRadioMessage(netlinkFamily, mac);
|
||||||
|
if (msg)
|
||||||
|
{
|
||||||
|
int ret = nl_send_auto(socket, msg.get());
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
RETURN_NL_ERROR("nl_send_auto", ret, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
RETURN(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
RETURN(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int ManageRadios(const int nRadios, TByte* macPrefix)
|
||||||
|
{
|
||||||
|
std::unique_ptr<struct nl_sock, nl_sock_deleter> socket(nl_socket_alloc());
|
||||||
|
if (!socket)
|
||||||
|
{
|
||||||
|
RETURN_ERROR("nl_socket_alloc", 1);
|
||||||
|
}
|
||||||
|
int ret;
|
||||||
|
ret = genl_connect(socket.get());
|
||||||
|
if (ret)
|
||||||
|
{
|
||||||
|
RETURN_NL_ERROR("genl_connect", ret, 1);
|
||||||
|
}
|
||||||
|
const int netlinkFamily = genl_ctrl_resolve(socket.get(), KERNEL_HWSIM_FAMILY_NAME);
|
||||||
|
if (netlinkFamily < 0)
|
||||||
|
{
|
||||||
|
fprintf(stderr,"The kernel module 'mac80211_hwsim' is not loaded\n");
|
||||||
|
return 2;
|
||||||
|
//RETURN_NL_ERROR("genl_ctrl_resolve", ret, 1);
|
||||||
|
}
|
||||||
|
ret = CreateRadios(socket.get(), netlinkFamily, nRadios, macPrefix);
|
||||||
|
if (ret)
|
||||||
|
{
|
||||||
|
RETURN(ret);
|
||||||
|
}
|
||||||
|
RETURN(0);
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
#ifndef _ADDINTERFACE_H_
|
||||||
|
#define _ADDINTERFACE_H_
|
||||||
|
|
||||||
|
#include "types.h"
|
||||||
|
|
||||||
|
int ParseAddress(const char* str, TByte addr[ETH_ALEN]);
|
||||||
|
|
||||||
|
int ManageRadios(const int nRadios, TByte* macPrefix);
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,80 @@
|
|||||||
|
#include "ccoordinate.h"
|
||||||
|
|
||||||
|
#include <math.h> // sqrt
|
||||||
|
|
||||||
|
TScale Scale=1;
|
||||||
|
|
||||||
|
CCoordinate::CCoordinate(TValue x, TValue y, TValue z)
|
||||||
|
{
|
||||||
|
Set(x, y, z);
|
||||||
|
}
|
||||||
|
|
||||||
|
CCoordinate::CCoordinate()
|
||||||
|
{
|
||||||
|
X=0;
|
||||||
|
Y=0;
|
||||||
|
Z=0;
|
||||||
|
}
|
||||||
|
|
||||||
|
CCoordinate::CCoordinate(const CCoordinate& coo)
|
||||||
|
{
|
||||||
|
*this=coo;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CCoordinate::SetX(TValue x)
|
||||||
|
{
|
||||||
|
X=x;
|
||||||
|
}
|
||||||
|
void CCoordinate::SetY(TValue y)
|
||||||
|
{
|
||||||
|
Y=y;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CCoordinate::SetZ(TValue z)
|
||||||
|
{
|
||||||
|
Z=z;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CCoordinate::Set(TValue x, TValue y)
|
||||||
|
{
|
||||||
|
SetX(x);
|
||||||
|
SetY(y);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CCoordinate::Set(TValue x, TValue y, TValue z)
|
||||||
|
{
|
||||||
|
Set(x, y);
|
||||||
|
SetZ(z);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CCoordinate::Set(CCoordinate coo)
|
||||||
|
{
|
||||||
|
Set(coo.X,coo.Y,coo.Z);
|
||||||
|
}
|
||||||
|
|
||||||
|
TDistance CCoordinate::DistanceWith(TValue x, TValue y, TValue z)
|
||||||
|
{
|
||||||
|
return Scale*sqrt( (X-x)*(X-x)+(Y-y)*(Y-y)+(Z-z)*(Z-z) );
|
||||||
|
}
|
||||||
|
|
||||||
|
TDistance CCoordinate::DistanceWith(CCoordinate coo)
|
||||||
|
{
|
||||||
|
return DistanceWith(coo.X, coo.Y, coo.Z);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CCoordinate::Display(ostream& os) const
|
||||||
|
{
|
||||||
|
os << X << " " << Y << " " << Z;
|
||||||
|
}
|
||||||
|
|
||||||
|
ostream& operator<<(ostream& os, const CCoordinate& coo)
|
||||||
|
{
|
||||||
|
coo.Display(os) ;
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
|
||||||
|
CCoordinate& CCoordinate::operator=(const CCoordinate& coo)
|
||||||
|
{
|
||||||
|
Set(coo.X,coo.Y,coo.Z);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
#ifndef _CCOORDINATE_H_
|
||||||
|
#define _CCOORDINATE_H_
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#include "types.h" // TValue, TDistance
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
extern TScale Scale;
|
||||||
|
|
||||||
|
class CCoordinate
|
||||||
|
{
|
||||||
|
TValue X;
|
||||||
|
TValue Y;
|
||||||
|
TValue Z;
|
||||||
|
|
||||||
|
public :
|
||||||
|
CCoordinate();
|
||||||
|
CCoordinate(TValue x, TValue y, TValue z);
|
||||||
|
CCoordinate(const CCoordinate& coo);
|
||||||
|
|
||||||
|
void SetX(TValue x);
|
||||||
|
void SetY(TValue y);
|
||||||
|
void SetZ(TValue z);
|
||||||
|
|
||||||
|
void Set(TValue x, TValue y);
|
||||||
|
void Set(TValue x, TValue y, TValue z);
|
||||||
|
|
||||||
|
void Set(CCoordinate coo);
|
||||||
|
|
||||||
|
TDistance DistanceWith(TValue x, TValue y, TValue z);
|
||||||
|
TDistance DistanceWith(CCoordinate coo);
|
||||||
|
|
||||||
|
void Display(ostream& os) const;
|
||||||
|
friend ostream& operator<<(ostream& os, const CCoordinate& coo);
|
||||||
|
|
||||||
|
CCoordinate& operator=(const CCoordinate& coo);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,455 @@
|
|||||||
|
#include <cstring> // strcpy
|
||||||
|
|
||||||
|
#include "cctrlserver.h"
|
||||||
|
#include "config.h" // MAX_SIZE_NAME
|
||||||
|
|
||||||
|
|
||||||
|
CCTRLServer::CCTRLServer(CWifiServer* wifiServerVTCP, CWifiServer* wifiServerITCP, CWifiServer* wifiServerSPY, CSelect* scheduler) : CSocketServer()
|
||||||
|
{
|
||||||
|
WifiServerVTCP=wifiServerVTCP;
|
||||||
|
WifiServerITCP=wifiServerITCP;
|
||||||
|
WifiServerSPY=wifiServerSPY;
|
||||||
|
Scheduler=scheduler;
|
||||||
|
}
|
||||||
|
|
||||||
|
CCTRLServer::~CCTRLServer()
|
||||||
|
{
|
||||||
|
// Close any open connections
|
||||||
|
CloseAllClient();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CCTRLServer::_Listen(TDescriptor& master, TPort port)
|
||||||
|
{
|
||||||
|
return CSocketServerFunctionITCP::_Listen(master, port);
|
||||||
|
}
|
||||||
|
|
||||||
|
TDescriptor CCTRLServer::_Accept(TDescriptor master, TCID& cid)
|
||||||
|
{
|
||||||
|
return CSocketServerFunctionITCP::_Accept(master, cid);
|
||||||
|
}
|
||||||
|
|
||||||
|
ssize_t CCTRLServer::Read(char* data, ssize_t sizeOfData)
|
||||||
|
{
|
||||||
|
return CSocket::Read(GetSocketClient(0),data, sizeOfData);
|
||||||
|
}
|
||||||
|
|
||||||
|
ssize_t CCTRLServer::Send(char* data, ssize_t sizeOfData)
|
||||||
|
{
|
||||||
|
return CSocket::Send(GetSocketClient(0),data, sizeOfData);
|
||||||
|
}
|
||||||
|
|
||||||
|
TOrder CCTRLServer::GetOrder()
|
||||||
|
{
|
||||||
|
TOrder order;
|
||||||
|
|
||||||
|
if( GetNumberClient() != 1 )
|
||||||
|
return TORDER_NO;
|
||||||
|
|
||||||
|
if( Read(reinterpret_cast<char*>(&order), sizeof(TOrder)) == SOCKET_ERROR )
|
||||||
|
return TORDER_NO;
|
||||||
|
|
||||||
|
return order;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CCTRLServer::SendCInfoWifi(CInfoWifi* infoWifi)
|
||||||
|
{
|
||||||
|
TCID cid=infoWifi->GetCid();
|
||||||
|
if( Send(reinterpret_cast<char*>(&cid),sizeof(cid)) == SOCKET_ERROR )
|
||||||
|
{
|
||||||
|
cerr<<"Error : SendCInfoWifi : cid : "<<infoWifi->GetCid()<<endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
CCoordinate coo=(*infoWifi);
|
||||||
|
if( Send(reinterpret_cast<char*>(&coo),sizeof(coo)) == SOCKET_ERROR )
|
||||||
|
{
|
||||||
|
cerr<<"Error : SendCInfoWifi : CCoordinate : "<<infoWifi->GetCid()<<endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sizeName=infoWifi->GetSizeName();
|
||||||
|
if( Send(reinterpret_cast<char*>(&sizeName),sizeof(sizeName)) == SOCKET_ERROR )
|
||||||
|
{
|
||||||
|
cerr<<"Error : SendCInfoWifi : size of name : "<<infoWifi->GetCid()<<endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if( sizeName > 0 )
|
||||||
|
{
|
||||||
|
char name[MAX_SIZE_NAME+1]; // +1 : \0
|
||||||
|
strcpy(name,(infoWifi->GetName()).c_str());
|
||||||
|
if( Send(name,sizeName+1) == SOCKET_ERROR ) // +1 : \0
|
||||||
|
{
|
||||||
|
cerr<<"Error : SendCInfoWifi : name : "<<infoWifi->GetCid()<<endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CCTRLServer::SendList()
|
||||||
|
{
|
||||||
|
// because the same List is shared by WifiServerVTCP and WifiServerITCP
|
||||||
|
|
||||||
|
CInfoWifi* infoWifi;
|
||||||
|
|
||||||
|
// Spies :
|
||||||
|
|
||||||
|
TIndex number=WifiServerSPY->GetNumberClient();
|
||||||
|
|
||||||
|
if( Send(reinterpret_cast<char*>(&number), sizeof(number)) == SOCKET_ERROR )
|
||||||
|
return;
|
||||||
|
|
||||||
|
for(TIndex i=0; i<number;i++)
|
||||||
|
{
|
||||||
|
if( WifiServerSPY->IsEnable(i) )
|
||||||
|
{
|
||||||
|
infoWifi=WifiServerSPY->GetReferenceOnInfoWifiByIndex(i);
|
||||||
|
if( ! SendCInfoWifi(infoWifi) )
|
||||||
|
{
|
||||||
|
cerr<<"Error : SendList : Send : Spies : CInfoWifi : "<<*infoWifi<<endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clients
|
||||||
|
|
||||||
|
number=WifiServerITCP->GetNumberClient();
|
||||||
|
|
||||||
|
if( Send(reinterpret_cast<char*>(&number), sizeof(number)) == SOCKET_ERROR )
|
||||||
|
return;
|
||||||
|
|
||||||
|
for(TIndex i=0; i<number;i++)
|
||||||
|
{
|
||||||
|
if( WifiServerITCP->IsEnable(i) )
|
||||||
|
{
|
||||||
|
infoWifi=WifiServerITCP->GetReferenceOnInfoWifiByIndex(i);
|
||||||
|
if( ! SendCInfoWifi(infoWifi) )
|
||||||
|
{
|
||||||
|
cerr<<"Error : SendList : Send : Clients : CInfoWifi : "<<*infoWifi<<endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CCTRLServer::ChangeCoordinate()
|
||||||
|
{
|
||||||
|
TCID cid;
|
||||||
|
|
||||||
|
if( Read(reinterpret_cast<char*>(&cid), sizeof(TCID)) == SOCKET_ERROR )
|
||||||
|
return;
|
||||||
|
|
||||||
|
CCoordinate coo;
|
||||||
|
|
||||||
|
if( Read(reinterpret_cast<char*>(&coo), sizeof(coo)) == SOCKET_ERROR )
|
||||||
|
return;
|
||||||
|
|
||||||
|
if( cid < TCID_GUEST_MIN )
|
||||||
|
return;
|
||||||
|
|
||||||
|
// because the same List is shared by WifiServerVTCP and WifiServerITCP
|
||||||
|
|
||||||
|
CInfoWifi* infoWifi;
|
||||||
|
|
||||||
|
infoWifi=WifiServerITCP->GetReferenceOnInfoWifiByCID(cid);
|
||||||
|
if( infoWifi != NULL )
|
||||||
|
{
|
||||||
|
infoWifi->Set(coo);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
infoWifi=WifiServerITCP->GetReferenceOnInfoWifiDeconnectedByCID(cid);
|
||||||
|
if( infoWifi != NULL )
|
||||||
|
{
|
||||||
|
infoWifi->Set(coo);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
CInfoWifi infoNewWifi(cid,coo);
|
||||||
|
WifiServerITCP->AddInfoWifiDeconnected(infoNewWifi);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CCTRLServer::SetName()
|
||||||
|
{
|
||||||
|
TCID cid;
|
||||||
|
|
||||||
|
if( Read(reinterpret_cast<char*>(&cid), sizeof(TCID)) == SOCKET_ERROR )
|
||||||
|
return;
|
||||||
|
|
||||||
|
int sizeName;
|
||||||
|
char strName[MAX_SIZE_NAME+1]; // +1 : \0
|
||||||
|
|
||||||
|
if( Read(reinterpret_cast<char*>(&sizeName), sizeof(sizeName)) == SOCKET_ERROR )
|
||||||
|
return;
|
||||||
|
|
||||||
|
if( Read(reinterpret_cast<char*>(strName), sizeof(strName)) == SOCKET_ERROR )
|
||||||
|
return;
|
||||||
|
|
||||||
|
if( cid < TCID_GUEST_MIN )
|
||||||
|
return;
|
||||||
|
|
||||||
|
// because the same List is shared by WifiServerVTCP and WifiServerITCP
|
||||||
|
|
||||||
|
string name(strName);
|
||||||
|
|
||||||
|
CInfoWifi* infoWifi;
|
||||||
|
|
||||||
|
infoWifi=WifiServerITCP->GetReferenceOnInfoWifiByCID(cid);
|
||||||
|
if( infoWifi != NULL )
|
||||||
|
{
|
||||||
|
infoWifi->SetName(name);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
infoWifi=WifiServerITCP->GetReferenceOnInfoWifiDeconnectedByCID(cid);
|
||||||
|
if( infoWifi != NULL )
|
||||||
|
{
|
||||||
|
infoWifi->SetName(name);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
infoWifi=WifiServerSPY->GetReferenceOnInfoWifiByCID(cid);
|
||||||
|
if( infoWifi != NULL )
|
||||||
|
{
|
||||||
|
infoWifi->SetName(name);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CCTRLServer::ChangePacketLoss()
|
||||||
|
{
|
||||||
|
int value;
|
||||||
|
|
||||||
|
if( Read(reinterpret_cast<char*>(&value), sizeof(value)) == SOCKET_ERROR )
|
||||||
|
return;
|
||||||
|
|
||||||
|
if ( value )
|
||||||
|
{
|
||||||
|
#ifdef _DEBUG
|
||||||
|
cout<<"Packet loss : Enable"<<endl;
|
||||||
|
#endif
|
||||||
|
CanLostPackets=true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
#ifdef _DEBUG
|
||||||
|
cout<<"Packet loss : Disable"<<endl;
|
||||||
|
#endif
|
||||||
|
CanLostPackets=false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CCTRLServer::SendStatus()
|
||||||
|
{
|
||||||
|
if( Send(reinterpret_cast<char*>(&CanLostPackets),sizeof(CanLostPackets)) == SOCKET_ERROR )
|
||||||
|
{
|
||||||
|
cerr<<"Error : SendStatus : Send : PacketLoss"<<endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( Send(reinterpret_cast<char*>(&Scale),sizeof(Scale)) == SOCKET_ERROR )
|
||||||
|
{
|
||||||
|
cerr<<"Error : SendStatus : Send : Scale"<<endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef ENABLE_VHOST
|
||||||
|
// VHOST
|
||||||
|
if( Send(reinterpret_cast<char*>(&WifiServerVTCP->Port),sizeof(WifiServerVTCP->Port)) == SOCKET_ERROR )
|
||||||
|
{
|
||||||
|
cerr<<"Error : SendStatus : Send : Port VHOST"<<endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// INET
|
||||||
|
|
||||||
|
if( Send(reinterpret_cast<char*>(&WifiServerITCP->Port),sizeof(WifiServerITCP->Port)) == SOCKET_ERROR )
|
||||||
|
{
|
||||||
|
cerr<<"Error : SendStatus : Send : Port INET"<<endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// SizeOfDisconnected
|
||||||
|
// be careful : the same List is shared by WifiServerVTCP and WifiServerITCP
|
||||||
|
|
||||||
|
if( Send(reinterpret_cast<char*>(&WifiServerITCP->MaxClientDeconnected),sizeof(WifiServerITCP->MaxClientDeconnected)) == SOCKET_ERROR )
|
||||||
|
{
|
||||||
|
cerr<<"Error : SendStatus : Send : Size MaxClientDeconnected"<<endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// SPY
|
||||||
|
|
||||||
|
bool spyIsConnected=( WifiServerSPY->GetNumberClient() > 0 );
|
||||||
|
if( Send(reinterpret_cast<char*>(&spyIsConnected),sizeof(spyIsConnected)) == SOCKET_ERROR )
|
||||||
|
{
|
||||||
|
cerr<<"Error : SendStatus : Send : spyIsConnected"<<endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CCTRLServer::SendShow()
|
||||||
|
{
|
||||||
|
if( Send(reinterpret_cast<char*>(&CanLostPackets),sizeof(CanLostPackets)) == SOCKET_ERROR )
|
||||||
|
{
|
||||||
|
cerr<<"Error : SendShow : Send : PacketLoss"<<endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( Send(reinterpret_cast<char*>(&Scale),sizeof(Scale)) == SOCKET_ERROR )
|
||||||
|
{
|
||||||
|
cerr<<"Error : SendShow : Send : Scale"<<endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool spyIsConnected=( WifiServerSPY->GetNumberClient() > 0 );
|
||||||
|
if( Send(reinterpret_cast<char*>(&spyIsConnected),sizeof(spyIsConnected)) == SOCKET_ERROR )
|
||||||
|
{
|
||||||
|
cerr<<"Error : SendShow : Send : spyIsConnected"<<endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CCTRLServer::SendDistance()
|
||||||
|
{
|
||||||
|
TCID cid1, cid2;
|
||||||
|
|
||||||
|
if( Read(reinterpret_cast<char*>(&cid1), sizeof(TCID)) == SOCKET_ERROR )
|
||||||
|
return;
|
||||||
|
|
||||||
|
if( Read(reinterpret_cast<char*>(&cid2), sizeof(TCID)) == SOCKET_ERROR )
|
||||||
|
return;
|
||||||
|
|
||||||
|
int codeError;
|
||||||
|
|
||||||
|
// because the same List is shared by WifiServerVTCP and WifiServerITCP
|
||||||
|
|
||||||
|
CCoordinate* coo1;
|
||||||
|
|
||||||
|
coo1=WifiServerITCP->GetReferenceOnInfoWifiByCID(cid1);
|
||||||
|
if( coo1 == NULL )
|
||||||
|
{
|
||||||
|
coo1=WifiServerITCP->GetReferenceOnInfoWifiDeconnectedByCID(cid1);
|
||||||
|
if( coo1 == NULL )
|
||||||
|
{
|
||||||
|
codeError=-1;
|
||||||
|
if( Send(reinterpret_cast<char*>(&codeError),sizeof(codeError)) == SOCKET_ERROR )
|
||||||
|
cerr<<"Error : SendDistance : Send : unknown cid1"<<endl;
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CCoordinate* coo2;
|
||||||
|
|
||||||
|
coo2=WifiServerITCP->GetReferenceOnInfoWifiByCID(cid2);
|
||||||
|
if( coo2 == NULL )
|
||||||
|
{
|
||||||
|
coo2=WifiServerITCP->GetReferenceOnInfoWifiDeconnectedByCID(cid2);
|
||||||
|
if( coo2 == NULL )
|
||||||
|
{
|
||||||
|
codeError=-2;
|
||||||
|
if( Send(reinterpret_cast<char*>(&codeError),sizeof(codeError)) == SOCKET_ERROR )
|
||||||
|
cerr<<"Error : SendDistance : Send : unknown cid2"<<endl;
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
codeError=0;
|
||||||
|
if( Send(reinterpret_cast<char*>(&codeError),sizeof(codeError)) == SOCKET_ERROR )
|
||||||
|
{
|
||||||
|
cerr<<"Error : SendDistance : Send : no error"<<endl;
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
|
||||||
|
TDistance distance=coo1->DistanceWith(*coo2);
|
||||||
|
|
||||||
|
if( Send(reinterpret_cast<char*>(&distance),sizeof(distance)) == SOCKET_ERROR )
|
||||||
|
{
|
||||||
|
cerr<<"Error : SendDistance : Send : distance"<<endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CCTRLServer::SetScale()
|
||||||
|
{
|
||||||
|
TScale new_scale;
|
||||||
|
|
||||||
|
if( Read(reinterpret_cast<char*>(&new_scale), sizeof(new_scale)) == SOCKET_ERROR )
|
||||||
|
return;
|
||||||
|
|
||||||
|
Scale=new_scale;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CCTRLServer::CloseAllClient()
|
||||||
|
{
|
||||||
|
// because the same List is shared by WifiServerVTCP and WifiServerITCP
|
||||||
|
|
||||||
|
// Clients :
|
||||||
|
|
||||||
|
// be careful : In the Scheduler, i must delete only the nodes of WifiServer, not the node of the CTRLServer
|
||||||
|
for (TIndex i = 0; i < WifiServerITCP->GetNumberClient(); i++)
|
||||||
|
Scheduler->DelNode((*WifiServerITCP)[i]);
|
||||||
|
|
||||||
|
WifiServerITCP->CloseAllClient();
|
||||||
|
|
||||||
|
// Spies :
|
||||||
|
|
||||||
|
for (TIndex i = 0; i < WifiServerSPY->GetNumberClient(); i++)
|
||||||
|
Scheduler->DelNode((*WifiServerSPY)[i]);
|
||||||
|
|
||||||
|
WifiServerSPY->CloseAllClient();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CCTRLServer::ReceiveOrder()
|
||||||
|
{
|
||||||
|
if ( Accept() == SOCKET_ERROR )
|
||||||
|
return;
|
||||||
|
|
||||||
|
TOrder order=GetOrder();
|
||||||
|
|
||||||
|
switch( order )
|
||||||
|
{
|
||||||
|
case TORDER_NO : break ;
|
||||||
|
|
||||||
|
case TORDER_LIST :
|
||||||
|
SendList();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TORDER_CHANGE_COORDINATE :
|
||||||
|
ChangeCoordinate();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TORDER_SETNAME :
|
||||||
|
SetName();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TORDER_PACKET_LOSS :
|
||||||
|
ChangePacketLoss();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TORDER_STATUS :
|
||||||
|
SendStatus();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TORDER_SHOW :
|
||||||
|
SendShow();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TORDER_DISTANCE_BETWEEN_CID :
|
||||||
|
SendDistance();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TORDER_SET_SCALE :
|
||||||
|
SetScale();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TORDER_CLOSE_ALL_CLIENT :
|
||||||
|
CloseAllClient();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
CloseClient(0);
|
||||||
|
}
|
||||||
@@ -0,0 +1,56 @@
|
|||||||
|
#ifndef _CCTRLSERVER_H_
|
||||||
|
#define _CCTRLSERVER_H_
|
||||||
|
|
||||||
|
#include "cwifiserver.h" // CWifiServer CSocketServer
|
||||||
|
#include "csocketserverfunctionitcp.h" // CSocketServerFunctionITCP
|
||||||
|
#include "cselect.h" // CSelect
|
||||||
|
#include "types.h" // TOrder
|
||||||
|
|
||||||
|
class CCTRLServer : public CSocketServer, public CSocketServerFunctionITCP
|
||||||
|
{
|
||||||
|
CWifiServer* WifiServerVTCP;
|
||||||
|
CWifiServer* WifiServerITCP;
|
||||||
|
CWifiServer* WifiServerSPY;
|
||||||
|
CSelect* Scheduler;
|
||||||
|
|
||||||
|
bool _Listen(TDescriptor& master, TPort port) override;
|
||||||
|
TDescriptor _Accept(TDescriptor master, TCID& cid) override;
|
||||||
|
|
||||||
|
using CSocketServer::Read;
|
||||||
|
ssize_t Read(char* data, ssize_t sizeOfData);
|
||||||
|
|
||||||
|
using CSocketServer::Send;
|
||||||
|
ssize_t Send(char* data, ssize_t sizeOfData);
|
||||||
|
|
||||||
|
TOrder GetOrder();
|
||||||
|
|
||||||
|
bool SendCInfoWifi(CInfoWifi* infoWifi);
|
||||||
|
|
||||||
|
void SendList();
|
||||||
|
|
||||||
|
void ChangeCoordinate();
|
||||||
|
|
||||||
|
void SetName();
|
||||||
|
|
||||||
|
void ChangePacketLoss();
|
||||||
|
|
||||||
|
void SendStatus();
|
||||||
|
|
||||||
|
void SendShow();
|
||||||
|
|
||||||
|
void SendDistance();
|
||||||
|
|
||||||
|
void SetScale();
|
||||||
|
|
||||||
|
void CloseAllClient();
|
||||||
|
|
||||||
|
public :
|
||||||
|
|
||||||
|
CCTRLServer(CWifiServer* wifiServerVTCP, CWifiServer* wifiServerITCP, CWifiServer* wifiServerSPY, CSelect* scheduler);
|
||||||
|
|
||||||
|
virtual ~CCTRLServer();
|
||||||
|
|
||||||
|
void ReceiveOrder();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,62 @@
|
|||||||
|
#include <iostream>
|
||||||
|
#include <string.h> // memcpy
|
||||||
|
|
||||||
|
#include "cdynbuffer.h"
|
||||||
|
|
||||||
|
const int DEFAULT_SIZE_BUFFER=1024;
|
||||||
|
|
||||||
|
CDynBuffer::CDynBuffer()
|
||||||
|
{
|
||||||
|
Buffer = nullptr;
|
||||||
|
Size=0;
|
||||||
|
Allocate(DEFAULT_SIZE_BUFFER,false);
|
||||||
|
}
|
||||||
|
|
||||||
|
CDynBuffer::~CDynBuffer()
|
||||||
|
{
|
||||||
|
if( Buffer != nullptr )
|
||||||
|
{
|
||||||
|
delete Buffer;
|
||||||
|
Buffer=nullptr;
|
||||||
|
Size=0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CDynBuffer::NeededSize(int size, bool keepValues)
|
||||||
|
{
|
||||||
|
if( size <= Size )
|
||||||
|
return;
|
||||||
|
|
||||||
|
Allocate(size,keepValues);
|
||||||
|
}
|
||||||
|
|
||||||
|
char* CDynBuffer::GetBuffer() const
|
||||||
|
{
|
||||||
|
return Buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CDynBuffer::Allocate(int size, bool keepValues)
|
||||||
|
{
|
||||||
|
if( ! keepValues )
|
||||||
|
{
|
||||||
|
if( Buffer != nullptr )
|
||||||
|
delete[] Buffer;
|
||||||
|
|
||||||
|
Buffer = new char [size];
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
char* newBuffer = new char [size];
|
||||||
|
|
||||||
|
if( Buffer != nullptr )
|
||||||
|
{
|
||||||
|
memcpy(newBuffer,Buffer,Size);
|
||||||
|
delete[] Buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
Buffer = newBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
Size=size;
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
#ifndef _CDYNBUFFER_H_
|
||||||
|
#define _CDYNBUFFER_H_
|
||||||
|
|
||||||
|
class CDynBuffer
|
||||||
|
{
|
||||||
|
private :
|
||||||
|
|
||||||
|
char* Buffer;
|
||||||
|
int Size;
|
||||||
|
|
||||||
|
void Allocate(int size, bool keepValues);
|
||||||
|
|
||||||
|
public :
|
||||||
|
|
||||||
|
CDynBuffer();
|
||||||
|
|
||||||
|
~CDynBuffer();
|
||||||
|
|
||||||
|
void NeededSize(int size, bool keepValues);
|
||||||
|
|
||||||
|
char* GetBuffer() const;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
#include <unistd.h> // close
|
||||||
|
#include <assert.h> // assert
|
||||||
|
|
||||||
|
#include "cinfosocket.h"
|
||||||
|
|
||||||
|
CInfoSocket::CInfoSocket()
|
||||||
|
{
|
||||||
|
SetDescriptor(-1);
|
||||||
|
DisableIt();
|
||||||
|
}
|
||||||
|
|
||||||
|
CInfoSocket::CInfoSocket(TDescriptor descriptor)
|
||||||
|
{
|
||||||
|
SetDescriptor(descriptor);
|
||||||
|
EnableIt();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CInfoSocket::SetDescriptor(TDescriptor descriptor)
|
||||||
|
{
|
||||||
|
Descriptor=descriptor;
|
||||||
|
EnableIt();
|
||||||
|
}
|
||||||
|
|
||||||
|
TDescriptor CInfoSocket::GetDescriptor() const
|
||||||
|
{
|
||||||
|
return Descriptor;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CInfoSocket::EnableIt()
|
||||||
|
{
|
||||||
|
assert( Descriptor >= 0 );
|
||||||
|
|
||||||
|
Enable=true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CInfoSocket::DisableIt()
|
||||||
|
{
|
||||||
|
Enable=false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CInfoSocket::IsEnable()
|
||||||
|
{
|
||||||
|
return Enable;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CInfoSocket::Close()
|
||||||
|
{
|
||||||
|
if( IsEnable() )
|
||||||
|
{
|
||||||
|
DisableIt();
|
||||||
|
close(Descriptor);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
#ifndef _CINFOSOCKET_H_
|
||||||
|
#define _CINFOSOCKET_H_
|
||||||
|
|
||||||
|
#include <iostream> // ostream
|
||||||
|
|
||||||
|
#include "types.h" // TDescriptor
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
class CInfoSocket
|
||||||
|
{
|
||||||
|
TDescriptor Descriptor;
|
||||||
|
bool Enable;
|
||||||
|
|
||||||
|
void EnableIt();
|
||||||
|
|
||||||
|
public :
|
||||||
|
|
||||||
|
CInfoSocket();
|
||||||
|
|
||||||
|
explicit CInfoSocket(TDescriptor descriptor);
|
||||||
|
|
||||||
|
void SetDescriptor(TDescriptor descriptor);
|
||||||
|
|
||||||
|
TDescriptor GetDescriptor() const;
|
||||||
|
|
||||||
|
void DisableIt();
|
||||||
|
|
||||||
|
bool IsEnable();
|
||||||
|
|
||||||
|
void Close();
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,63 @@
|
|||||||
|
#include <assert.h> // assert
|
||||||
|
|
||||||
|
#include "config.h" // MAX_SIZE_NAME
|
||||||
|
#include "cinfowifi.h"
|
||||||
|
|
||||||
|
CInfoWifi::CInfoWifi(): CCoordinate()
|
||||||
|
{
|
||||||
|
SetCid(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
CInfoWifi::CInfoWifi(TCID cid, CCoordinate coo) : CCoordinate(coo)
|
||||||
|
{
|
||||||
|
SetCid(cid);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CInfoWifi::SetCid(TCID cid)
|
||||||
|
{
|
||||||
|
// with the empty constructor : cid=0
|
||||||
|
assert( cid==0 || cid >=TCID_GUEST_MIN );
|
||||||
|
Cid=cid;
|
||||||
|
}
|
||||||
|
|
||||||
|
TCID CInfoWifi::GetCid() const
|
||||||
|
{
|
||||||
|
return Cid;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CInfoWifi::SetName(string name)
|
||||||
|
{
|
||||||
|
if( name.size() > MAX_SIZE_NAME )
|
||||||
|
name.resize(MAX_SIZE_NAME);
|
||||||
|
|
||||||
|
Name=name;
|
||||||
|
}
|
||||||
|
|
||||||
|
string CInfoWifi::GetName() const
|
||||||
|
{
|
||||||
|
return Name;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CInfoWifi::GetSizeName() const
|
||||||
|
{
|
||||||
|
return Name.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CInfoWifi::HasName() const
|
||||||
|
{
|
||||||
|
return ! Name.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CInfoWifi::Display(ostream& os) const
|
||||||
|
{
|
||||||
|
os << Cid << " ";
|
||||||
|
if( HasName() )
|
||||||
|
os << "("<<Name<<") ";
|
||||||
|
CCoordinate::Display(os);
|
||||||
|
}
|
||||||
|
|
||||||
|
ostream& operator<<(ostream& os, const CInfoWifi& infowifi)
|
||||||
|
{
|
||||||
|
infowifi.Display(os) ;
|
||||||
|
return os;
|
||||||
|
}
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
#ifndef _CINFOWIFI_H_
|
||||||
|
#define _CINFOWIFI_H_
|
||||||
|
|
||||||
|
#include <iostream> // ostream
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "ccoordinate.h"
|
||||||
|
#include "types.h" // TCID
|
||||||
|
|
||||||
|
const TCID TCID_GUEST_MIN=3;
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
class CInfoWifi : public CCoordinate
|
||||||
|
{
|
||||||
|
TCID Cid;
|
||||||
|
string Name;
|
||||||
|
|
||||||
|
public :
|
||||||
|
|
||||||
|
CInfoWifi();
|
||||||
|
CInfoWifi(TCID cid, CCoordinate coo);
|
||||||
|
|
||||||
|
void SetCid(TCID cid);
|
||||||
|
|
||||||
|
TCID GetCid() const;
|
||||||
|
|
||||||
|
void SetName(string name);
|
||||||
|
string GetName() const;
|
||||||
|
int GetSizeName() const;
|
||||||
|
bool HasName() const;
|
||||||
|
|
||||||
|
void Display(ostream& os) const;
|
||||||
|
|
||||||
|
friend ostream& operator<<(ostream& os, const CInfoWifi& infowifi);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
+1095
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,275 @@
|
|||||||
|
#ifndef _CKERNELWIFI_H_
|
||||||
|
#define _CKERNELWIFI_H_
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <mutex>
|
||||||
|
|
||||||
|
#include "config_hwsim.h"
|
||||||
|
|
||||||
|
#include "cwirelessdevice.h"
|
||||||
|
#include "cwirelessdevicelist.h"
|
||||||
|
#include "cmonwirelessdevice.h"
|
||||||
|
#include "cselect.h"
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
|
#include "cthread.h"
|
||||||
|
#include <condition_variable>
|
||||||
|
|
||||||
|
#include "cdynbuffer.h"
|
||||||
|
|
||||||
|
namespace ckernelwifi{
|
||||||
|
|
||||||
|
class CallFromStaticFunc ;
|
||||||
|
}
|
||||||
|
class CKernelWifi : public intthread::AsyncTask {
|
||||||
|
|
||||||
|
protected :
|
||||||
|
|
||||||
|
pthread_t serverloop_id ;
|
||||||
|
|
||||||
|
CSelect Scheduler;
|
||||||
|
bool _connected_to_server { false };
|
||||||
|
std::mutex _mutex_connected_to_server ;
|
||||||
|
std::condition_variable _cond_connected_to_server ;
|
||||||
|
|
||||||
|
bool _being_initialized { false } ;
|
||||||
|
|
||||||
|
bool _being_started { false } ;
|
||||||
|
std::mutex _being_started_mutex ;
|
||||||
|
|
||||||
|
WirelessDeviceList _list_winterfaces ;
|
||||||
|
|
||||||
|
/** pointer for netlink socket */
|
||||||
|
struct nl_sock * _netlink_socket { nullptr };
|
||||||
|
|
||||||
|
/** pointer for netlink callback function */
|
||||||
|
struct nl_cb * _cb { nullptr };
|
||||||
|
|
||||||
|
/** For the family ID used by hwsim */
|
||||||
|
int m_family_id { 1 };
|
||||||
|
|
||||||
|
intthread::InterruptibleThread hwsimloop_task ;
|
||||||
|
intthread::InterruptibleThread serverloop_task ;
|
||||||
|
intthread::InterruptibleThread monitorloop_task ;
|
||||||
|
intthread::InterruptibleThread winterface_update_loop_task ;
|
||||||
|
intthread::InterruptibleThread connection_to_server_loop_task ;
|
||||||
|
|
||||||
|
bool _initialized { false } ;
|
||||||
|
std::mutex _mutex_initialized ;
|
||||||
|
|
||||||
|
MonitorWirelessDevice * monwireless = nullptr ;
|
||||||
|
|
||||||
|
int init();
|
||||||
|
int init_first();
|
||||||
|
|
||||||
|
void mac_address_to_string(char *address, struct ether_addr *mac);
|
||||||
|
|
||||||
|
public :
|
||||||
|
|
||||||
|
static ckernelwifi::CallFromStaticFunc * forward ;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Default Constructor
|
||||||
|
*/
|
||||||
|
CKernelWifi();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Default Destructor
|
||||||
|
*/
|
||||||
|
~CKernelWifi();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief start the all activity
|
||||||
|
*/
|
||||||
|
int start();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief stop the all activity
|
||||||
|
*/
|
||||||
|
int stop();
|
||||||
|
|
||||||
|
int process_messages(struct nl_msg *msg);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief free dynamicly allocated memory and socket descriptors
|
||||||
|
*/
|
||||||
|
void clean_all();
|
||||||
|
|
||||||
|
bool initialized();
|
||||||
|
|
||||||
|
void connected_to_server(bool v);
|
||||||
|
|
||||||
|
bool is_connected_to_server();
|
||||||
|
|
||||||
|
bool reconnect_to_server() ;
|
||||||
|
|
||||||
|
void manage_server_crash_loop() ;
|
||||||
|
|
||||||
|
void being_started(bool v);
|
||||||
|
|
||||||
|
bool is_being_started();
|
||||||
|
|
||||||
|
protected :
|
||||||
|
|
||||||
|
void cout_mac_address(struct ether_addr *src);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Callback function to process messages received from kernel
|
||||||
|
* It processes the frames received from hwsim via netlink messages.
|
||||||
|
* These frames get sent via vsock to vwifi-server.
|
||||||
|
* \param msg - pointer to netlink message
|
||||||
|
* \param arg - pointer to additional args
|
||||||
|
* \return success or failure
|
||||||
|
*/
|
||||||
|
static int process_messages_cb(struct nl_msg *msg, void *arg);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Send a register message to kernel via netlink
|
||||||
|
* This informs hwsim we wish to receive frames
|
||||||
|
* Taken from wmediumd
|
||||||
|
* \return void
|
||||||
|
*/
|
||||||
|
int send_register_msg();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Initialize netlink communications
|
||||||
|
* Taken from wmediumd
|
||||||
|
* \return void
|
||||||
|
*/
|
||||||
|
int init_netlink();
|
||||||
|
int init_netlink_first();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief start receiving hwsim netlink frame from hwsim driver
|
||||||
|
*/
|
||||||
|
void recv_msg_from_hwsim_loop_start();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Send a tx_info frame to the kernel space. This frame indicates
|
||||||
|
* that the frame was transmitted/acked successfully. The ack is sent back
|
||||||
|
* to the driver with HWSIM_ATTR_ADDR_TRANSMITTER unmodified.
|
||||||
|
* This is derived form wmediumd.
|
||||||
|
* TODO: modify if we create more accurate acking.
|
||||||
|
* \param src - mac address of transmitting radio
|
||||||
|
* \param flags - falgs
|
||||||
|
* \param signal - signal strength
|
||||||
|
* \param tx_attempts - number of transmit attempts
|
||||||
|
* \param cookie - unique identifier for frame
|
||||||
|
* \return success or failure
|
||||||
|
*/
|
||||||
|
int send_tx_info_frame_nl(struct ether_addr *src,
|
||||||
|
unsigned int flags, int signal,
|
||||||
|
struct hwsim_tx_rate *tx_attempts,
|
||||||
|
u64 cookie);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief start receiving hwsim frame from vwifi-server loop
|
||||||
|
*/
|
||||||
|
void recv_msg_from_server_loop_start();
|
||||||
|
|
||||||
|
static void recv_msg_from_server_signal_handle(int sig_num);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief this is meant to be a thread which detects removal of driver
|
||||||
|
* Used to suspend normal actions until driver is loaded
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
void monitor_hwsim_loop();
|
||||||
|
|
||||||
|
void winet_update_loop();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Send a cloned frame to the kernel space driver.
|
||||||
|
* This will send a frame to the driver using netlink.
|
||||||
|
* It is received by hwsim with hwsim_cloned_frame_received_nl()
|
||||||
|
* This is taken from wmediumd and modified. It is called after the
|
||||||
|
* message has been received from wmasterd.
|
||||||
|
* \param dst - mac address of receving radio
|
||||||
|
* \param data - frame data
|
||||||
|
* \param data_len - length of frame
|
||||||
|
* \param rate_idx - number of attempts
|
||||||
|
* \param signal - signal strength
|
||||||
|
* \param freq - frequency
|
||||||
|
* \return success or failure
|
||||||
|
*/
|
||||||
|
int send_cloned_frame_msg(struct ether_addr *dst, char *data, int data_len,int rate_idx, int signal, uint32_t freq);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief handle messages received from server
|
||||||
|
*/
|
||||||
|
|
||||||
|
void recv_from_server();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief callback from cmonitorwirelessdevice that is called to
|
||||||
|
* handle addding wireless inet
|
||||||
|
*/
|
||||||
|
void handle_new_winet_notification(WirelessDevice);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief callback from cmonitorwirelessdevice that is called to
|
||||||
|
* handle deleting wireless inet
|
||||||
|
*/
|
||||||
|
void handle_del_winet_notification(const WirelessDevice&);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief callback from cmonitorwirelessdevice that is called to
|
||||||
|
* handle initial wireless inet
|
||||||
|
*/
|
||||||
|
void handle_init_winet_notification(WirelessDevice);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief get permanent mac address of ifname interface
|
||||||
|
*/
|
||||||
|
bool get_pmaddr(struct ether_addr &,const char *ifname);
|
||||||
|
|
||||||
|
/**
|
||||||
|
*\biref reconnecting to a server when detecting a socket disconnection
|
||||||
|
*/
|
||||||
|
void manage_server_crash();
|
||||||
|
|
||||||
|
// 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 void _Close() = 0;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \namespace ckernelwifi
|
||||||
|
*
|
||||||
|
* A namespace is used here, since a class CallFromStaticFunc is defined in other files
|
||||||
|
*/
|
||||||
|
namespace ckernelwifi {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \class CallFromStaticFunc
|
||||||
|
* \brief this class is an artifact used to call a member function from static function
|
||||||
|
*/
|
||||||
|
class CallFromStaticFunc {
|
||||||
|
|
||||||
|
CKernelWifi * m_obj ;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
explicit CallFromStaticFunc(CKernelWifi * obj){
|
||||||
|
|
||||||
|
m_obj = obj ;
|
||||||
|
};
|
||||||
|
|
||||||
|
int process_messages(struct nl_msg *msg) {
|
||||||
|
|
||||||
|
// add exception to check null ptr
|
||||||
|
m_obj->process_messages(msg);
|
||||||
|
return 0 ;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* _CKERNELWIFI_H_ */
|
||||||
|
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
#ifndef _CLISTINFO_H_
|
||||||
|
#define _CLISTINFO_H_
|
||||||
|
|
||||||
|
#include <vector> // vector
|
||||||
|
|
||||||
|
template <typename TypeInfo>
|
||||||
|
class CListInfo : public std::vector<TypeInfo>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,672 @@
|
|||||||
|
#include "cmonwirelessdevice.h"
|
||||||
|
#include "cwirelessdevice.h"
|
||||||
|
|
||||||
|
#include <asm/types.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <linux/netlink.h>
|
||||||
|
#include <linux/rtnetlink.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include <cstring>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#include <net/if_arp.h>
|
||||||
|
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
|
#include <thread>
|
||||||
|
|
||||||
|
#include <netlink/netlink.h>
|
||||||
|
#include <netlink/genl/genl.h>
|
||||||
|
#include <netlink/genl/ctrl.h>
|
||||||
|
#include <netlink/genl/family.h>
|
||||||
|
#include <netlink/route/link.h>
|
||||||
|
|
||||||
|
#include <linux/nl80211.h>
|
||||||
|
|
||||||
|
#ifdef _DEBUG
|
||||||
|
#include <net/if.h> // IFF_UP
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* allow calling a non static function from static function */
|
||||||
|
monitorinet::CallFromStaticFunc * MonitorWirelessDevice::forward = nullptr ;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void MonitorWirelessDevice::setNewInetCallback(CallbackFunction cb){
|
||||||
|
|
||||||
|
_newinet_cb = cb ;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MonitorWirelessDevice::setDelInetCallback(CallbackFunction cb){
|
||||||
|
|
||||||
|
_delinet_cb = cb ;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MonitorWirelessDevice::setInitInetCallback(CallbackFunction cb){
|
||||||
|
|
||||||
|
_initinet_cb = cb ;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
MonitorWirelessDevice::MonitorWirelessDevice(){
|
||||||
|
|
||||||
|
|
||||||
|
struct sockaddr_nl addr;
|
||||||
|
|
||||||
|
/* create a netlink route socket */
|
||||||
|
if(( _inetsock = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE)) < 0)
|
||||||
|
throw std::runtime_error("couldn't create a AF_NETLINK socket");
|
||||||
|
|
||||||
|
/* joins the multicast groups for link notifications */
|
||||||
|
std::memset(&addr, 0, sizeof addr);
|
||||||
|
addr.nl_family = AF_NETLINK;
|
||||||
|
addr.nl_groups = RTMGRP_LINK | RTMGRP_IPV4_IFADDR;
|
||||||
|
|
||||||
|
if (bind(_inetsock, (struct sockaddr *)&addr, sizeof(addr)) < 0)
|
||||||
|
throw std::runtime_error("couldn't bind to AF_NETLINK socket");
|
||||||
|
|
||||||
|
|
||||||
|
/* allows calls from static callback to non static member function */
|
||||||
|
forward = new monitorinet::CallFromStaticFunc(this);
|
||||||
|
|
||||||
|
/* init netlink 80211 */
|
||||||
|
if (nl80211_init() < 0)
|
||||||
|
throw std::runtime_error("Error initializing netlink 802.11");
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
MonitorWirelessDevice::~MonitorWirelessDevice(){
|
||||||
|
|
||||||
|
#ifdef _DEBUG
|
||||||
|
std::cout << __func__ << std::endl ;
|
||||||
|
#endif
|
||||||
|
if (started())
|
||||||
|
stop();
|
||||||
|
|
||||||
|
while(!outside_loop());
|
||||||
|
|
||||||
|
clean();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void MonitorWirelessDevice::clean(){
|
||||||
|
|
||||||
|
close(_inetsock);
|
||||||
|
nl_cb_put(wifi.cb);
|
||||||
|
nl_cb_put(wifi.cb1);
|
||||||
|
nl_close(wifi.nls);
|
||||||
|
nl_socket_free(wifi.nls);
|
||||||
|
}
|
||||||
|
|
||||||
|
int MonitorWirelessDevice::main_loop() {
|
||||||
|
|
||||||
|
fd_set rfds;
|
||||||
|
struct timeval tv;
|
||||||
|
|
||||||
|
|
||||||
|
_outsideloopmutex.lock() ;
|
||||||
|
_outsideloop = false ;
|
||||||
|
_outsideloopmutex.unlock();
|
||||||
|
|
||||||
|
|
||||||
|
while (started()) {
|
||||||
|
|
||||||
|
FD_ZERO(&rfds);
|
||||||
|
FD_CLR(_inetsock, &rfds);
|
||||||
|
FD_SET(_inetsock, &rfds);
|
||||||
|
|
||||||
|
tv.tv_sec = 1;
|
||||||
|
tv.tv_usec = 0;
|
||||||
|
|
||||||
|
int retval = select(FD_SETSIZE, &rfds, NULL, NULL, &tv);
|
||||||
|
if (retval == -1){
|
||||||
|
perror("select in MonitorWirelessDevice main_loop function");
|
||||||
|
stop();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if (retval){
|
||||||
|
|
||||||
|
#ifdef _DEBUG
|
||||||
|
std::cout << __func__ << "process event received from AF_NETLINK socket" << std::endl ;
|
||||||
|
#endif
|
||||||
|
recv_inet_event();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
_outsideloopmutex.lock() ;
|
||||||
|
_outsideloop = true ;
|
||||||
|
_outsideloopmutex.unlock();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool MonitorWirelessDevice::outside_loop(){
|
||||||
|
|
||||||
|
bool outsideorno = false ;
|
||||||
|
_outsideloopmutex.lock();
|
||||||
|
if (_outsideloop) outsideorno = true ;
|
||||||
|
_outsideloopmutex.unlock();
|
||||||
|
|
||||||
|
return outsideorno ;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MonitorWirelessDevice::start() {
|
||||||
|
|
||||||
|
if(started())
|
||||||
|
return ;
|
||||||
|
|
||||||
|
if (!outside_loop())
|
||||||
|
return ;
|
||||||
|
|
||||||
|
_startedmutex.lock() ;
|
||||||
|
_started = true ;
|
||||||
|
_startedmutex.unlock();
|
||||||
|
|
||||||
|
std::thread mainloop(&MonitorWirelessDevice::main_loop,this);
|
||||||
|
|
||||||
|
mainloop.detach();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MonitorWirelessDevice::stop() {
|
||||||
|
|
||||||
|
_startedmutex.lock();
|
||||||
|
_started = false ;
|
||||||
|
_startedmutex.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MonitorWirelessDevice::started() {
|
||||||
|
|
||||||
|
bool startorno = false ;
|
||||||
|
_startedmutex.lock();
|
||||||
|
if (_started) startorno = true ;
|
||||||
|
_startedmutex.unlock();
|
||||||
|
|
||||||
|
return startorno ;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************************************************/
|
||||||
|
/***************** handle netlink net device events from kernel ******************************/
|
||||||
|
/**********************************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
void MonitorWirelessDevice::recv_inet_event()
|
||||||
|
{
|
||||||
|
|
||||||
|
int len;
|
||||||
|
char buf[IFLIST_REPLY_BUFFER];
|
||||||
|
struct iovec iov = { buf, sizeof(buf) };
|
||||||
|
struct sockaddr_nl snl;
|
||||||
|
struct msghdr msg = { static_cast<void *>(&snl), sizeof(snl), &iov, 1, NULL, 0, 0 };
|
||||||
|
struct nlmsghdr *nlmsgheader;
|
||||||
|
|
||||||
|
/* read the waiting message */
|
||||||
|
len = recvmsg(_inetsock, &msg, 0);
|
||||||
|
if (len < 0)
|
||||||
|
perror("read_netlink");
|
||||||
|
for (nlmsgheader = reinterpret_cast<struct nlmsghdr *>(buf); NLMSG_OK(nlmsgheader, (unsigned int)len); nlmsgheader = NLMSG_NEXT(nlmsgheader, len)) {
|
||||||
|
|
||||||
|
switch (nlmsgheader->nlmsg_type) {
|
||||||
|
case NLMSG_DONE:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NLMSG_ERROR:
|
||||||
|
perror("read_netlink");
|
||||||
|
break;
|
||||||
|
|
||||||
|
// case RTM_SETLINK: /* we try to use it in order to detect chaging in wireless inet configuration, but it didn't work
|
||||||
|
//#ifdef _DEBUG
|
||||||
|
// std::cout << "Network interface configuration modified" << std::endl ;
|
||||||
|
//#endif
|
||||||
|
// break;
|
||||||
|
|
||||||
|
|
||||||
|
case RTM_NEWLINK:
|
||||||
|
#ifdef _DEBUG
|
||||||
|
std::cout << "Network interface added" << std::endl ;
|
||||||
|
#endif
|
||||||
|
new_net_interface(nlmsgheader);
|
||||||
|
break;
|
||||||
|
case RTM_DELLINK:
|
||||||
|
#ifdef _DEBUG
|
||||||
|
std::cout << "Network interface deleted" << std::endl ;
|
||||||
|
#endif
|
||||||
|
del_net_interface(nlmsgheader);
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void MonitorWirelessDevice::new_net_interface(struct nlmsghdr *h)
|
||||||
|
{
|
||||||
|
int len;
|
||||||
|
struct rtattr *tb[IFLA_MAX + 1];
|
||||||
|
char *name;
|
||||||
|
struct rtattr *rta;
|
||||||
|
struct ifinfomsg *ifi;
|
||||||
|
struct ether_addr macaddr ;
|
||||||
|
ifi = static_cast<struct ifinfomsg *>(NLMSG_DATA(h));
|
||||||
|
|
||||||
|
/*if (!(ifi->ifi_flags & IFLA_ADDRESS))
|
||||||
|
{
|
||||||
|
std::cout << "! IFLA_ADDRESS" << std::endl ;
|
||||||
|
return;
|
||||||
|
}*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef _DEBUG
|
||||||
|
if (ifi->ifi_flags & IFF_UP) { // get UP flag of the network interface
|
||||||
|
|
||||||
|
std::cout << "interface UP" << std::endl;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
std::cout << "Interface DOWN" << std::endl;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* retrieve all attributes */
|
||||||
|
memset(tb, 0, sizeof(tb));
|
||||||
|
rta = IFLA_RTA(ifi);
|
||||||
|
len = h->nlmsg_len - NLMSG_LENGTH(sizeof(struct ifinfomsg));
|
||||||
|
while (RTA_OK(rta, len)) {
|
||||||
|
if (rta->rta_type <= IFLA_MAX)
|
||||||
|
tb[rta->rta_type] = rta;
|
||||||
|
rta = RTA_NEXT(rta, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* require name field to be set */
|
||||||
|
if (tb[IFLA_IFNAME]) {
|
||||||
|
name = static_cast<char *>(RTA_DATA(tb[IFLA_IFNAME]));
|
||||||
|
} else {
|
||||||
|
std::cerr << "do not find interface name" << std::endl ;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef _DEBUG
|
||||||
|
if (ifi->ifi_family == AF_UNSPEC)
|
||||||
|
std::cout << "family: AF_UNSPEC" << std::endl;
|
||||||
|
|
||||||
|
if (ifi->ifi_family == AF_INET6)
|
||||||
|
std::cout << "family: AF_INET6" << std::endl ;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* require address field to be set */
|
||||||
|
if (tb[IFLA_ADDRESS]) {
|
||||||
|
|
||||||
|
std::memcpy(&macaddr, static_cast<void *>(RTA_DATA(tb[IFLA_ADDRESS])), ETH_ALEN);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string inet_name(name);
|
||||||
|
|
||||||
|
WirelessDevice inetdevice (inet_name,ifi->ifi_index,ifi->ifi_type,macaddr,0);
|
||||||
|
|
||||||
|
if(inetdevice.checkif_wireless_device()){
|
||||||
|
|
||||||
|
get_winterface_infos(ifi->ifi_index); // we can call a callback here, instead calling it in recv_winterface_infos, to reduce cpu
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void MonitorWirelessDevice::del_net_interface(struct nlmsghdr *h)
|
||||||
|
{
|
||||||
|
int len;
|
||||||
|
struct rtattr *tb[IFLA_MAX + 1];
|
||||||
|
char *name;
|
||||||
|
struct rtattr *rta;
|
||||||
|
struct ifinfomsg *ifi;
|
||||||
|
struct ether_addr macaddr ;
|
||||||
|
ifi = static_cast<struct ifinfomsg *>(NLMSG_DATA(h));
|
||||||
|
|
||||||
|
/*if (!(ifi->ifi_flags & IFLA_ADDRESS))
|
||||||
|
{
|
||||||
|
std::cout << "! IFLA_ADDRESS" << std::endl ;
|
||||||
|
return;
|
||||||
|
}*/
|
||||||
|
|
||||||
|
|
||||||
|
/* retrieve all attributes */
|
||||||
|
memset(tb, 0, sizeof(tb));
|
||||||
|
rta = IFLA_RTA(ifi);
|
||||||
|
len = h->nlmsg_len - NLMSG_LENGTH(sizeof(struct ifinfomsg));
|
||||||
|
while (RTA_OK(rta, len)) {
|
||||||
|
if (rta->rta_type <= IFLA_MAX)
|
||||||
|
tb[rta->rta_type] = rta;
|
||||||
|
rta = RTA_NEXT(rta, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* require name field to be set */
|
||||||
|
if (tb[IFLA_IFNAME]) {
|
||||||
|
name = static_cast<char *>(RTA_DATA(tb[IFLA_IFNAME]));
|
||||||
|
} else {
|
||||||
|
std::cerr << "do not find interface name" << std::endl ;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef _DEBUG
|
||||||
|
if (ifi->ifi_family == AF_UNSPEC)
|
||||||
|
std::cout << "family: AF_UNSPEC" << std::endl;
|
||||||
|
|
||||||
|
if (ifi->ifi_family == AF_INET6)
|
||||||
|
std::cout << "family: AF_INET6" << std::endl ;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* require address field to be set */
|
||||||
|
if (tb[IFLA_ADDRESS]) {
|
||||||
|
|
||||||
|
std::memcpy(&macaddr, static_cast<void *>(RTA_DATA(tb[IFLA_ADDRESS])), ETH_ALEN);
|
||||||
|
|
||||||
|
|
||||||
|
std::string inet_name(name);
|
||||||
|
|
||||||
|
WirelessDevice inetdevice (inet_name,ifi->ifi_index,ifi->ifi_type,macaddr,0);
|
||||||
|
|
||||||
|
if(inetdevice.checkif_wireless_device()){
|
||||||
|
|
||||||
|
_delinet_cb(inetdevice);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************************************************/
|
||||||
|
/***************** handle communication with nl80211 module ***********************************/
|
||||||
|
/**********************************************************************************************/
|
||||||
|
|
||||||
|
int MonitorWirelessDevice::nl80211_init(){
|
||||||
|
|
||||||
|
|
||||||
|
std::cout << __func__ << std::endl ;
|
||||||
|
|
||||||
|
/* init netlink socket with nl80211 module */
|
||||||
|
wifi.nls = nl_socket_alloc();
|
||||||
|
|
||||||
|
if (!wifi.nls) {
|
||||||
|
|
||||||
|
std::cerr << "Failed to allocate netlink socket." << std::endl ;
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
nl_socket_set_buffer_size(wifi.nls, 8192, 8192);
|
||||||
|
|
||||||
|
if (genl_connect(wifi.nls)) {
|
||||||
|
|
||||||
|
std::cerr << "Failed to connect to generic netlink" << std::endl ;
|
||||||
|
nl_close(wifi.nls);
|
||||||
|
nl_socket_free(wifi.nls);
|
||||||
|
return -ENOLINK;
|
||||||
|
}
|
||||||
|
|
||||||
|
wifi.nl80211_id = genl_ctrl_resolve(wifi.nls, "nl80211");
|
||||||
|
if (wifi.nl80211_id < 0) {
|
||||||
|
|
||||||
|
std::cerr << "nl80211 not found." << std::endl ;
|
||||||
|
nl_close(wifi.nls);
|
||||||
|
nl_socket_free(wifi.nls);
|
||||||
|
return -ENOENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*set a callback that receive messages from a module */
|
||||||
|
wifi.cb = nl_cb_alloc(NL_CB_DEFAULT);
|
||||||
|
|
||||||
|
if (!wifi.cb) {
|
||||||
|
|
||||||
|
std::cerr << "Failed to allocate netlink callback." << std::endl ;
|
||||||
|
nl_close(wifi.nls);
|
||||||
|
nl_socket_free(wifi.nls);
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*set a callback that receive messages from a module */
|
||||||
|
wifi.cb1 = nl_cb_alloc(NL_CB_DEFAULT);
|
||||||
|
|
||||||
|
if (!wifi.cb1) {
|
||||||
|
|
||||||
|
std::cerr << "Failed to allocate netlink callback." << std::endl ;
|
||||||
|
nl_close(wifi.nls);
|
||||||
|
nl_socket_free(wifi.nls);
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* set callbacks */
|
||||||
|
nl_cb_set(wifi.cb1, NL_CB_VALID, NL_CB_CUSTOM,recv_winterface_extra_infos_cb, &(wifi.err1));
|
||||||
|
nl_cb_set(wifi.cb1, NL_CB_FINISH, NL_CB_CUSTOM, handle_iee80211_com_finish_cb, &(wifi.err1));
|
||||||
|
nl_cb_set(wifi.cb, NL_CB_VALID, NL_CB_CUSTOM,recv_winterface_infos_cb, &(wifi.err));
|
||||||
|
nl_cb_set(wifi.cb, NL_CB_FINISH, NL_CB_CUSTOM, handle_iee80211_com_finish_cb, &(wifi.err));
|
||||||
|
|
||||||
|
return wifi.nl80211_id ;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int MonitorWirelessDevice::get_winterface_infos(int ifindex)
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
wifi.err = 1 ;
|
||||||
|
int flags ;
|
||||||
|
|
||||||
|
/* for one interface or for all interface */
|
||||||
|
if (ifindex != 0)
|
||||||
|
|
||||||
|
flags = 0;
|
||||||
|
else
|
||||||
|
flags = NLM_F_DUMP;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* allocate a msg to send to a module */
|
||||||
|
struct nl_msg *msg = nlmsg_alloc();
|
||||||
|
|
||||||
|
if (!msg) {
|
||||||
|
|
||||||
|
std::cerr << "Failed to allocate netlink message." << std::endl ;
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* send get inerface command to deriver */
|
||||||
|
genlmsg_put(msg, 0, 0, wifi.nl80211_id, 0, flags , NL80211_CMD_GET_INTERFACE, 0);
|
||||||
|
//genlmsg_put(msg,NL_AUTO_PORT,NL_AUTO_SEQ,wifi.nl80211_id,0,flags, NL80211_CMD_GET_INTERFACE, 0);
|
||||||
|
|
||||||
|
if (ifindex != 0)
|
||||||
|
nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex);
|
||||||
|
|
||||||
|
|
||||||
|
if (nl_send_auto(wifi.nls, msg) < 0)
|
||||||
|
{
|
||||||
|
nlmsg_free(msg);
|
||||||
|
return -1 ;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ifindex != 0)
|
||||||
|
nl_recvmsgs(wifi.nls, wifi.cb);
|
||||||
|
else
|
||||||
|
while(wifi.err > 0)
|
||||||
|
nl_recvmsgs(wifi.nls, wifi.cb);
|
||||||
|
|
||||||
|
nlmsg_free(msg);
|
||||||
|
|
||||||
|
return 0 ;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int MonitorWirelessDevice::recv_winterface_infos_cb(struct nl_msg *msg, [[maybe_unused]] void *arg){
|
||||||
|
|
||||||
|
forward->recv_winterface_infos(msg);
|
||||||
|
return 0 ;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int MonitorWirelessDevice::recv_winterface_infos(struct nl_msg *msg){
|
||||||
|
|
||||||
|
|
||||||
|
struct nlattr *tb_msg[NL80211_ATTR_MAX + 1];
|
||||||
|
struct genlmsghdr *gnlh = static_cast<struct genlmsghdr *>(nlmsg_data(nlmsg_hdr(msg)));
|
||||||
|
|
||||||
|
char *ifname;
|
||||||
|
int ifindex;
|
||||||
|
int iftype;
|
||||||
|
struct ether_addr macaddr ;
|
||||||
|
uint32_t txp = 0;
|
||||||
|
|
||||||
|
nla_parse(tb_msg, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),genlmsg_attrlen(gnlh, 0), NULL);
|
||||||
|
|
||||||
|
if (tb_msg[NL80211_ATTR_IFNAME])
|
||||||
|
|
||||||
|
ifname = nla_get_string(tb_msg[NL80211_ATTR_IFNAME]) ;
|
||||||
|
|
||||||
|
else
|
||||||
|
return NL_SKIP;
|
||||||
|
|
||||||
|
if (tb_msg[NL80211_ATTR_IFINDEX])
|
||||||
|
|
||||||
|
ifindex = nla_get_u32(tb_msg[NL80211_ATTR_IFINDEX]);
|
||||||
|
else
|
||||||
|
return NL_SKIP;
|
||||||
|
|
||||||
|
if (tb_msg[NL80211_ATTR_MAC])
|
||||||
|
|
||||||
|
std::memcpy(&macaddr, static_cast<void *>(nla_data(tb_msg[NL80211_ATTR_MAC])), ETH_ALEN);
|
||||||
|
else
|
||||||
|
return NL_SKIP;
|
||||||
|
|
||||||
|
|
||||||
|
if (tb_msg[NL80211_ATTR_IFTYPE])
|
||||||
|
|
||||||
|
iftype = nla_get_u32(tb_msg[NL80211_ATTR_IFTYPE]);
|
||||||
|
else
|
||||||
|
return NL_SKIP;
|
||||||
|
|
||||||
|
if (tb_msg[NL80211_ATTR_WIPHY_TX_POWER_LEVEL]) {
|
||||||
|
|
||||||
|
txp = nla_get_u32(tb_msg[NL80211_ATTR_WIPHY_TX_POWER_LEVEL]);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string inet_name(ifname);
|
||||||
|
|
||||||
|
WirelessDevice inetdevice (inet_name,ifindex,iftype,macaddr,txp);
|
||||||
|
|
||||||
|
if(!init_interfaces){
|
||||||
|
|
||||||
|
_initinet_cb(inetdevice);
|
||||||
|
init_interfaces = true ;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
_newinet_cb(inetdevice) ;
|
||||||
|
|
||||||
|
return NL_SKIP;
|
||||||
|
}
|
||||||
|
|
||||||
|
int MonitorWirelessDevice::recv_winterface_extra_infos_cb(struct nl_msg *msg, [[maybe_unused]] void *arg){
|
||||||
|
|
||||||
|
forward->recv_winterface_extra_infos(msg);
|
||||||
|
return 0 ;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int MonitorWirelessDevice::recv_winterface_extra_infos(struct nl_msg *msg){
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
struct nlattr *tb_msg[NL80211_ATTR_MAX + 1];
|
||||||
|
struct genlmsghdr *gnlh = static_cast<struct genlmsghdr *>(nlmsg_data(nlmsg_hdr(msg)));
|
||||||
|
|
||||||
|
struct nlattr *sinfo[NL80211_STA_INFO_MAX + 1];
|
||||||
|
// struct nlattr *rinfo[NL80211_RATE_INFO_MAX + 1];
|
||||||
|
|
||||||
|
struct nla_policy stats[NL80211_STA_INFO_MAX + 1];
|
||||||
|
stats[NL80211_STA_INFO_INACTIVE_TIME].type = NLA_U32 ;
|
||||||
|
stats[NL80211_STA_INFO_RX_BYTES].type = NLA_U32 ;
|
||||||
|
stats[NL80211_STA_INFO_TX_BYTES].type = NLA_U32 ;
|
||||||
|
stats[NL80211_STA_INFO_RX_PACKETS].type = NLA_U32 ;
|
||||||
|
stats[NL80211_STA_INFO_TX_PACKETS].type = NLA_U32 ;
|
||||||
|
stats[NL80211_STA_INFO_SIGNAL].type = NLA_U8 ;
|
||||||
|
stats[NL80211_STA_INFO_TX_BITRATE].type = NLA_NESTED;
|
||||||
|
stats[NL80211_STA_INFO_LLID].type = NLA_U16 ;
|
||||||
|
stats[NL80211_STA_INFO_PLID].type = NLA_U16 ;
|
||||||
|
stats[NL80211_STA_INFO_PLINK_STATE].type = NLA_U8 ;
|
||||||
|
|
||||||
|
nla_parse(tb_msg, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),genlmsg_attrlen(gnlh, 0), NULL);
|
||||||
|
|
||||||
|
|
||||||
|
/* get signal power-tx */
|
||||||
|
if (!tb_msg[NL80211_ATTR_STA_INFO]) {
|
||||||
|
|
||||||
|
std::cerr << __func__ << "sta stats missing!" << std::endl ;
|
||||||
|
return NL_SKIP;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nla_parse_nested(sinfo, NL80211_STA_INFO_MAX,tb_msg[NL80211_ATTR_STA_INFO], stats))
|
||||||
|
|
||||||
|
{
|
||||||
|
|
||||||
|
std::cerr << "failed to parse nested attributes" << std::endl;
|
||||||
|
return NL_SKIP;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (sinfo[NL80211_STA_INFO_SIGNAL]) {
|
||||||
|
|
||||||
|
int signal = 100+(int8_t)nla_get_u8(sinfo[NL80211_STA_INFO_SIGNAL]);
|
||||||
|
std::cout << __func__ << " Signal : " << signal << std::endl ;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return NL_SKIP;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int MonitorWirelessDevice::handle_iee80211_com_finish_cb( [[maybe_unused]] struct nl_msg *msg, void *arg){
|
||||||
|
|
||||||
|
forward->handle_iee80211_com_finish(arg);
|
||||||
|
return 0 ;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int MonitorWirelessDevice::handle_iee80211_com_finish(void *arg){
|
||||||
|
|
||||||
|
#ifdef _DEBUG
|
||||||
|
std::cout << __func__ << std::endl ;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int *ret = static_cast<int *>(arg);
|
||||||
|
*ret = 0;
|
||||||
|
return NL_SKIP;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,199 @@
|
|||||||
|
#ifndef _CMONITORWIRELESSDEVICE_H_
|
||||||
|
#define _CMONITORWIRELESSDEVICE_H_
|
||||||
|
|
||||||
|
|
||||||
|
#include "cwirelessdevice.h"
|
||||||
|
#include <list>
|
||||||
|
#include <mutex>
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
|
namespace monitorinet {
|
||||||
|
class CallFromStaticFunc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** Buffer size for netlink route interface list */
|
||||||
|
#define IFLIST_REPLY_BUFFER 4096
|
||||||
|
|
||||||
|
typedef std::function<void(WirelessDevice)> CallbackFunction ;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
struct nl_sock *nls;
|
||||||
|
int nl80211_id;
|
||||||
|
int err,err1 ;
|
||||||
|
struct nl_cb* cb;
|
||||||
|
struct nl_cb* cb1;
|
||||||
|
} WIFI;
|
||||||
|
|
||||||
|
|
||||||
|
class MonitorWirelessDevice {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* set to true when wireless interfaces are initialised */
|
||||||
|
bool init_interfaces = false ;
|
||||||
|
|
||||||
|
/* for netlink communication with 80211 module */
|
||||||
|
WIFI wifi ;
|
||||||
|
|
||||||
|
bool _outsideloop { true } ;
|
||||||
|
bool _started { false } ;
|
||||||
|
int _inetsock ;
|
||||||
|
|
||||||
|
std::mutex _startedmutex ;
|
||||||
|
std::mutex _outsideloopmutex ;
|
||||||
|
|
||||||
|
int main_loop();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief processes netlink route events from the kernel
|
||||||
|
* Determines the event type for netlink route messages (del/new).
|
||||||
|
* \return void
|
||||||
|
*/
|
||||||
|
void recv_inet_event();
|
||||||
|
bool outside_loop();
|
||||||
|
void clean();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief processes RTM_NEWLINK messages
|
||||||
|
* Detects when interfaces are created and modified
|
||||||
|
* \param struct nlmsghdr * - netlink message header
|
||||||
|
* \return void
|
||||||
|
*/
|
||||||
|
void new_net_interface(struct nlmsghdr *) ;
|
||||||
|
|
||||||
|
|
||||||
|
void del_net_interface(struct nlmsghdr *h);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief callback to be set through setCallback function by another object
|
||||||
|
* this callback is called by new_net_interface function in order to send a created, deleted or changed wirelessdevice
|
||||||
|
*/
|
||||||
|
CallbackFunction _newinet_cb ;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief callback to be set through setCallback function by another object
|
||||||
|
* this callback is called by new_net_interface function in order to send a created, deleted or changed wirelessdevice
|
||||||
|
*/
|
||||||
|
CallbackFunction _delinet_cb ;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief callback to be set through setCallback function by another object
|
||||||
|
* this callback is called by recv_winterface_infos function in order to send infos of each existing wireless interface
|
||||||
|
*/
|
||||||
|
CallbackFunction _initinet_cb ;
|
||||||
|
|
||||||
|
static int recv_winterface_infos_cb(struct nl_msg *msg, void *arg);
|
||||||
|
static int recv_winterface_extra_infos_cb(struct nl_msg *msg, void *arg);
|
||||||
|
static int handle_iee80211_com_finish_cb(struct nl_msg *msg, void *arg);
|
||||||
|
|
||||||
|
static monitorinet::CallFromStaticFunc * forward ;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
|
||||||
|
MonitorWirelessDevice();
|
||||||
|
~MonitorWirelessDevice();
|
||||||
|
MonitorWirelessDevice(const MonitorWirelessDevice &) = delete ;
|
||||||
|
MonitorWirelessDevice & operator=(const MonitorWirelessDevice&) = delete ;
|
||||||
|
|
||||||
|
void start();
|
||||||
|
void stop();
|
||||||
|
bool started();
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief set new interface notification callback
|
||||||
|
* \param CallbackFunction - defined earlier as typedef std::function<void(WirelessDevice)> CallbackFunction
|
||||||
|
* \return void
|
||||||
|
*/
|
||||||
|
void setNewInetCallback(CallbackFunction);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief set delete interface notification callback
|
||||||
|
* \param CallbackFunction - defined earlier as typedef std::function<void(WirelessDevice)> CallbackFunction
|
||||||
|
* \return void
|
||||||
|
*/
|
||||||
|
void setInitInetCallback(CallbackFunction);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief set interface initial list notification callback
|
||||||
|
* \param CallbackFunction - defined earlier as typedef std::function<void(WirelessDevice)> CallbackFunction
|
||||||
|
* \return void
|
||||||
|
*/
|
||||||
|
void setDelInetCallback(CallbackFunction);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*\fn int get_interface_infos()
|
||||||
|
* \brief Uses nl80211 to initialize a list of wireless interfaces Processes multiple netlink messages containing interface data
|
||||||
|
*\return error codes
|
||||||
|
*/
|
||||||
|
int get_winterface_infos(int);
|
||||||
|
|
||||||
|
int recv_winterface_infos(struct nl_msg *msg);
|
||||||
|
int recv_winterface_extra_infos(struct nl_msg *msg);
|
||||||
|
|
||||||
|
int handle_iee80211_com_finish(void *arg);
|
||||||
|
|
||||||
|
int nl80211_init() ;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \namespace monitorinet
|
||||||
|
*
|
||||||
|
* A namespace is used here, since a class CallFromStaticFunc is defined in other files
|
||||||
|
*/
|
||||||
|
namespace monitorinet {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \class CallFromStaticFunc
|
||||||
|
* \brief this class is an artifact used to call a member function from static function
|
||||||
|
*/
|
||||||
|
class CallFromStaticFunc {
|
||||||
|
|
||||||
|
MonitorWirelessDevice * m_obj ;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
explicit CallFromStaticFunc(MonitorWirelessDevice * obj){
|
||||||
|
|
||||||
|
m_obj = obj ;
|
||||||
|
};
|
||||||
|
|
||||||
|
int recv_winterface_infos(struct nl_msg *msg) {
|
||||||
|
|
||||||
|
// add exception to check null ptr
|
||||||
|
m_obj->recv_winterface_infos(msg);
|
||||||
|
return 0 ;
|
||||||
|
};
|
||||||
|
|
||||||
|
int recv_winterface_extra_infos(struct nl_msg *msg) {
|
||||||
|
|
||||||
|
// add exception to check null ptr
|
||||||
|
m_obj->recv_winterface_extra_infos(msg);
|
||||||
|
return 0 ;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
int handle_iee80211_com_finish(void *arg) {
|
||||||
|
|
||||||
|
// add exception to check null ptr
|
||||||
|
m_obj->handle_iee80211_com_finish(arg);
|
||||||
|
return 0 ;
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
#ifndef _CONFIG_H_
|
||||||
|
#define _CONFIG_H_
|
||||||
|
|
||||||
|
#include "types.h" // TIndex / TPort
|
||||||
|
|
||||||
|
#ifndef DISABLE_VHOST
|
||||||
|
#define ENABLE_VHOST
|
||||||
|
#endif
|
||||||
|
|
||||||
|
const TIndex WIFI_MAX_DECONNECTED_CLIENT = 15;
|
||||||
|
|
||||||
|
const bool LOST_PACKET_BY_DEFAULT=false;
|
||||||
|
|
||||||
|
const TPort DEFAULT_WIFI_CLIENT_PORT_VHOST = 8211;
|
||||||
|
const TPort DEFAULT_WIFI_CLIENT_PORT_INET = DEFAULT_WIFI_CLIENT_PORT_VHOST+1;
|
||||||
|
|
||||||
|
const TPort DEFAULT_WIFI_SPY_PORT = DEFAULT_WIFI_CLIENT_PORT_VHOST+2;
|
||||||
|
|
||||||
|
const TPort DEFAULT_CTRL_PORT = DEFAULT_WIFI_CLIENT_PORT_VHOST+3;
|
||||||
|
|
||||||
|
#define DEFAULT_ADDRESS_IP "127.0.0.1"
|
||||||
|
|
||||||
|
const int MAX_SIZE_NAME=12;
|
||||||
|
|
||||||
|
const int DEFAULT_NUMBER_WLAN_INTERFACE=0;
|
||||||
|
#define DEFAULT_MAC_PREFIX "74:F8:F6"
|
||||||
|
|
||||||
|
#ifdef _DEBUG
|
||||||
|
// #define _VERBOSE1
|
||||||
|
// #define _VERBOSE2
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
#ifndef _CONFIG_HWSIM_
|
||||||
|
#define _CONFIG_HWSIM_
|
||||||
|
|
||||||
|
#include "hwsim.h"
|
||||||
|
|
||||||
|
constexpr char KERNEL_HWSIM_FAMILY_NAME[] = "MAC80211_HWSIM";
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,99 @@
|
|||||||
|
#include <errno.h> // errno
|
||||||
|
#include <assert.h> // assert
|
||||||
|
#include <cstddef> // NULL
|
||||||
|
|
||||||
|
#include "cselect.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
CSelect::CSelect()
|
||||||
|
{
|
||||||
|
Init();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSelect::Init()
|
||||||
|
{
|
||||||
|
//clear the socket set
|
||||||
|
FD_ZERO(&Master);
|
||||||
|
|
||||||
|
//clear the socket set
|
||||||
|
FD_ZERO(&Dup);
|
||||||
|
|
||||||
|
MaxDescriptor=-1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSelect::UpdateMaxDescriptor(TDescriptor descriptor)
|
||||||
|
{
|
||||||
|
//highest file descriptor number, need it for the select function
|
||||||
|
if ( descriptor > MaxDescriptor )
|
||||||
|
MaxDescriptor=descriptor;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CSelect::AddNode(TDescriptor descriptor)
|
||||||
|
{
|
||||||
|
//add new socket to array of sockets
|
||||||
|
ListNodes.push_back(descriptor);
|
||||||
|
|
||||||
|
//add child sockets to set
|
||||||
|
FD_SET( descriptor , &Master);
|
||||||
|
|
||||||
|
//highest file descriptor number, need it for the select function
|
||||||
|
UpdateMaxDescriptor(descriptor);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSelect::DelNode(TDescriptor descriptor)
|
||||||
|
{
|
||||||
|
MaxDescriptor=-1;
|
||||||
|
for (auto node = ListNodes.begin() ; node != ListNodes.end(); ++node)
|
||||||
|
{
|
||||||
|
if( *node == descriptor )
|
||||||
|
{
|
||||||
|
auto node_to_delete = node;
|
||||||
|
|
||||||
|
FD_CLR(descriptor , &Master);
|
||||||
|
|
||||||
|
for (++node ; node != ListNodes.end(); ++node)
|
||||||
|
UpdateMaxDescriptor(*node);
|
||||||
|
|
||||||
|
ListNodes.erase(node_to_delete);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
UpdateMaxDescriptor(*node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TDescriptor CSelect::Wait()
|
||||||
|
{
|
||||||
|
return Wait(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
TDescriptor CSelect::Wait(const sigset_t *sigmask)
|
||||||
|
{
|
||||||
|
/* back up master */
|
||||||
|
Dup = Master;
|
||||||
|
|
||||||
|
//wait for an activity on one of the sockets , timeout is NULL ,
|
||||||
|
//so wait indefinitely
|
||||||
|
int activity=pselect( MaxDescriptor + 1 , &Dup , NULL , NULL , NULL, sigmask);
|
||||||
|
|
||||||
|
if ((activity < 0) && (errno!=EINTR))
|
||||||
|
return SCHEDULER_ERROR;
|
||||||
|
|
||||||
|
return activity;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool CSelect::DescriptorHasAction(TDescriptor descriptor)
|
||||||
|
{
|
||||||
|
return FD_ISSET( descriptor , &Dup);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CSelect::NodeHasAction(TIndex index)
|
||||||
|
{
|
||||||
|
assert( index < ListNodes.size() );
|
||||||
|
|
||||||
|
return FD_ISSET( ListNodes[index] , &Dup);
|
||||||
|
}
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
#ifndef _CSELECT_H_
|
||||||
|
#define _CSELECT_H_
|
||||||
|
|
||||||
|
#include <sys/select.h> // fd_set
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <vector> // vector
|
||||||
|
|
||||||
|
#include "types.h" // TDescriptor
|
||||||
|
|
||||||
|
const int SCHEDULER_ERROR=-1;
|
||||||
|
|
||||||
|
class CSelect
|
||||||
|
{
|
||||||
|
private :
|
||||||
|
|
||||||
|
//set of socket descriptors
|
||||||
|
fd_set Master;
|
||||||
|
fd_set Dup;
|
||||||
|
|
||||||
|
TDescriptor MaxDescriptor;
|
||||||
|
|
||||||
|
std::vector<TDescriptor> ListNodes;
|
||||||
|
|
||||||
|
void UpdateMaxDescriptor(TDescriptor descriptor);
|
||||||
|
|
||||||
|
void Init();
|
||||||
|
|
||||||
|
public :
|
||||||
|
|
||||||
|
CSelect();
|
||||||
|
|
||||||
|
bool AddNode(TDescriptor descriptor);
|
||||||
|
|
||||||
|
void DelNode(TDescriptor descriptor);
|
||||||
|
|
||||||
|
TDescriptor Wait();
|
||||||
|
|
||||||
|
TDescriptor Wait(const sigset_t *sigmask);
|
||||||
|
|
||||||
|
bool DescriptorHasAction(TDescriptor descriptor);
|
||||||
|
|
||||||
|
bool NodeHasAction(TIndex index);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
+106
@@ -0,0 +1,106 @@
|
|||||||
|
#include <cstdio> //perror
|
||||||
|
|
||||||
|
#include <iostream> // cout
|
||||||
|
|
||||||
|
#include <sys/socket.h> //socket
|
||||||
|
#include <arpa/inet.h> // struct sockaddr_in & inet_ntoa & ntohs
|
||||||
|
#include <linux/vm_sockets.h> // struct sockaddr_vm
|
||||||
|
#include <unistd.h> // close
|
||||||
|
#include <fcntl.h> // F_GETFL O_NONBLOCK
|
||||||
|
|
||||||
|
#include "csocket.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
CSocket::CSocket()
|
||||||
|
{
|
||||||
|
Master=0;
|
||||||
|
}
|
||||||
|
|
||||||
|
CSocket::~CSocket()
|
||||||
|
{
|
||||||
|
Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
CSocket::CSocket( const CSocket & socket )
|
||||||
|
{
|
||||||
|
Master=socket.Master;
|
||||||
|
}
|
||||||
|
|
||||||
|
TDescriptor CSocket::GetDescriptor() const
|
||||||
|
{
|
||||||
|
return Master;
|
||||||
|
}
|
||||||
|
|
||||||
|
ssize_t CSocket::Send(TDescriptor descriptor, const char* data, ssize_t sizeOfData)
|
||||||
|
{
|
||||||
|
ssize_t ret = send(descriptor, data, sizeOfData, 0);
|
||||||
|
if ( ret != sizeOfData )
|
||||||
|
return SOCKET_ERROR ;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
ssize_t CSocket::SendBigData(TDescriptor descriptor, const char* data, TMinimalSize sizeOfData)
|
||||||
|
{
|
||||||
|
ssize_t ret = Send(descriptor, (char*)&sizeOfData, (unsigned)sizeof(sizeOfData));
|
||||||
|
if( ret == SOCKET_ERROR )
|
||||||
|
return SOCKET_ERROR;
|
||||||
|
|
||||||
|
return Send(descriptor, data, sizeOfData);
|
||||||
|
}
|
||||||
|
|
||||||
|
ssize_t CSocket::Read(TDescriptor descriptor, char* data, ssize_t sizeOfData)
|
||||||
|
{
|
||||||
|
ssize_t ret = recv(descriptor , data, sizeOfData, 0);
|
||||||
|
if ( ret <= 0 )
|
||||||
|
return SOCKET_ERROR ;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
ssize_t CSocket::ReadEqualSize(TDescriptor descriptor, CDynBuffer* data, ssize_t byteAlreadyRead, ssize_t sizeToRead)
|
||||||
|
{
|
||||||
|
ssize_t sizeToRead_backup = sizeToRead;
|
||||||
|
sizeToRead-=byteAlreadyRead;
|
||||||
|
|
||||||
|
data->NeededSize(sizeToRead_backup,(byteAlreadyRead!=0));
|
||||||
|
|
||||||
|
char* buffer = data->GetBuffer();
|
||||||
|
buffer+=byteAlreadyRead;
|
||||||
|
|
||||||
|
while( sizeToRead > 0 )
|
||||||
|
{
|
||||||
|
ssize_t sizeRead=Read(descriptor, buffer, sizeToRead);
|
||||||
|
|
||||||
|
if( sizeRead == SOCKET_ERROR )
|
||||||
|
return SOCKET_ERROR;
|
||||||
|
|
||||||
|
sizeToRead-=sizeRead;
|
||||||
|
|
||||||
|
buffer+=sizeRead;
|
||||||
|
}
|
||||||
|
|
||||||
|
return sizeToRead_backup;
|
||||||
|
}
|
||||||
|
|
||||||
|
ssize_t CSocket::ReadBigData(TDescriptor descriptor, CDynBuffer* data)
|
||||||
|
{
|
||||||
|
TMinimalSize size;
|
||||||
|
|
||||||
|
int ret = Read(descriptor, (char*)&size, (unsigned)sizeof(size));
|
||||||
|
if( ret == SOCKET_ERROR )
|
||||||
|
return SOCKET_ERROR;
|
||||||
|
|
||||||
|
return ReadEqualSize(descriptor, data, 0, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
CSocket::operator int()
|
||||||
|
{
|
||||||
|
return Master;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSocket::Close()
|
||||||
|
{
|
||||||
|
close(Master);
|
||||||
|
}
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
#ifndef _CSOCKET_H_
|
||||||
|
#define _CSOCKET_H_
|
||||||
|
|
||||||
|
#include <sys/types.h> // ssize_t
|
||||||
|
|
||||||
|
#include "types.h" // TDescriptor / TSocket
|
||||||
|
#include "cdynbuffer.h" // CDynBuffer
|
||||||
|
|
||||||
|
const int SOCKET_ERROR=-1;
|
||||||
|
|
||||||
|
class CSocket
|
||||||
|
{
|
||||||
|
friend class CWifi;
|
||||||
|
|
||||||
|
protected :
|
||||||
|
|
||||||
|
TDescriptor Master;
|
||||||
|
|
||||||
|
CSocket();
|
||||||
|
|
||||||
|
CSocket( const CSocket & socket );
|
||||||
|
|
||||||
|
TDescriptor GetDescriptor() const;
|
||||||
|
|
||||||
|
virtual ssize_t Send(TDescriptor descriptor, const char* data, ssize_t sizeOfData);
|
||||||
|
virtual ssize_t SendBigData(TDescriptor descriptor, const char* data, TMinimalSize sizeOfData);
|
||||||
|
|
||||||
|
virtual ssize_t Read(TDescriptor descriptor, char* data, ssize_t sizeOfData);
|
||||||
|
virtual ssize_t ReadBigData(TDescriptor descriptor, CDynBuffer* data);
|
||||||
|
|
||||||
|
private :
|
||||||
|
ssize_t ReadEqualSize(TDescriptor descriptor, CDynBuffer* data, ssize_t byteAlreadyRead, ssize_t sizeToRead);
|
||||||
|
|
||||||
|
public :
|
||||||
|
|
||||||
|
void Close();
|
||||||
|
|
||||||
|
~CSocket();
|
||||||
|
|
||||||
|
operator int();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,102 @@
|
|||||||
|
#include <iostream> // cout
|
||||||
|
#include <cstdio> //perror
|
||||||
|
|
||||||
|
#include <sys/ioctl.h> // ioctl
|
||||||
|
#include <fcntl.h> // open
|
||||||
|
|
||||||
|
#include <arpa/inet.h> // INADDR_ANY
|
||||||
|
#include <unistd.h> // close
|
||||||
|
#include <assert.h> // assert
|
||||||
|
|
||||||
|
#include "csocketclient.h"
|
||||||
|
#include "tools.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
// ----------------- CSocketClient
|
||||||
|
|
||||||
|
CSocketClient::~CSocketClient()
|
||||||
|
{
|
||||||
|
CSocket::Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
CSocketClient::CSocketClient() : CSocket()
|
||||||
|
{
|
||||||
|
Init();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSocketClient::Init()
|
||||||
|
{
|
||||||
|
IsConnected=false;
|
||||||
|
StopTheReconnect=false ;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CSocketClient::ConnectLoop()
|
||||||
|
{
|
||||||
|
while ( ! StopTheReconnect )
|
||||||
|
{
|
||||||
|
if( _Connect() )
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The system asks to stop the reconnect
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CSocketClient::Connect(struct sockaddr* server, size_t size_of_server)
|
||||||
|
{
|
||||||
|
if( ! _Configure() )
|
||||||
|
{
|
||||||
|
cerr<<"Error : CSocketClient::Connect : Configure"<<endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( ! connect(Master,server,size_of_server) )
|
||||||
|
{
|
||||||
|
IsConnected=true;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
perror("CSocketClient::Connect : connect");
|
||||||
|
Close();
|
||||||
|
sleep(2);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ssize_t CSocketClient::Send(const char* data, ssize_t sizeOfData)
|
||||||
|
{
|
||||||
|
if ( IsConnected ){
|
||||||
|
|
||||||
|
return CSocket::Send(Master, data, sizeOfData);
|
||||||
|
|
||||||
|
}
|
||||||
|
return SOCKET_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
ssize_t CSocketClient::SendBigData(const char* data, TMinimalSize sizeOfData)
|
||||||
|
{
|
||||||
|
if ( IsConnected ){
|
||||||
|
return CSocket::SendBigData(Master, data, sizeOfData);
|
||||||
|
}
|
||||||
|
return SOCKET_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
ssize_t CSocketClient::Read(char* data, ssize_t sizeOfData)
|
||||||
|
{
|
||||||
|
if ( IsConnected ){
|
||||||
|
|
||||||
|
return CSocket::Read(Master, data, sizeOfData);
|
||||||
|
|
||||||
|
}
|
||||||
|
return SOCKET_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
ssize_t CSocketClient::ReadBigData(CDynBuffer* data)
|
||||||
|
{
|
||||||
|
if ( IsConnected ){
|
||||||
|
return CSocket::ReadBigData(Master, data);
|
||||||
|
}
|
||||||
|
return SOCKET_ERROR;
|
||||||
|
}
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
#ifndef _CSOCKETCLIENT_H_
|
||||||
|
#define _CSOCKETCLIENT_H_
|
||||||
|
|
||||||
|
#include "csocket.h"
|
||||||
|
|
||||||
|
class CSocketClient : public CSocket
|
||||||
|
{
|
||||||
|
bool IsConnected;
|
||||||
|
|
||||||
|
bool StopTheReconnect;
|
||||||
|
|
||||||
|
void Init();
|
||||||
|
|
||||||
|
protected :
|
||||||
|
|
||||||
|
bool Connect(struct sockaddr* server, size_t size_of_server);
|
||||||
|
|
||||||
|
public :
|
||||||
|
|
||||||
|
CSocketClient();
|
||||||
|
virtual ~CSocketClient();
|
||||||
|
|
||||||
|
using CSocket::Send;
|
||||||
|
ssize_t Send(const char* data, ssize_t sizeOfData);
|
||||||
|
|
||||||
|
using CSocket::SendBigData;
|
||||||
|
ssize_t SendBigData(const char* data, TMinimalSize sizeOfData);
|
||||||
|
|
||||||
|
using CSocket::Read;
|
||||||
|
ssize_t Read(char* data, ssize_t sizeOfData);
|
||||||
|
|
||||||
|
using CSocket::ReadBigData;
|
||||||
|
ssize_t ReadBigData(CDynBuffer* data);
|
||||||
|
|
||||||
|
bool ConnectLoop();
|
||||||
|
|
||||||
|
// virtual :
|
||||||
|
virtual bool _Configure() = 0;
|
||||||
|
virtual bool _Connect() = 0;
|
||||||
|
virtual int _GetID() = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
#include <iostream> // cout
|
||||||
|
#include <cstdio> //perror
|
||||||
|
|
||||||
|
#include <sys/ioctl.h> // ioctl
|
||||||
|
#include <fcntl.h> // open
|
||||||
|
|
||||||
|
#include <arpa/inet.h> // INADDR_ANY
|
||||||
|
#include <unistd.h> // close
|
||||||
|
#include <assert.h> // assert
|
||||||
|
|
||||||
|
#include "csocketclientitcp.h"
|
||||||
|
#include "tools.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
CSocketClientITCP::CSocketClientITCP() : CSocketClient()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSocketClientITCP::Init(const char* IP, TPort port)
|
||||||
|
{
|
||||||
|
Server.sin_family = AF_INET;
|
||||||
|
Server.sin_addr.s_addr = inet_addr(IP);
|
||||||
|
Server.sin_port = htons(port);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CSocketClientITCP::_Configure()
|
||||||
|
{
|
||||||
|
Master = socket(AF_INET , SOCK_STREAM , 0);
|
||||||
|
|
||||||
|
if( Master == SOCKET_ERROR )
|
||||||
|
{
|
||||||
|
perror("CSocketClientITCP::Configure : socket");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CSocketClientITCP::_Connect()
|
||||||
|
{
|
||||||
|
return Connect((struct sockaddr*) &Server, sizeof(Server));
|
||||||
|
}
|
||||||
|
|
||||||
|
int CSocketClientITCP::_GetID()
|
||||||
|
{
|
||||||
|
struct sockaddr_in my_addr;
|
||||||
|
|
||||||
|
socklen_t len = sizeof(my_addr);
|
||||||
|
getsockname(Master, (struct sockaddr *) &my_addr, &len);
|
||||||
|
|
||||||
|
return hash_ipaddr(&my_addr) ;
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
#ifndef _CSOCKETCLIENTITCP_H_
|
||||||
|
#define _CSOCKETCLIENTITCP_H_
|
||||||
|
|
||||||
|
#include "csocketclient.h"
|
||||||
|
|
||||||
|
#include <netinet/ip.h> // struct sockaddr_in
|
||||||
|
|
||||||
|
class CSocketClientITCP : public CSocketClient
|
||||||
|
{
|
||||||
|
private :
|
||||||
|
|
||||||
|
struct sockaddr_in Server;
|
||||||
|
|
||||||
|
public :
|
||||||
|
|
||||||
|
CSocketClientITCP();
|
||||||
|
|
||||||
|
void Init(const char* IP, TPort port);
|
||||||
|
|
||||||
|
bool _Configure() override;
|
||||||
|
|
||||||
|
bool _Connect() override;
|
||||||
|
|
||||||
|
int _GetID() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,66 @@
|
|||||||
|
#include <iostream> // cout
|
||||||
|
#include <cstdio> //perror
|
||||||
|
|
||||||
|
#include <sys/ioctl.h> // ioctl
|
||||||
|
#include <fcntl.h> // open
|
||||||
|
|
||||||
|
#include <arpa/inet.h> // INADDR_ANY
|
||||||
|
#include <unistd.h> // close
|
||||||
|
#include <assert.h> // assert
|
||||||
|
#include <cstring> // memset
|
||||||
|
|
||||||
|
#include "csocketclientvtcp.h"
|
||||||
|
#include "tools.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
CSocketClientVTCP::CSocketClientVTCP() : CSocketClient()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSocketClientVTCP::Init(TPort port)
|
||||||
|
{
|
||||||
|
memset(&Server, 0, sizeof(Server));
|
||||||
|
Server.svm_family = AF_VSOCK;
|
||||||
|
Server.svm_port = port;
|
||||||
|
Server.svm_cid = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CSocketClientVTCP::_Configure()
|
||||||
|
{
|
||||||
|
Master = socket(AF_VSOCK , SOCK_STREAM , 0);
|
||||||
|
|
||||||
|
if( Master == SOCKET_ERROR )
|
||||||
|
{
|
||||||
|
perror("CSocketClientVTCP::Configure : socket");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CSocketClientVTCP::_Connect()
|
||||||
|
{
|
||||||
|
return Connect((struct sockaddr*) &Server, sizeof(Server));
|
||||||
|
}
|
||||||
|
|
||||||
|
int CSocketClientVTCP::_GetID()
|
||||||
|
{
|
||||||
|
int cid;
|
||||||
|
|
||||||
|
int ioctl_fd = open("/dev/vsock", 0);
|
||||||
|
if (ioctl_fd < 0)
|
||||||
|
{
|
||||||
|
perror("Error : CSocketClientVHOST::GetID : open /dev/vsock :");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if( ioctl(ioctl_fd, IOCTL_VM_SOCKETS_GET_LOCAL_CID, &cid) < 0 )
|
||||||
|
{
|
||||||
|
perror("Error : CSocketClientVHOST::GetID : ioctl : Cannot get local CID :");
|
||||||
|
close(ioctl_fd);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
close(ioctl_fd);
|
||||||
|
return cid;
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
#ifndef _CSOCKETCLIENTVTCP_H_
|
||||||
|
#define _CSOCKETCLIENTVTCP_H_
|
||||||
|
|
||||||
|
#include <netinet/ip.h> // struct sockaddr_in
|
||||||
|
#include <linux/vm_sockets.h> // struct sockaddr_vm
|
||||||
|
|
||||||
|
#include "csocketclient.h"
|
||||||
|
|
||||||
|
class CSocketClientVTCP : public CSocketClient
|
||||||
|
{
|
||||||
|
private :
|
||||||
|
|
||||||
|
struct sockaddr_vm Server;
|
||||||
|
|
||||||
|
public :
|
||||||
|
|
||||||
|
CSocketClientVTCP();
|
||||||
|
|
||||||
|
void Init(TPort port);
|
||||||
|
|
||||||
|
bool _Configure() override;
|
||||||
|
|
||||||
|
bool _Connect() override;
|
||||||
|
|
||||||
|
int _GetID() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,166 @@
|
|||||||
|
#include <iostream> // cout
|
||||||
|
#include <cstdio> //perror
|
||||||
|
#include <cstring> // memcpy
|
||||||
|
#include <assert.h> // assert
|
||||||
|
|
||||||
|
#include <arpa/inet.h> // INADDR_ANY
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <linux/vm_sockets.h> // struct sockaddr_vm
|
||||||
|
|
||||||
|
#include "csocketserver.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
CSocketServer::CSocketServer(CListInfo<CInfoSocket>* infoSockets) : CSocket()
|
||||||
|
{
|
||||||
|
Init(0);
|
||||||
|
|
||||||
|
if( infoSockets == NULL )
|
||||||
|
{
|
||||||
|
InfoSockets = new CListInfo<CInfoSocket>;
|
||||||
|
|
||||||
|
ListInfoSelfManaged=true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
InfoSockets = infoSockets;
|
||||||
|
|
||||||
|
ListInfoSelfManaged=false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CSocketServer::CSocketServer( const CSocketServer & socketServer ) : CSocket(socketServer)
|
||||||
|
{
|
||||||
|
*this=socketServer;
|
||||||
|
}
|
||||||
|
|
||||||
|
CSocketServer& CSocketServer::operator=(const CSocketServer& socketServer)
|
||||||
|
{
|
||||||
|
if( this != &socketServer )
|
||||||
|
{
|
||||||
|
// protect against invalid self-assignment
|
||||||
|
Init(socketServer.GetPort());
|
||||||
|
|
||||||
|
ListInfoSelfManaged=socketServer.ListInfoSelfManaged;
|
||||||
|
|
||||||
|
if( ListInfoSelfManaged )
|
||||||
|
{
|
||||||
|
if( InfoSockets != NULL )
|
||||||
|
delete InfoSockets;
|
||||||
|
InfoSockets = new CListInfo<CInfoSocket>(*(socketServer.InfoSockets));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
InfoSockets = socketServer.InfoSockets;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// by convention, always return *this
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSocketServer::Init(TPort port)
|
||||||
|
{
|
||||||
|
Port=port;
|
||||||
|
}
|
||||||
|
|
||||||
|
TPort CSocketServer::GetPort() const
|
||||||
|
{
|
||||||
|
return Port;
|
||||||
|
}
|
||||||
|
|
||||||
|
CSocketServer::~CSocketServer()
|
||||||
|
{
|
||||||
|
for (auto& infoSocket : *InfoSockets)
|
||||||
|
infoSocket.Close();
|
||||||
|
|
||||||
|
delete InfoSockets;
|
||||||
|
|
||||||
|
CSocket::Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CSocketServer::Listen()
|
||||||
|
{
|
||||||
|
return _Listen(Master, Port);
|
||||||
|
}
|
||||||
|
|
||||||
|
TDescriptor CSocketServer::Accept(TCID& cid)
|
||||||
|
{
|
||||||
|
TDescriptor new_socket;
|
||||||
|
|
||||||
|
new_socket = _Accept(Master, cid);
|
||||||
|
if( new_socket == SOCKET_ERROR )
|
||||||
|
return SOCKET_ERROR;
|
||||||
|
|
||||||
|
//add new socket to array of sockets
|
||||||
|
InfoSockets->push_back(CInfoSocket(new_socket));
|
||||||
|
|
||||||
|
return new_socket;
|
||||||
|
}
|
||||||
|
|
||||||
|
TDescriptor CSocketServer::Accept()
|
||||||
|
{
|
||||||
|
TCID cid;
|
||||||
|
|
||||||
|
return Accept(cid);
|
||||||
|
}
|
||||||
|
|
||||||
|
TDescriptor CSocketServer::GetSocketClient(TIndex index) const
|
||||||
|
{
|
||||||
|
assert( index < InfoSockets->size() );
|
||||||
|
|
||||||
|
return (*InfoSockets)[index].GetDescriptor();
|
||||||
|
}
|
||||||
|
|
||||||
|
TDescriptor CSocketServer::operator[] (TIndex index)
|
||||||
|
{
|
||||||
|
return GetSocketClient(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
TIndex CSocketServer::GetNumberClient() const
|
||||||
|
{
|
||||||
|
return InfoSockets->size();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CSocketServer::IsEnable(TIndex index)
|
||||||
|
{
|
||||||
|
assert( index < GetNumberClient() );
|
||||||
|
|
||||||
|
return (*InfoSockets)[index].IsEnable();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSocketServer::DisableClient(TIndex index)
|
||||||
|
{
|
||||||
|
assert( index < InfoSockets->size() );
|
||||||
|
|
||||||
|
(*InfoSockets)[index].DisableIt();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSocketServer::CloseClient(TIndex index)
|
||||||
|
{
|
||||||
|
assert( index < InfoSockets->size() );
|
||||||
|
|
||||||
|
(*InfoSockets)[index].Close();
|
||||||
|
|
||||||
|
InfoSockets->erase (InfoSockets->begin()+index);
|
||||||
|
}
|
||||||
|
|
||||||
|
ssize_t CSocketServer::Send(TDescriptor descriptor, const char* data, ssize_t sizeOfData)
|
||||||
|
{
|
||||||
|
return CSocket::Send(descriptor, data, sizeOfData);
|
||||||
|
}
|
||||||
|
|
||||||
|
ssize_t CSocketServer::SendBigData(TDescriptor descriptor, const char* data, TMinimalSize sizeOfData)
|
||||||
|
{
|
||||||
|
return CSocket::SendBigData(descriptor, data, sizeOfData);
|
||||||
|
}
|
||||||
|
|
||||||
|
ssize_t CSocketServer::Read(TDescriptor descriptor, char* data, ssize_t sizeOfData)
|
||||||
|
{
|
||||||
|
return CSocket::Read(descriptor, data, sizeOfData);
|
||||||
|
}
|
||||||
|
|
||||||
|
ssize_t CSocketServer::ReadBigData(TDescriptor descriptor, CDynBuffer* data)
|
||||||
|
{
|
||||||
|
return CSocket::ReadBigData(descriptor, data);
|
||||||
|
}
|
||||||
@@ -0,0 +1,63 @@
|
|||||||
|
#ifndef _CSOCKETSERVER_H_
|
||||||
|
#define _CSOCKETSERVER_H_
|
||||||
|
|
||||||
|
#include "csocket.h"
|
||||||
|
#include "cinfosocket.h"
|
||||||
|
#include "clistinfo.h"
|
||||||
|
#include "types.h" // TIndex
|
||||||
|
|
||||||
|
class CSocketServer : public CSocket
|
||||||
|
{
|
||||||
|
protected :
|
||||||
|
|
||||||
|
TPort Port;
|
||||||
|
|
||||||
|
bool ListInfoSelfManaged;
|
||||||
|
CListInfo<CInfoSocket>* InfoSockets;
|
||||||
|
|
||||||
|
TDescriptor GetSocketClient(TIndex index) const;
|
||||||
|
|
||||||
|
TDescriptor Accept(TCID& cid);
|
||||||
|
TDescriptor Accept();
|
||||||
|
|
||||||
|
explicit CSocketServer(CListInfo<CInfoSocket>* infoSockets = NULL);
|
||||||
|
|
||||||
|
CSocketServer(TSocket type, CListInfo<CInfoSocket>* infoSockets = NULL);
|
||||||
|
|
||||||
|
CSocketServer( const CSocketServer & socketServer );
|
||||||
|
|
||||||
|
~CSocketServer();
|
||||||
|
|
||||||
|
CSocketServer& operator=(const CSocketServer& socketServer);
|
||||||
|
|
||||||
|
TPort GetPort() const;
|
||||||
|
|
||||||
|
void DisableClient(TIndex index);
|
||||||
|
|
||||||
|
void CloseClient(TIndex index);
|
||||||
|
|
||||||
|
ssize_t Send(TDescriptor descriptor, const char* data, ssize_t sizeOfData) override;
|
||||||
|
ssize_t SendBigData(TDescriptor descriptor, const char* data, TMinimalSize sizeOfData) override;
|
||||||
|
|
||||||
|
ssize_t Read(TDescriptor descriptor, char* data, ssize_t sizeOfData) override;
|
||||||
|
ssize_t ReadBigData(TDescriptor descriptor, CDynBuffer* data) override;
|
||||||
|
|
||||||
|
// virtual :
|
||||||
|
|
||||||
|
virtual bool _Listen(TDescriptor& master, TPort port) = 0;
|
||||||
|
virtual TDescriptor _Accept(TDescriptor master, TCID& cid) = 0;
|
||||||
|
|
||||||
|
public :
|
||||||
|
|
||||||
|
TIndex GetNumberClient() const;
|
||||||
|
|
||||||
|
TDescriptor operator[] (TIndex index);
|
||||||
|
|
||||||
|
bool IsEnable(TIndex index);
|
||||||
|
|
||||||
|
void Init(TPort port);
|
||||||
|
|
||||||
|
bool Listen();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,95 @@
|
|||||||
|
#include <iostream> // cout
|
||||||
|
#include <cstdio> //perror
|
||||||
|
#include <cstring> // memcpy
|
||||||
|
#include <assert.h> // assert
|
||||||
|
|
||||||
|
#include <arpa/inet.h> // INADDR_ANY
|
||||||
|
#include <sys/socket.h>
|
||||||
|
|
||||||
|
#include "csocket.h" // SOCKET_ERROR
|
||||||
|
#include "csocketserverfunctionitcp.h"
|
||||||
|
#include "tools.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
bool CSocketServerFunctionITCP::Configure(TDescriptor& master)
|
||||||
|
{
|
||||||
|
//create a master socket
|
||||||
|
|
||||||
|
master = socket(AF_INET , SOCK_STREAM , 0);
|
||||||
|
|
||||||
|
if( master == SOCKET_ERROR )
|
||||||
|
{
|
||||||
|
perror("CSocketServerFunctionITCP::Configure : socket");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CSocketServerFunctionITCP::_Listen(TDescriptor& master, TPort port)
|
||||||
|
{
|
||||||
|
if( ! Configure(master) )
|
||||||
|
{
|
||||||
|
cerr<<"Error : CSocketServerFunctionITCP::_Listen : Configure"<<endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//set master socket to allow multiple connections ,
|
||||||
|
//this is just a good habit, it will work without this
|
||||||
|
int opt = 1 ; // TRUE
|
||||||
|
if( setsockopt(master, SOL_SOCKET, SO_REUSEADDR, (char *)&opt, sizeof(opt)) < 0 )
|
||||||
|
{
|
||||||
|
perror("CSocketServerFunctionITCP::_Listen : setsockopt : SO_REUSEADDR");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct timeval timeout;
|
||||||
|
timeout.tv_sec = 3;
|
||||||
|
timeout.tv_usec = 0;
|
||||||
|
if (setsockopt (master, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(timeout)) < 0)
|
||||||
|
perror("CSocketServerFunctionITCP::_Listen : setsockopt : SO_RCVTIMEO\n");
|
||||||
|
if (setsockopt (master, SOL_SOCKET, SO_SNDTIMEO, (char *)&timeout, sizeof(timeout)) < 0)
|
||||||
|
perror("CSocketServerFunctionITCP::_Listen : setsockopt : SO_SNDTIMEO\n");
|
||||||
|
|
||||||
|
//type of socket created
|
||||||
|
struct sockaddr_in address;
|
||||||
|
address.sin_family = AF_INET;
|
||||||
|
address.sin_addr.s_addr = INADDR_ANY;
|
||||||
|
address.sin_port = htons( port );
|
||||||
|
|
||||||
|
//bind the socket
|
||||||
|
if (bind(master, (struct sockaddr *)&address, sizeof(address))<0)
|
||||||
|
{
|
||||||
|
perror("CSocketServer::_Listen : bind");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
cout<<"Listener on port : "<<port<<endl;
|
||||||
|
//try to specify maximum of 3 pending connections for the master socket
|
||||||
|
if( listen(master, 3) < 0 )
|
||||||
|
{
|
||||||
|
perror("CSocketServerFunctionITCP::_Listen : listen");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
TDescriptor CSocketServerFunctionITCP::_Accept(TDescriptor master, TCID& cid)
|
||||||
|
{
|
||||||
|
TDescriptor new_socket;
|
||||||
|
|
||||||
|
struct sockaddr_in address;
|
||||||
|
int addrlen = sizeof(address);
|
||||||
|
|
||||||
|
if( (new_socket = accept(master, (struct sockaddr *)&address, (socklen_t*)&addrlen)) < 0 )
|
||||||
|
{
|
||||||
|
perror("CSocketServerFunctionITCP::_Accept : accept");
|
||||||
|
return SOCKET_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
cid=hash_ipaddr(&address);
|
||||||
|
|
||||||
|
return new_socket;
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
#ifndef _CSOCKETSERVERFUNCTIONITCP_H_
|
||||||
|
#define _CSOCKETSERVERFUNCTIONITCP_H_
|
||||||
|
|
||||||
|
#include "types.h"
|
||||||
|
|
||||||
|
class CSocketServerFunctionITCP
|
||||||
|
{
|
||||||
|
private :
|
||||||
|
|
||||||
|
bool Configure(TDescriptor& master);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
bool _Listen(TDescriptor& master, TPort port);
|
||||||
|
|
||||||
|
TDescriptor _Accept(TDescriptor master, TCID& cid);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,91 @@
|
|||||||
|
#include <iostream> // cout
|
||||||
|
#include <cstdio> //perror
|
||||||
|
#include <cstring> // memset
|
||||||
|
#include <assert.h> // assert
|
||||||
|
|
||||||
|
#include <arpa/inet.h> // INADDR_ANY
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <linux/vm_sockets.h> // struct sockaddr_vm
|
||||||
|
|
||||||
|
#include "csocket.h" // SOCKET_ERROR
|
||||||
|
|
||||||
|
#include "csocketserverfunctionvtcp.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
bool CSocketServerFunctionVTCP::Configure(TDescriptor& master)
|
||||||
|
{
|
||||||
|
//create a master socket
|
||||||
|
|
||||||
|
master = socket(AF_VSOCK , SOCK_STREAM , 0);
|
||||||
|
|
||||||
|
if( master == SOCKET_ERROR )
|
||||||
|
{
|
||||||
|
perror("CSocketServerFunctionVTCP::_Configure : socket");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CSocketServerFunctionVTCP::_Listen(TDescriptor& master, TPort port)
|
||||||
|
{
|
||||||
|
if( ! Configure(master) )
|
||||||
|
{
|
||||||
|
cerr<<"Error : CSocketServerFunctionVTCP::_Listen : Configure"<<endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//type of socket created
|
||||||
|
struct sockaddr_vm address;
|
||||||
|
memset(&address, 0, sizeof(address));
|
||||||
|
address.svm_family = AF_VSOCK;
|
||||||
|
address.svm_port = port;
|
||||||
|
address.svm_cid = VMADDR_CID_ANY;
|
||||||
|
|
||||||
|
//bind the socket
|
||||||
|
if (bind(master, (struct sockaddr*)&address, sizeof(address)) != 0)
|
||||||
|
{
|
||||||
|
perror("CSocketServerFunctionVTCP::_Listen : bind");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Seems useless with VSOCK : the server detects immediately that a client is disconnected
|
||||||
|
struct timeval timeout;
|
||||||
|
timeout.tv_sec = 3;
|
||||||
|
timeout.tv_usec = 0;
|
||||||
|
if (setsockopt (master, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(timeout)) < 0)
|
||||||
|
perror("CSocketServerFunctionVTCP::_Listen : setsockopt : SO_RCVTIMEO\n");
|
||||||
|
if (setsockopt (master, SOL_SOCKET, SO_SNDTIMEO, (char *)&timeout, sizeof(timeout)) < 0)
|
||||||
|
perror("CSocketServerFunctionVTCP::_Listen : setsockopt : SO_SNDTIMEO\n");
|
||||||
|
*/
|
||||||
|
|
||||||
|
cout<<"Listener on port : "<<port<<endl;
|
||||||
|
//try to specify maximum of 3 pending connections for the master socket
|
||||||
|
if( listen(master, 3) < 0 )
|
||||||
|
{
|
||||||
|
perror("CSocketServerFunctionVTCP::_Listen : listen");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
TDescriptor CSocketServerFunctionVTCP::_Accept(TDescriptor master, TCID& cid)
|
||||||
|
{
|
||||||
|
TDescriptor new_socket;
|
||||||
|
|
||||||
|
struct sockaddr_in address;
|
||||||
|
int addrlen = sizeof(address);
|
||||||
|
|
||||||
|
if( (new_socket = accept(master, (struct sockaddr *)&address, (socklen_t*)&addrlen)) < 0 )
|
||||||
|
{
|
||||||
|
perror("CSocketServerFunctionVTCP::_Accept : accept");
|
||||||
|
return SOCKET_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
cid=((struct sockaddr_vm*)&address)->svm_cid;
|
||||||
|
|
||||||
|
return new_socket;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
#ifndef _CSOCKETSERVERFUNCTIONVTCP_H_
|
||||||
|
#define _CSOCKETSERVERFUNCTIONVTCP_H_
|
||||||
|
|
||||||
|
#include "types.h"
|
||||||
|
|
||||||
|
class CSocketServerFunctionVTCP
|
||||||
|
{
|
||||||
|
private :
|
||||||
|
|
||||||
|
bool Configure(TDescriptor& master);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
bool _Listen(TDescriptor& master, TPort port);
|
||||||
|
|
||||||
|
TDescriptor _Accept(TDescriptor master, TCID& cid);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
+142
@@ -0,0 +1,142 @@
|
|||||||
|
#include "cthread.h"
|
||||||
|
#include <condition_variable>
|
||||||
|
|
||||||
|
#include <signal.h>
|
||||||
|
|
||||||
|
namespace intthread {
|
||||||
|
|
||||||
|
|
||||||
|
/*********************************************************/
|
||||||
|
/* Global variables and functions */
|
||||||
|
/********************************************************/
|
||||||
|
|
||||||
|
thread_local InterruptFlag this_thread_interrupt_flag ;
|
||||||
|
|
||||||
|
void interruption_point(){
|
||||||
|
|
||||||
|
if(this_thread_interrupt_flag.is_set())
|
||||||
|
{
|
||||||
|
throw thread_interrupted();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************************/
|
||||||
|
/* InterruptFlag class definitions */
|
||||||
|
/********************************************************/
|
||||||
|
|
||||||
|
InterruptFlag::InterruptFlag()
|
||||||
|
{
|
||||||
|
_set = false ;
|
||||||
|
}
|
||||||
|
|
||||||
|
void InterruptFlag::set(){
|
||||||
|
|
||||||
|
std::lock_guard<std::mutex> guard(_mutex);
|
||||||
|
_set = true ;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
bool InterruptFlag::is_set() {
|
||||||
|
|
||||||
|
std::lock_guard<std::mutex> guard(_mutex);
|
||||||
|
return _set ;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*********************************************************/
|
||||||
|
/* InterruptibleThread class definitions */
|
||||||
|
/********************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int InterruptibleThread::number_thread = 0 ;
|
||||||
|
|
||||||
|
std::mutex InterruptibleThread::_number_thread_mutex ;
|
||||||
|
|
||||||
|
InterruptibleThread::InterruptibleThread(){
|
||||||
|
|
||||||
|
count_thread();
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool InterruptibleThread::started()
|
||||||
|
{
|
||||||
|
|
||||||
|
return _started ;
|
||||||
|
}
|
||||||
|
|
||||||
|
void InterruptibleThread::interrupt(){
|
||||||
|
|
||||||
|
if (_interrupt_flag != nullptr){
|
||||||
|
_interrupt_flag->set();
|
||||||
|
|
||||||
|
}
|
||||||
|
_started = false ;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void InterruptibleThread::join(){
|
||||||
|
|
||||||
|
_internal_thread.join();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
pthread_t InterruptibleThread::get_native_handle(){
|
||||||
|
|
||||||
|
return _internal_thread.native_handle();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::thread::id InterruptibleThread::get_id(){
|
||||||
|
|
||||||
|
|
||||||
|
return _internal_thread.get_id();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void InterruptibleThread::count_thread(){
|
||||||
|
|
||||||
|
std::unique_lock<std::mutex> lk(_number_thread_mutex);
|
||||||
|
number_thread++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void InterruptibleThread::uncount_thread(){
|
||||||
|
|
||||||
|
std::unique_lock<std::mutex> lk(_number_thread_mutex);
|
||||||
|
number_thread--;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool InterruptibleThread::all_thread_interrupted(){
|
||||||
|
|
||||||
|
std::unique_lock<std::mutex> lk(_number_thread_mutex);
|
||||||
|
return (number_thread == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*********************************************************/
|
||||||
|
/* AsyncTask class definitions */
|
||||||
|
/********************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
AsyncTask::AsyncTask(){
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void AsyncTask::dead() {
|
||||||
|
|
||||||
|
std::unique_lock<std::mutex> lk(_mutex_condition);
|
||||||
|
InterruptibleThread::uncount_thread() ;
|
||||||
|
_condition.notify_all();
|
||||||
|
lk.unlock();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+127
@@ -0,0 +1,127 @@
|
|||||||
|
#ifndef _CTHREAD_H_
|
||||||
|
#define _CTHREAD_H_
|
||||||
|
|
||||||
|
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <thread>
|
||||||
|
#include <future>
|
||||||
|
#include <iostream>
|
||||||
|
#include <mutex>
|
||||||
|
//#include <functional>
|
||||||
|
|
||||||
|
namespace intthread {
|
||||||
|
|
||||||
|
|
||||||
|
void interruption_point();
|
||||||
|
|
||||||
|
struct thread_interrupted{};
|
||||||
|
|
||||||
|
class InterruptFlag
|
||||||
|
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
bool _set ;
|
||||||
|
std::mutex _mutex ;
|
||||||
|
|
||||||
|
public:
|
||||||
|
InterruptFlag();
|
||||||
|
|
||||||
|
void set();
|
||||||
|
bool is_set() ;
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class AsyncTask
|
||||||
|
|
||||||
|
{
|
||||||
|
protected :
|
||||||
|
|
||||||
|
std::condition_variable _condition ;
|
||||||
|
std::mutex _mutex_condition ;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
AsyncTask();
|
||||||
|
void dead() ;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
extern thread_local InterruptFlag this_thread_interrupt_flag ;
|
||||||
|
|
||||||
|
class InterruptibleThread
|
||||||
|
|
||||||
|
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
|
||||||
|
InterruptFlag* _interrupt_flag {nullptr} ;
|
||||||
|
std::thread _internal_thread ;
|
||||||
|
static int number_thread ;
|
||||||
|
static std::mutex _number_thread_mutex ;
|
||||||
|
bool _started {false} ;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
InterruptibleThread();
|
||||||
|
|
||||||
|
pthread_t get_native_handle();
|
||||||
|
|
||||||
|
|
||||||
|
/* include <functional> with this version */
|
||||||
|
/*template<typename CLASS>
|
||||||
|
void start(CLASS * obj , void (CLASS::* f)() ){
|
||||||
|
|
||||||
|
std::function< void(void)> _f = std::bind(f,*obj) ;
|
||||||
|
|
||||||
|
std::promise<InterruptFlag*> p ;
|
||||||
|
_internal_thread = std::thread([_f,&p]{
|
||||||
|
p.set_value(&this_thread_interrupt_flag);
|
||||||
|
_f();
|
||||||
|
});
|
||||||
|
_interrupt_flag = p.get_future().get();
|
||||||
|
|
||||||
|
}*/
|
||||||
|
|
||||||
|
bool started() ;
|
||||||
|
|
||||||
|
template <typename OBJECT, typename FUNC>
|
||||||
|
void start(OBJECT * obj , FUNC f ){
|
||||||
|
|
||||||
|
|
||||||
|
std::promise<InterruptFlag*> p ;
|
||||||
|
_internal_thread = std::thread([obj,f,&p]{
|
||||||
|
p.set_value(&this_thread_interrupt_flag);
|
||||||
|
(obj->*f)();
|
||||||
|
});
|
||||||
|
_interrupt_flag = p.get_future().get();
|
||||||
|
_started = true ;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void interrupt();
|
||||||
|
void join();
|
||||||
|
std::thread::id get_id();
|
||||||
|
|
||||||
|
|
||||||
|
static bool all_thread_interrupted();
|
||||||
|
|
||||||
|
static void count_thread();
|
||||||
|
|
||||||
|
|
||||||
|
static void uncount_thread();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
} // intthread space
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,97 @@
|
|||||||
|
#include <math.h> // log10
|
||||||
|
#include <stdlib.h> // rand
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#include <netlink/netlink.h> // (struct nlmsghdr *)
|
||||||
|
|
||||||
|
#include "hwsim.h" // HWSIM_ATTR_FREQ
|
||||||
|
#include <netlink/genl/genl.h> // genlmsg_parse
|
||||||
|
|
||||||
|
#include "cwifi.h"
|
||||||
|
|
||||||
|
//#include "config.h"
|
||||||
|
|
||||||
|
const double ConstanteC=92.45;
|
||||||
|
const TFrequency DEFAULT_FREQUENCY=2412; // Hz
|
||||||
|
|
||||||
|
const int MTU=2352; // Maximum Transmission Unit : 2352 (from include/linux/ieee80211.h)
|
||||||
|
|
||||||
|
TFrequency CWifi::GetFrequency(struct nlmsghdr* nlh)
|
||||||
|
{
|
||||||
|
/* we get the attributes*/
|
||||||
|
struct nlattr *attrs[HWSIM_ATTR_FREQ + 1];
|
||||||
|
genlmsg_parse(nlh, 0, attrs, HWSIM_ATTR_FREQ, NULL);
|
||||||
|
|
||||||
|
/* we get frequence */
|
||||||
|
if (attrs[HWSIM_ATTR_FREQ])
|
||||||
|
return nla_get_u32(attrs[HWSIM_ATTR_FREQ]);
|
||||||
|
else
|
||||||
|
return DEFAULT_FREQUENCY;
|
||||||
|
}
|
||||||
|
|
||||||
|
// distance : meter
|
||||||
|
// frequency : Hz
|
||||||
|
int CWifi::Attenuation(TDistance distance, TFrequency frequency)
|
||||||
|
{
|
||||||
|
if( distance == 0 )
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
// ConstanteC+20*log10(frequency/1000)+20*log10(distance/1000);
|
||||||
|
// ConstanteC+20*(log10(frequency)-log10(1000))+20*(log10(distance)-log10(1000))
|
||||||
|
return ConstanteC+20*(log10(frequency)-3)+20*(log10(distance)-3);
|
||||||
|
}
|
||||||
|
|
||||||
|
TPower CWifi::BoundedPower(int power)
|
||||||
|
{
|
||||||
|
if( power < TPower_MIN )
|
||||||
|
return TPower_MIN;
|
||||||
|
if( power > TPower_MAX )
|
||||||
|
return TPower_MAX;
|
||||||
|
return power;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CWifi::PacketIsLost(TPower signalLevel)
|
||||||
|
{
|
||||||
|
//don't forget : signalLevel is negative
|
||||||
|
|
||||||
|
int alea = rand() % 53 + 40; // between 40 and 92
|
||||||
|
if( alea > -signalLevel )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
ssize_t CWifi::SendSignalWithSocket(CSocket* socket, TDescriptor descriptor, TPower* power, const char* buffer, int sizeOfBuffer)
|
||||||
|
{
|
||||||
|
// cout<<"send power : "<<power<<endl;
|
||||||
|
int val=socket->Send(descriptor, reinterpret_cast<const char*>(power), sizeof(TPower));
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
int valread;
|
||||||
|
|
||||||
|
// read the power
|
||||||
|
valread = socket->Read(descriptor, reinterpret_cast<char*>(power), sizeof(TPower));
|
||||||
|
if ( valread <= 0 )
|
||||||
|
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 )
|
||||||
|
return SOCKET_ERROR;
|
||||||
|
|
||||||
|
int sizeTotal=reinterpret_cast<struct nlmsghdr *>(buffer->GetBuffer())->nlmsg_len;
|
||||||
|
|
||||||
|
if( sizeTotal > MTU ) // to avoid that a error packet overfulls the memory
|
||||||
|
return SOCKET_ERROR;
|
||||||
|
|
||||||
|
return socket->ReadEqualSize(descriptor, buffer, sizeRead, sizeTotal);
|
||||||
|
}
|
||||||
+25
@@ -0,0 +1,25 @@
|
|||||||
|
#ifndef _WIFI_H_
|
||||||
|
#define _WIFI_H_
|
||||||
|
|
||||||
|
#include "types.h" // TPower
|
||||||
|
#include "csocket.h" // CSocket
|
||||||
|
|
||||||
|
class CWifi
|
||||||
|
{
|
||||||
|
protected :
|
||||||
|
|
||||||
|
TFrequency GetFrequency(struct nlmsghdr* nlh);
|
||||||
|
|
||||||
|
// distance : meter
|
||||||
|
int Attenuation(TDistance distance, TFrequency frequency);
|
||||||
|
|
||||||
|
// return power value between [TPower_MIN,TPower_MAX]
|
||||||
|
TPower BoundedPower(int power);
|
||||||
|
|
||||||
|
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);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
#include "cwificlient.h"
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
#ifndef _CWIFICLIENT_H_
|
||||||
|
#define _CWIFICLIENT_H_
|
||||||
|
|
||||||
|
#include "ckernelwifi.h"
|
||||||
|
#include "csocketclient.h"
|
||||||
|
#include "cwifi.h"
|
||||||
|
|
||||||
|
template <typename TypeCSocketClient>
|
||||||
|
class CWifiClient : public CKernelWifi, public CWifi, public TypeCSocketClient
|
||||||
|
{
|
||||||
|
bool _Connect(int* id) override
|
||||||
|
{
|
||||||
|
if( ! TypeCSocketClient::_Connect() )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if( ! Scheduler.AddNode(*this) )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
*id=TypeCSocketClient::_GetID();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
ssize_t _SendSignal(TPower* power, const char* buffer, int sizeOfBuffer) override
|
||||||
|
{ return SendSignalWithSocket(this, this->GetDescriptor(), power, buffer, sizeOfBuffer); }
|
||||||
|
|
||||||
|
ssize_t _RecvSignal(TPower* power, CDynBuffer* buffer) override
|
||||||
|
{ return RecvSignalWithSocket(this, this->GetDescriptor(), power, buffer); }
|
||||||
|
|
||||||
|
void _Close() override { TypeCSocketClient::Close(); };
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* _CWIFICLIENT_H_ */
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,267 @@
|
|||||||
|
#include <iostream> // cout
|
||||||
|
#include <cstdio> //perror
|
||||||
|
#include <cstring> // memcpy
|
||||||
|
#include <assert.h> // assert
|
||||||
|
|
||||||
|
#include <arpa/inet.h> // struct sockaddr_in
|
||||||
|
#include <sys/socket.h> // AF_VSOCK / AF_INET
|
||||||
|
#include <linux/vm_sockets.h> // struct sockaddr_vm
|
||||||
|
|
||||||
|
#include "cwifiserver.h"
|
||||||
|
#include "tools.h"
|
||||||
|
#include "config.h" // LOST_PACKET_BY_DEFAULT
|
||||||
|
|
||||||
|
bool CanLostPackets=LOST_PACKET_BY_DEFAULT;
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
CWifiServer::CWifiServer() : CSocketServer ()
|
||||||
|
{
|
||||||
|
DefaultValues();
|
||||||
|
|
||||||
|
InfoWifis = new CListInfo<CInfoWifi>;
|
||||||
|
InfoWifisDeconnected = new CListInfo<CInfoWifi>;
|
||||||
|
}
|
||||||
|
|
||||||
|
CWifiServer::CWifiServer(CListInfo<CInfoSocket>* infoSockets, CListInfo<CInfoWifi>* infoWifis, CListInfo<CInfoWifi>* infoWifisDeconnected) : CSocketServer (infoSockets)
|
||||||
|
{
|
||||||
|
DefaultValues();
|
||||||
|
|
||||||
|
InfoWifis = infoWifis;
|
||||||
|
InfoWifisDeconnected = infoWifisDeconnected;
|
||||||
|
}
|
||||||
|
|
||||||
|
CWifiServer::CWifiServer( const CWifiServer & wifiServer ) : CSocketServer(wifiServer), CWifi(wifiServer)
|
||||||
|
{
|
||||||
|
*this=wifiServer;
|
||||||
|
}
|
||||||
|
|
||||||
|
CWifiServer::~CWifiServer()
|
||||||
|
{
|
||||||
|
if( ListInfoSelfManaged )
|
||||||
|
{
|
||||||
|
delete InfoWifis;
|
||||||
|
delete InfoWifisDeconnected;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CWifiServer& CWifiServer::operator=(const CWifiServer& wifiServer)
|
||||||
|
{
|
||||||
|
if( this != &wifiServer )
|
||||||
|
{
|
||||||
|
// protect against invalid self-assignment
|
||||||
|
MaxClientDeconnected=wifiServer.MaxClientDeconnected;
|
||||||
|
|
||||||
|
if( ListInfoSelfManaged )
|
||||||
|
{
|
||||||
|
if( InfoWifis != NULL )
|
||||||
|
{
|
||||||
|
delete InfoWifis;
|
||||||
|
delete InfoWifisDeconnected;
|
||||||
|
}
|
||||||
|
InfoWifis = new CListInfo<CInfoWifi>(*(wifiServer.InfoWifis));
|
||||||
|
InfoWifisDeconnected = new CListInfo<CInfoWifi>(*(wifiServer.InfoWifisDeconnected));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
InfoWifis = wifiServer.InfoWifis;
|
||||||
|
InfoWifisDeconnected = wifiServer.InfoWifisDeconnected;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// by convention, always return *this
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CWifiServer::DefaultValues()
|
||||||
|
{
|
||||||
|
MaxClientDeconnected=0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CWifiServer::Listen(TIndex maxClientDeconnected)
|
||||||
|
{
|
||||||
|
MaxClientDeconnected=maxClientDeconnected;
|
||||||
|
|
||||||
|
if( ! _Listen(Master, Port) )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CWifiServer::RecoverInfosOfInfoWifiDeconnected(TCID cid, CCoordinate& coo, string& name)
|
||||||
|
{
|
||||||
|
for (auto infoWifiDeconnected = InfoWifisDeconnected->begin(); infoWifiDeconnected != InfoWifisDeconnected->end(); ++infoWifiDeconnected)
|
||||||
|
{
|
||||||
|
if ( infoWifiDeconnected->GetCid() == cid )
|
||||||
|
{
|
||||||
|
coo=*infoWifiDeconnected;
|
||||||
|
name=infoWifiDeconnected->GetName();
|
||||||
|
|
||||||
|
InfoWifisDeconnected->erase(infoWifiDeconnected);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CWifiServer::RecoverInfosOfInfoWifi(TCID cid, CCoordinate& coo, string& name)
|
||||||
|
{
|
||||||
|
int index=0;
|
||||||
|
for (auto& infoWifi : *InfoWifis)
|
||||||
|
{
|
||||||
|
if( IsEnable(index) )
|
||||||
|
if( infoWifi.GetCid() == cid )
|
||||||
|
{
|
||||||
|
coo=infoWifi;
|
||||||
|
name=infoWifi.GetName();
|
||||||
|
|
||||||
|
DisableClient(index);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
TDescriptor CWifiServer::Accept()
|
||||||
|
{
|
||||||
|
TCID cid;
|
||||||
|
|
||||||
|
TDescriptor new_socket = CSocketServer::Accept(cid);
|
||||||
|
if( new_socket == SOCKET_ERROR )
|
||||||
|
return SOCKET_ERROR;
|
||||||
|
|
||||||
|
CInfoWifi infoWifi;
|
||||||
|
|
||||||
|
CCoordinate coo;
|
||||||
|
string name;
|
||||||
|
if( RecoverInfosOfInfoWifiDeconnected(cid,coo,name) || RecoverInfosOfInfoWifi(cid, coo,name) )
|
||||||
|
{
|
||||||
|
infoWifi.Set(coo);
|
||||||
|
infoWifi.SetName(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
infoWifi.SetCid(cid);
|
||||||
|
|
||||||
|
InfoWifis->push_back(infoWifi);
|
||||||
|
|
||||||
|
return new_socket;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CWifiServer::ShowInfoWifi(TIndex index)
|
||||||
|
{
|
||||||
|
assert( index < GetNumberClient() );
|
||||||
|
|
||||||
|
cout<<(*InfoWifis)[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
void CWifiServer::CloseClient(TIndex index)
|
||||||
|
{
|
||||||
|
assert( index < GetNumberClient() );
|
||||||
|
|
||||||
|
CSocketServer::CloseClient(index);
|
||||||
|
|
||||||
|
// save the InfoWifi (the coordinate of the cid)
|
||||||
|
AddInfoWifiDeconnected( (*InfoWifis)[index] );
|
||||||
|
|
||||||
|
InfoWifis->erase(InfoWifis->begin()+index);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CWifiServer::CloseAllClient()
|
||||||
|
{
|
||||||
|
// ( be careful : "TIndex i" is a **unsigned** int : i=0 ; i-1 != -1 but = 65534 )
|
||||||
|
|
||||||
|
TIndex nbre=GetNumberClient(); // because CloseClient changes the value of GetNumberClient()
|
||||||
|
for (TIndex i = 0; i < nbre; i++)
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
return SendSignalWithSocket(this, descriptor, power, buffer, sizeOfBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
ssize_t CWifiServer::RecvSignal(TDescriptor descriptor, TPower* power, CDynBuffer* buffer)
|
||||||
|
{
|
||||||
|
return RecvSignalWithSocket(this, descriptor, power, buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CWifiServer::SendAllOtherClients(TIndex index,TPower power, const char* data, ssize_t sizeOfData)
|
||||||
|
{
|
||||||
|
CCoordinate coo=(*InfoWifis)[index];
|
||||||
|
// cout<<"Forward "<<sizeOfData<<" bytes with "<<power<<" powers"<<endl;
|
||||||
|
|
||||||
|
for (TIndex i = 0; i < GetNumberClient(); i++)
|
||||||
|
{
|
||||||
|
if( i != index )
|
||||||
|
if( IsEnable(i) )
|
||||||
|
{
|
||||||
|
TFrequency frequency = static_cast<TFrequency>(GetFrequency( reinterpret_cast<struct nlmsghdr*>(const_cast<char*>(data)) ));
|
||||||
|
TPower signalLevel=BoundedPower(power-Attenuation(coo.DistanceWith((*InfoWifis)[i]),frequency));
|
||||||
|
|
||||||
|
if( ! CanLostPackets || ! PacketIsLost(signalLevel) )
|
||||||
|
if( SendSignal((*InfoSockets)[i].GetDescriptor(), &signalLevel, data, sizeOfData) < 0 )
|
||||||
|
(*InfoSockets)[i].DisableIt();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CWifiServer::SendAllOtherClientsWithoutLoss(TIndex index, TPower power, const char* data, ssize_t sizeOfData)
|
||||||
|
{
|
||||||
|
for (TIndex i = 0; i < GetNumberClient(); i++)
|
||||||
|
{
|
||||||
|
if( i != index )
|
||||||
|
if( IsEnable(i) )
|
||||||
|
if( SendSignal((*InfoSockets)[i].GetDescriptor(), &power, data, sizeOfData) < 0 )
|
||||||
|
(*InfoSockets)[i].DisableIt();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CWifiServer::SendAllClientsWithoutLoss(TPower power, const char* data, ssize_t sizeOfData)
|
||||||
|
{
|
||||||
|
for (TIndex i = 0; i < GetNumberClient(); i++)
|
||||||
|
if( IsEnable(i) )
|
||||||
|
if( SendSignal((*InfoSockets)[i].GetDescriptor(), &power, data, sizeOfData) < 0 )
|
||||||
|
(*InfoSockets)[i].DisableIt();
|
||||||
|
}
|
||||||
|
|
||||||
|
CInfoWifi* CWifiServer::GetReferenceOnInfoWifiByCID(TCID cid) const
|
||||||
|
{
|
||||||
|
for (auto& infoWifi : *InfoWifis)
|
||||||
|
{
|
||||||
|
if( infoWifi.GetCid() == cid )
|
||||||
|
return &infoWifi;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
CInfoWifi* CWifiServer::GetReferenceOnInfoWifiDeconnectedByCID(TCID cid) const
|
||||||
|
{
|
||||||
|
for (auto& infoWifiDeconnected : *InfoWifisDeconnected)
|
||||||
|
{
|
||||||
|
if( infoWifiDeconnected.GetCid() == cid )
|
||||||
|
return &infoWifiDeconnected;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
CInfoWifi* CWifiServer::GetReferenceOnInfoWifiByIndex(TIndex index) const
|
||||||
|
{
|
||||||
|
assert( index < GetNumberClient() );
|
||||||
|
|
||||||
|
return &((*InfoWifis)[index]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CWifiServer::AddInfoWifiDeconnected(CInfoWifi infoWifi)
|
||||||
|
{
|
||||||
|
if( InfoWifisDeconnected->size() >= MaxClientDeconnected )
|
||||||
|
InfoWifisDeconnected->erase(InfoWifisDeconnected->begin());
|
||||||
|
|
||||||
|
InfoWifisDeconnected->push_back(infoWifi);
|
||||||
|
}
|
||||||
@@ -0,0 +1,67 @@
|
|||||||
|
#ifndef _CWIFISERVER_H_
|
||||||
|
#define _CWIFISERVER_H_
|
||||||
|
|
||||||
|
#include "csocketserver.h"
|
||||||
|
#include "cinfowifi.h"
|
||||||
|
#include "cwifi.h"
|
||||||
|
|
||||||
|
extern bool CanLostPackets;
|
||||||
|
|
||||||
|
class CWifiServer : public CSocketServer, public CWifi
|
||||||
|
{
|
||||||
|
friend class CCTRLServer;
|
||||||
|
|
||||||
|
TIndex MaxClientDeconnected;
|
||||||
|
|
||||||
|
CListInfo<CInfoWifi>* InfoWifis;
|
||||||
|
CListInfo<CInfoWifi>* InfoWifisDeconnected;
|
||||||
|
|
||||||
|
bool RecoverInfosOfInfoWifiDeconnected(TCID cid, CCoordinate& coo, string& name);
|
||||||
|
|
||||||
|
bool RecoverInfosOfInfoWifi(TCID cid, CCoordinate& coo, string& name);
|
||||||
|
|
||||||
|
void DefaultValues();
|
||||||
|
|
||||||
|
public :
|
||||||
|
|
||||||
|
CWifiServer();
|
||||||
|
|
||||||
|
CWifiServer(CListInfo<CInfoSocket>* infoSockets, CListInfo<CInfoWifi>* infoWifis, CListInfo<CInfoWifi>* infoWifisDeconnected);
|
||||||
|
|
||||||
|
CWifiServer( const CWifiServer & wifiServer );
|
||||||
|
|
||||||
|
~CWifiServer();
|
||||||
|
|
||||||
|
CWifiServer& operator=(const CWifiServer& wifiServer);
|
||||||
|
|
||||||
|
bool Listen(TIndex maxClientDeconnected);
|
||||||
|
|
||||||
|
TDescriptor Accept();
|
||||||
|
|
||||||
|
void ShowInfoWifi(TIndex index);
|
||||||
|
|
||||||
|
void CloseClient(TIndex index);
|
||||||
|
|
||||||
|
void CloseAllClient();
|
||||||
|
|
||||||
|
ssize_t SendSignal(TDescriptor descriptor, TPower* power, const char* buffer, int sizeOfBuffer);
|
||||||
|
|
||||||
|
ssize_t RecvSignal(TDescriptor descriptor, TPower* power, CDynBuffer* buffer);
|
||||||
|
|
||||||
|
void SendAllOtherClients(TIndex index,TPower power, const char* data, ssize_t sizeOfData);
|
||||||
|
|
||||||
|
void SendAllOtherClientsWithoutLoss(TIndex index, TPower power, const char* data, ssize_t sizeOfData);
|
||||||
|
|
||||||
|
void SendAllClientsWithoutLoss(TPower power, const char* data, ssize_t sizeOfData);
|
||||||
|
|
||||||
|
CInfoWifi* GetReferenceOnInfoWifiByCID(TCID cid) const;
|
||||||
|
|
||||||
|
CInfoWifi* GetReferenceOnInfoWifiDeconnectedByCID(TCID cid) const;
|
||||||
|
|
||||||
|
CInfoWifi* GetReferenceOnInfoWifiByIndex(TIndex index) const;
|
||||||
|
|
||||||
|
void AddInfoWifiDeconnected(CInfoWifi infoWifi);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
#include"cwifiserveritcp.h"
|
||||||
|
|
||||||
|
CWifiServerITCP::CWifiServerITCP() : CWifiServer()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
CWifiServerITCP::CWifiServerITCP(CListInfo<CInfoSocket>* infoSockets, CListInfo<CInfoWifi>* infoWifis, CListInfo<CInfoWifi>* infoWifisDeconnected) : CWifiServer(infoSockets, infoWifis, infoWifisDeconnected)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CWifiServerITCP::_Listen(TDescriptor& master, TPort port)
|
||||||
|
{
|
||||||
|
return CSocketServerFunctionITCP::_Listen(master, port);
|
||||||
|
}
|
||||||
|
|
||||||
|
TDescriptor CWifiServerITCP::_Accept(TDescriptor master, TCID& cid)
|
||||||
|
{
|
||||||
|
return CSocketServerFunctionITCP::_Accept(master, cid);
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
#ifndef _CWIFISERVERITCP_H_
|
||||||
|
#define _CWIFISERVERITCP_H_
|
||||||
|
|
||||||
|
#include "csocketserverfunctionitcp.h"
|
||||||
|
#include "cwifiserver.h"
|
||||||
|
|
||||||
|
class CWifiServerITCP : public CWifiServer, public CSocketServerFunctionITCP
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
CWifiServerITCP();
|
||||||
|
|
||||||
|
CWifiServerITCP(CListInfo<CInfoSocket>* infoSockets, CListInfo<CInfoWifi>* infoWifis, CListInfo<CInfoWifi>* infoWifisDeconnected);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
bool _Listen(TDescriptor& master, TPort port) override;
|
||||||
|
|
||||||
|
TDescriptor _Accept(TDescriptor master, TCID& cid) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
#include"cwifiservervtcp.h"
|
||||||
|
|
||||||
|
CWifiServerVTCP::CWifiServerVTCP(CListInfo<CInfoSocket>* infoSockets, CListInfo<CInfoWifi>* infoWifis, CListInfo<CInfoWifi>* infoWifisDeconnected) : CWifiServer(infoSockets, infoWifis, infoWifisDeconnected)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CWifiServerVTCP::_Listen(TDescriptor& master, TPort port)
|
||||||
|
{
|
||||||
|
return CSocketServerFunctionVTCP::_Listen(master, port);
|
||||||
|
}
|
||||||
|
|
||||||
|
TDescriptor CWifiServerVTCP::_Accept(TDescriptor master, TCID& cid)
|
||||||
|
{
|
||||||
|
return CSocketServerFunctionVTCP::_Accept(master, cid);
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
#ifndef _CWIFISERVERVTCP_H_
|
||||||
|
#define _CWIFISERVERVTCP_H_
|
||||||
|
|
||||||
|
#include "csocketserverfunctionvtcp.h"
|
||||||
|
#include "cwifiserver.h"
|
||||||
|
|
||||||
|
class CWifiServerVTCP : public CWifiServer, public CSocketServerFunctionVTCP
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
CWifiServerVTCP(CListInfo<CInfoSocket>* infoSockets, CListInfo<CInfoWifi>* infoWifis, CListInfo<CInfoWifi>* infoWifisDeconnected);
|
||||||
|
|
||||||
|
private :
|
||||||
|
|
||||||
|
bool _Listen(TDescriptor& master, TPort port) override;
|
||||||
|
|
||||||
|
TDescriptor _Accept(TDescriptor master, TCID& cid) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,107 @@
|
|||||||
|
#include "cwirelessdevice.h"
|
||||||
|
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <net/if_arp.h>
|
||||||
|
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
|
#include <regex>
|
||||||
|
|
||||||
|
const std::regex wlan("wlan[0-9]*");
|
||||||
|
|
||||||
|
WirelessDevice::WirelessDevice(){
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
WirelessDevice::~WirelessDevice(){
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
WirelessDevice::WirelessDevice(const std::string & name,int index ,int iftype ,const struct ether_addr & macaddr,int txpower):_name(name),_index(index),_iftype(iftype), _txpower(txpower), _macaddr(macaddr), _machwsim(macaddr) {
|
||||||
|
|
||||||
|
// _machwsim.ether_addr_octet[0] |= 0x40 ;
|
||||||
|
|
||||||
|
// std::memcpy(&_macaddr,&macaddr,ETH_ALEN);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
WirelessDevice::WirelessDevice(const std::string & name,int index ,int iftype ,const struct ether_addr & macaddr,const struct ether_addr & machwsim,int txpower):_name(name),_index(index),_iftype(iftype), _txpower(txpower), _macaddr(macaddr), _machwsim(machwsim) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string WirelessDevice::getName() const {
|
||||||
|
|
||||||
|
return _name ;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ether_addr WirelessDevice::getMacaddr() const {
|
||||||
|
|
||||||
|
return _macaddr ;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void WirelessDevice::setMachwsim(const struct ether_addr & machwsim) {
|
||||||
|
|
||||||
|
_machwsim = machwsim ;
|
||||||
|
// std::memcpy(&_macaddr,&macaddr,ETH_ALEN);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ether_addr WirelessDevice::getMachwsim() const {
|
||||||
|
|
||||||
|
return _machwsim ;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WirelessDevice::checkif_wireless_device(){
|
||||||
|
|
||||||
|
if (std::regex_match(_name,wlan))
|
||||||
|
return true ;
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int WirelessDevice::getIndex() const {
|
||||||
|
|
||||||
|
return _index ;
|
||||||
|
}
|
||||||
|
|
||||||
|
int WirelessDevice::getTxPower() const {
|
||||||
|
|
||||||
|
return _txpower ;
|
||||||
|
}
|
||||||
|
|
||||||
|
// friend functions
|
||||||
|
|
||||||
|
std::ostream & operator<< ( std::ostream & os , const WirelessDevice & wdevice ){
|
||||||
|
|
||||||
|
char macstring[18];
|
||||||
|
char machwsimstring[18];
|
||||||
|
|
||||||
|
sprintf(macstring, "%02X:%02X:%02X:%02X:%02X:%02X",
|
||||||
|
wdevice._macaddr.ether_addr_octet[0], wdevice._macaddr.ether_addr_octet[1], wdevice._macaddr.ether_addr_octet[2],
|
||||||
|
wdevice._macaddr.ether_addr_octet[3], wdevice._macaddr.ether_addr_octet[4], wdevice._macaddr.ether_addr_octet[5]);
|
||||||
|
|
||||||
|
sprintf(machwsimstring, "%02X:%02X:%02X:%02X:%02X:%02X",
|
||||||
|
wdevice._machwsim.ether_addr_octet[0], wdevice._machwsim.ether_addr_octet[1], wdevice._machwsim.ether_addr_octet[2],
|
||||||
|
wdevice._machwsim.ether_addr_octet[3], wdevice._machwsim.ether_addr_octet[4], wdevice._machwsim.ether_addr_octet[5]);
|
||||||
|
|
||||||
|
os << "name: " << wdevice._name << std::endl ;
|
||||||
|
|
||||||
|
os << "index: " << wdevice._index << std::endl ;
|
||||||
|
|
||||||
|
/* ARPHRD_ETHER normal, ARPHRD_IEEE80211_RADIOTAP as monitor */
|
||||||
|
if (wdevice._iftype == ARPHRD_ETHER)
|
||||||
|
os << "iftype: ARPHRD_ETHER" << std::endl ;
|
||||||
|
else if (wdevice._iftype == ARPHRD_IEEE80211_RADIOTAP)
|
||||||
|
os << "iftype: ARPHRD_IEEE80211_RADIOTAP" << std::endl;
|
||||||
|
else
|
||||||
|
os << "iftype: UNKNOWN" << std::endl;
|
||||||
|
|
||||||
|
os << "mac:" << macstring << std::endl ;
|
||||||
|
|
||||||
|
os << "mac hwsim:" << machwsimstring << std::endl ;
|
||||||
|
|
||||||
|
os << "Tx-Power : " << wdevice._txpower / 100 << "." << wdevice._txpower % 100 << "dBm" << std::endl ;
|
||||||
|
|
||||||
|
return os ;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,60 @@
|
|||||||
|
#ifndef _WIRELESSDEVICE_H
|
||||||
|
#define _WIRELESSDEVICE_H
|
||||||
|
|
||||||
|
#include <net/ethernet.h>
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
class WirelessDevice {
|
||||||
|
|
||||||
|
std::string _name;
|
||||||
|
int _index;
|
||||||
|
int _iftype;
|
||||||
|
//unsigned char _macaddr[ETH_ALEN];
|
||||||
|
int _txpower ;
|
||||||
|
struct ether_addr _macaddr ;
|
||||||
|
struct ether_addr _machwsim = {0x00,0X00,0x00,0X00,0x00,0X00};
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
WirelessDevice();
|
||||||
|
~WirelessDevice();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \fn WirelessDevice(std::string n,int i,int t,const struct ether_addr & m,const struct ether_addr & h);
|
||||||
|
* \biref Constructor
|
||||||
|
* \param n - interface name
|
||||||
|
* i - index
|
||||||
|
* t - type
|
||||||
|
* m - wireless net device mac address
|
||||||
|
* h - wireless net device mac address in hwsim driver
|
||||||
|
*/
|
||||||
|
WirelessDevice(const std::string &,int,int,const struct ether_addr &,const struct ether_addr &,int);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \fn WirelessDevice(std::string n,int i,int t,const struct ether_addr & m);
|
||||||
|
* \biref Constructor
|
||||||
|
* \param n - interface name
|
||||||
|
* i - index
|
||||||
|
* t - type
|
||||||
|
* m - wireless net device mac address
|
||||||
|
*/
|
||||||
|
WirelessDevice(const std::string &,int,int,const struct ether_addr &,int);
|
||||||
|
|
||||||
|
friend std::ostream & operator<< ( std::ostream & , const WirelessDevice &);
|
||||||
|
|
||||||
|
struct ether_addr getMacaddr() const ;
|
||||||
|
struct ether_addr getMachwsim() const ;
|
||||||
|
|
||||||
|
void setMachwsim(const struct ether_addr &);
|
||||||
|
|
||||||
|
std::string getName() const ;
|
||||||
|
|
||||||
|
bool checkif_wireless_device();
|
||||||
|
int getIndex() const ;
|
||||||
|
int getTxPower() const ;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,102 @@
|
|||||||
|
/**
|
||||||
|
* \file cwirelessdevicelist.cc
|
||||||
|
* \brief manage std::list of WirelessDevice objects
|
||||||
|
* \author
|
||||||
|
* \version
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "cwirelessdevicelist.h"
|
||||||
|
#include <cstring>
|
||||||
|
#include <algorithm> // std::transform
|
||||||
|
|
||||||
|
WirelessDeviceList::WirelessDeviceList(){
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
WirelessDeviceList::~WirelessDeviceList(){
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WirelessDeviceList::get_device_by_mac(WirelessDevice & wdev , struct ether_addr macaddr) {
|
||||||
|
|
||||||
|
_listaccess.lock();
|
||||||
|
for (auto & wd : _wdevices_list){
|
||||||
|
|
||||||
|
struct ether_addr mac = wd.second.getMacaddr() ;
|
||||||
|
if(std::memcmp(&mac,&macaddr,ETH_ALEN) == 0){
|
||||||
|
wdev = wd.second ;
|
||||||
|
_listaccess.unlock();
|
||||||
|
return true ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_listaccess.unlock();
|
||||||
|
|
||||||
|
return false ;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WirelessDeviceList::add_device(const WirelessDevice & wdevice){
|
||||||
|
|
||||||
|
_listaccess.lock();
|
||||||
|
|
||||||
|
_wdevices_list[wdevice.getIndex()] = wdevice ;
|
||||||
|
|
||||||
|
_listaccess.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
void WirelessDeviceList::delete_device(const WirelessDevice & wdevice){
|
||||||
|
|
||||||
|
_listaccess.lock();
|
||||||
|
|
||||||
|
_wdevices_list.erase(wdevice.getIndex()) ;
|
||||||
|
|
||||||
|
_listaccess.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
void WirelessDeviceList::delete_device(int index){
|
||||||
|
|
||||||
|
_listaccess.lock();
|
||||||
|
|
||||||
|
_wdevices_list.erase(index);
|
||||||
|
|
||||||
|
_listaccess.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<WirelessDevice> & WirelessDeviceList::list_devices() {
|
||||||
|
|
||||||
|
std::vector<WirelessDevice> * list_wd = new std::vector<WirelessDevice>();
|
||||||
|
list_wd->reserve(_wdevices_list.size());
|
||||||
|
|
||||||
|
_listaccess.lock();
|
||||||
|
|
||||||
|
std::transform (_wdevices_list.begin(),
|
||||||
|
_wdevices_list.end(),
|
||||||
|
back_inserter(*list_wd),
|
||||||
|
[] (std::pair<int, WirelessDevice> const & pair)
|
||||||
|
{
|
||||||
|
return pair.second;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
_listaccess.unlock();
|
||||||
|
|
||||||
|
return *(list_wd) ;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/** friend functions */
|
||||||
|
|
||||||
|
std::ostream & operator<< ( std::ostream & os , WirelessDeviceList & wdlist ){
|
||||||
|
|
||||||
|
wdlist._listaccess.lock();
|
||||||
|
|
||||||
|
for (const auto & wd : wdlist._wdevices_list){
|
||||||
|
|
||||||
|
os << wd.second;
|
||||||
|
os << std::endl ;
|
||||||
|
}
|
||||||
|
|
||||||
|
wdlist._listaccess.unlock();
|
||||||
|
|
||||||
|
return os ;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,85 @@
|
|||||||
|
/**
|
||||||
|
* \file cwirelessdevicelist.h
|
||||||
|
* \brief manage std::list of WirelessDevice objects
|
||||||
|
* \author
|
||||||
|
* \version
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _CWIRELESSDEVICELIST_H_
|
||||||
|
#define _CWIRELESSDEVICELIST_H_
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
#include <mutex>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "cwirelessdevice.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \class WirelessDeviceList
|
||||||
|
* \brief This class represents a std::list of WirelessDevice objects
|
||||||
|
*/
|
||||||
|
class WirelessDeviceList {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief manage threads access to wdevices_list
|
||||||
|
*/
|
||||||
|
std::mutex _listaccess ;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief list of existing wireless network interfaces
|
||||||
|
*/
|
||||||
|
std::map<int,WirelessDevice> _wdevices_list;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
WirelessDeviceList();
|
||||||
|
~WirelessDeviceList();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \fn add_device(int)
|
||||||
|
* \brief Add to _wdevices_list a wireless network device
|
||||||
|
* \param wdevice Wireless network device
|
||||||
|
* \return void
|
||||||
|
*/
|
||||||
|
void add_device(const WirelessDevice & wdevice);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \fn delete_device(int)
|
||||||
|
* \brief Remove from _wdevice_list a wireless network device by index
|
||||||
|
* \param index Ifindex of wireless network device
|
||||||
|
* \return void
|
||||||
|
*/
|
||||||
|
void delete_device(int index);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \fn delete_device(const WirelessDevice & wdevice)
|
||||||
|
* \brief Remove from _wdevice_list a wireless network device by index
|
||||||
|
* \param wdevice wireless network device to remove from _wdevices_list
|
||||||
|
* \return void
|
||||||
|
*/
|
||||||
|
void delete_device(const WirelessDevice & wdevice);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \fn list_devices()
|
||||||
|
* \brief Get a list of all wireless network devices
|
||||||
|
* \return std::vector List of all devices
|
||||||
|
*/
|
||||||
|
std::vector<WirelessDevice> & list_devices() ;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \fn get_device_by_mac(struct ether_addr macaddr)
|
||||||
|
* \brief Get a device related to mac address
|
||||||
|
* \param wdev : WirelessDevice to find
|
||||||
|
* \param macaddr : mac address to find
|
||||||
|
* \return true if found and false otherwise
|
||||||
|
*/
|
||||||
|
bool get_device_by_mac(WirelessDevice & wdev , struct ether_addr macaddr);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief << operator overidden
|
||||||
|
*/
|
||||||
|
friend std::ostream & operator<< ( std::ostream & , WirelessDeviceList &);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
+16
@@ -0,0 +1,16 @@
|
|||||||
|
#ifndef _HWSIM_H_
|
||||||
|
#define _HWSIM_H_
|
||||||
|
|
||||||
|
#include "types.h"
|
||||||
|
|
||||||
|
#define __packed __attribute__((packed))
|
||||||
|
|
||||||
|
#define BIT(x) (1 << (x))
|
||||||
|
|
||||||
|
#include "mac80211_hwsim.h"
|
||||||
|
|
||||||
|
#define VERSION_NR 1
|
||||||
|
|
||||||
|
#endif /* _HWSIM_H_ */
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
#ifndef IEEE80211_H_
|
||||||
|
#define IEEE80211_H_
|
||||||
|
|
||||||
|
// From Kernel : include/net/mac80211.h
|
||||||
|
#define IEEE80211_TX_MAX_RATES 4
|
||||||
|
|
||||||
|
#endif /* IEEE80211_H_ */
|
||||||
|
|
||||||
@@ -0,0 +1,344 @@
|
|||||||
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
|
/*
|
||||||
|
* mac80211_hwsim - software simulator of 802.11 radio(s) for mac80211
|
||||||
|
* Copyright (c) 2008, Jouni Malinen <j@w1.fi>
|
||||||
|
* Copyright (c) 2011, Javier Lopez <jlopex@gmail.com>
|
||||||
|
* Copyright (C) 2020, 2022-2024 Intel Corporation
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __MAC80211_HWSIM_H
|
||||||
|
#define __MAC80211_HWSIM_H
|
||||||
|
|
||||||
|
/**
|
||||||
|
* enum hwsim_tx_control_flags - flags to describe transmission info/status
|
||||||
|
*
|
||||||
|
* These flags are used to give the wmediumd extra information in order to
|
||||||
|
* modify its behavior for each frame
|
||||||
|
*
|
||||||
|
* @HWSIM_TX_CTL_REQ_TX_STATUS: require TX status callback for this frame.
|
||||||
|
* @HWSIM_TX_CTL_NO_ACK: tell the wmediumd not to wait for an ack
|
||||||
|
* @HWSIM_TX_STAT_ACK: Frame was acknowledged
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
enum hwsim_tx_control_flags {
|
||||||
|
HWSIM_TX_CTL_REQ_TX_STATUS = BIT(0),
|
||||||
|
HWSIM_TX_CTL_NO_ACK = BIT(1),
|
||||||
|
HWSIM_TX_STAT_ACK = BIT(2),
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DOC: Frame transmission/registration support
|
||||||
|
*
|
||||||
|
* Frame transmission and registration support exists to allow userspace
|
||||||
|
* entities such as wmediumd to receive and process all broadcasted
|
||||||
|
* frames from a mac80211_hwsim radio device.
|
||||||
|
*
|
||||||
|
* This allow user space applications to decide if the frame should be
|
||||||
|
* dropped or not and implement a wireless medium simulator at user space.
|
||||||
|
*
|
||||||
|
* Registration is done by sending a register message to the driver and
|
||||||
|
* will be automatically unregistered if the user application doesn't
|
||||||
|
* responds to sent frames.
|
||||||
|
* Once registered the user application has to take responsibility of
|
||||||
|
* broadcasting the frames to all listening mac80211_hwsim radio
|
||||||
|
* interfaces.
|
||||||
|
*
|
||||||
|
* For more technical details, see the corresponding command descriptions
|
||||||
|
* below.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* enum hwsim_commands - supported hwsim commands
|
||||||
|
*
|
||||||
|
* @HWSIM_CMD_UNSPEC: unspecified command to catch errors
|
||||||
|
*
|
||||||
|
* @HWSIM_CMD_REGISTER: request to register and received all broadcasted
|
||||||
|
* frames by any mac80211_hwsim radio device.
|
||||||
|
* @HWSIM_CMD_FRAME: send/receive a broadcasted frame from/to kernel/user
|
||||||
|
* space, uses:
|
||||||
|
* %HWSIM_ATTR_ADDR_TRANSMITTER, %HWSIM_ATTR_ADDR_RECEIVER,
|
||||||
|
* %HWSIM_ATTR_FRAME, %HWSIM_ATTR_FLAGS, %HWSIM_ATTR_RX_RATE,
|
||||||
|
* %HWSIM_ATTR_SIGNAL, %HWSIM_ATTR_COOKIE, %HWSIM_ATTR_FREQ (optional)
|
||||||
|
* @HWSIM_CMD_TX_INFO_FRAME: Transmission info report from user space to
|
||||||
|
* kernel, uses:
|
||||||
|
* %HWSIM_ATTR_ADDR_TRANSMITTER, %HWSIM_ATTR_FLAGS,
|
||||||
|
* %HWSIM_ATTR_TX_INFO, %WSIM_ATTR_TX_INFO_FLAGS,
|
||||||
|
* %HWSIM_ATTR_SIGNAL, %HWSIM_ATTR_COOKIE
|
||||||
|
* @HWSIM_CMD_NEW_RADIO: create a new radio with the given parameters,
|
||||||
|
* returns the radio ID (>= 0) or negative on errors, if successful
|
||||||
|
* then multicast the result, uses optional parameter:
|
||||||
|
* %HWSIM_ATTR_REG_STRICT_REG, %HWSIM_ATTR_SUPPORT_P2P_DEVICE,
|
||||||
|
* %HWSIM_ATTR_DESTROY_RADIO_ON_CLOSE, %HWSIM_ATTR_CHANNELS,
|
||||||
|
* %HWSIM_ATTR_NO_VIF, %HWSIM_ATTR_RADIO_NAME, %HWSIM_ATTR_USE_CHANCTX,
|
||||||
|
* %HWSIM_ATTR_REG_HINT_ALPHA2, %HWSIM_ATTR_REG_CUSTOM_REG,
|
||||||
|
* %HWSIM_ATTR_PERM_ADDR
|
||||||
|
* @HWSIM_CMD_DEL_RADIO: destroy a radio, reply is multicasted
|
||||||
|
* @HWSIM_CMD_GET_RADIO: fetch information about existing radios, uses:
|
||||||
|
* %HWSIM_ATTR_RADIO_ID
|
||||||
|
* @HWSIM_CMD_ADD_MAC_ADDR: add a receive MAC address (given in the
|
||||||
|
* %HWSIM_ATTR_ADDR_RECEIVER attribute) to a device identified by
|
||||||
|
* %HWSIM_ATTR_ADDR_TRANSMITTER. This lets wmediumd forward frames
|
||||||
|
* to this receiver address for a given station.
|
||||||
|
* @HWSIM_CMD_DEL_MAC_ADDR: remove the MAC address again, the attributes
|
||||||
|
* are the same as to @HWSIM_CMD_ADD_MAC_ADDR.
|
||||||
|
* @HWSIM_CMD_START_PMSR: request to start peer measurement with the
|
||||||
|
* %HWSIM_ATTR_PMSR_REQUEST. Result will be sent back asynchronously
|
||||||
|
* with %HWSIM_CMD_REPORT_PMSR.
|
||||||
|
* @HWSIM_CMD_ABORT_PMSR: Abort previously started peer measurement.
|
||||||
|
* @HWSIM_CMD_REPORT_PMSR: Report peer measurement data.
|
||||||
|
* @__HWSIM_CMD_MAX: enum limit
|
||||||
|
*/
|
||||||
|
enum hwsim_commands {
|
||||||
|
HWSIM_CMD_UNSPEC,
|
||||||
|
HWSIM_CMD_REGISTER,
|
||||||
|
HWSIM_CMD_FRAME,
|
||||||
|
HWSIM_CMD_TX_INFO_FRAME,
|
||||||
|
HWSIM_CMD_NEW_RADIO,
|
||||||
|
HWSIM_CMD_DEL_RADIO,
|
||||||
|
HWSIM_CMD_GET_RADIO,
|
||||||
|
HWSIM_CMD_ADD_MAC_ADDR,
|
||||||
|
HWSIM_CMD_DEL_MAC_ADDR,
|
||||||
|
HWSIM_CMD_START_PMSR,
|
||||||
|
HWSIM_CMD_ABORT_PMSR,
|
||||||
|
HWSIM_CMD_REPORT_PMSR,
|
||||||
|
__HWSIM_CMD_MAX,
|
||||||
|
};
|
||||||
|
#define HWSIM_CMD_MAX (_HWSIM_CMD_MAX - 1)
|
||||||
|
|
||||||
|
#define HWSIM_CMD_CREATE_RADIO HWSIM_CMD_NEW_RADIO
|
||||||
|
#define HWSIM_CMD_DESTROY_RADIO HWSIM_CMD_DEL_RADIO
|
||||||
|
|
||||||
|
/**
|
||||||
|
* enum hwsim_attrs - hwsim netlink attributes
|
||||||
|
*
|
||||||
|
* @HWSIM_ATTR_UNSPEC: unspecified attribute to catch errors
|
||||||
|
*
|
||||||
|
* @HWSIM_ATTR_ADDR_RECEIVER: MAC address of the radio device that
|
||||||
|
* the frame is broadcasted to
|
||||||
|
* @HWSIM_ATTR_ADDR_TRANSMITTER: MAC address of the radio device that
|
||||||
|
* the frame was broadcasted from
|
||||||
|
* @HWSIM_ATTR_FRAME: Data array
|
||||||
|
* @HWSIM_ATTR_FLAGS: mac80211 transmission flags, used to process
|
||||||
|
* properly the frame at user space
|
||||||
|
* @HWSIM_ATTR_RX_RATE: estimated rx rate index for this frame at user
|
||||||
|
* space
|
||||||
|
* @HWSIM_ATTR_SIGNAL: estimated RX signal for this frame at user
|
||||||
|
* space
|
||||||
|
* @HWSIM_ATTR_TX_INFO: ieee80211_tx_rate array
|
||||||
|
* @HWSIM_ATTR_COOKIE: sk_buff cookie to identify the frame
|
||||||
|
* @HWSIM_ATTR_CHANNELS: u32 attribute used with the %HWSIM_CMD_CREATE_RADIO
|
||||||
|
* command giving the number of channels supported by the new radio
|
||||||
|
* @HWSIM_ATTR_RADIO_ID: u32 attribute used with %HWSIM_CMD_DESTROY_RADIO
|
||||||
|
* only to destroy a radio
|
||||||
|
* @HWSIM_ATTR_REG_HINT_ALPHA2: alpha2 for regulatoro driver hint
|
||||||
|
* (nla string, length 2)
|
||||||
|
* @HWSIM_ATTR_REG_CUSTOM_REG: custom regulatory domain index (u32 attribute)
|
||||||
|
* @HWSIM_ATTR_REG_STRICT_REG: request REGULATORY_STRICT_REG (flag attribute)
|
||||||
|
* @HWSIM_ATTR_SUPPORT_P2P_DEVICE: support P2P Device virtual interface (flag)
|
||||||
|
* @HWSIM_ATTR_USE_CHANCTX: used with the %HWSIM_CMD_CREATE_RADIO
|
||||||
|
* command to force use of channel contexts even when only a
|
||||||
|
* single channel is supported
|
||||||
|
* @HWSIM_ATTR_DESTROY_RADIO_ON_CLOSE: used with the %HWSIM_CMD_CREATE_RADIO
|
||||||
|
* command to force radio removal when process that created the radio dies
|
||||||
|
* @HWSIM_ATTR_RADIO_NAME: Name of radio, e.g. phy666
|
||||||
|
* @HWSIM_ATTR_NO_VIF: Do not create vif (wlanX) when creating radio.
|
||||||
|
* @HWSIM_ATTR_PAD: padding attribute for 64-bit values, ignore
|
||||||
|
* @HWSIM_ATTR_FREQ: Frequency at which packet is transmitted or received.
|
||||||
|
* @HWSIM_ATTR_TX_INFO_FLAGS: additional flags for corresponding
|
||||||
|
* rates of %HWSIM_ATTR_TX_INFO
|
||||||
|
* @HWSIM_ATTR_PERM_ADDR: permanent mac address of new radio
|
||||||
|
* @HWSIM_ATTR_IFTYPE_SUPPORT: u32 attribute of supported interface types bits
|
||||||
|
* @HWSIM_ATTR_CIPHER_SUPPORT: u32 array of supported cipher types
|
||||||
|
* @HWSIM_ATTR_MLO_SUPPORT: claim MLO support (exact parameters TBD) for
|
||||||
|
* the new radio
|
||||||
|
* @HWSIM_ATTR_PMSR_SUPPORT: nested attribute used with %HWSIM_CMD_CREATE_RADIO
|
||||||
|
* to provide peer measurement capabilities. (nl80211_peer_measurement_attrs)
|
||||||
|
* @HWSIM_ATTR_PMSR_REQUEST: nested attribute used with %HWSIM_CMD_START_PMSR
|
||||||
|
* to provide details about peer measurement request (nl80211_peer_measurement_attrs)
|
||||||
|
* @HWSIM_ATTR_PMSR_RESULT: nested attributed used with %HWSIM_CMD_REPORT_PMSR
|
||||||
|
* to provide peer measurement result (nl80211_peer_measurement_attrs)
|
||||||
|
* @HWSIM_ATTR_MULTI_RADIO: Register multiple wiphy radios (flag).
|
||||||
|
* Adds one radio for each band. Number of supported channels will be set for
|
||||||
|
* each radio instead of for the wiphy.
|
||||||
|
* @__HWSIM_ATTR_MAX: enum limit
|
||||||
|
*/
|
||||||
|
enum hwsim_attrs {
|
||||||
|
HWSIM_ATTR_UNSPEC,
|
||||||
|
HWSIM_ATTR_ADDR_RECEIVER,
|
||||||
|
HWSIM_ATTR_ADDR_TRANSMITTER,
|
||||||
|
HWSIM_ATTR_FRAME,
|
||||||
|
HWSIM_ATTR_FLAGS,
|
||||||
|
HWSIM_ATTR_RX_RATE,
|
||||||
|
HWSIM_ATTR_SIGNAL,
|
||||||
|
HWSIM_ATTR_TX_INFO,
|
||||||
|
HWSIM_ATTR_COOKIE,
|
||||||
|
HWSIM_ATTR_CHANNELS,
|
||||||
|
HWSIM_ATTR_RADIO_ID,
|
||||||
|
HWSIM_ATTR_REG_HINT_ALPHA2,
|
||||||
|
HWSIM_ATTR_REG_CUSTOM_REG,
|
||||||
|
HWSIM_ATTR_REG_STRICT_REG,
|
||||||
|
HWSIM_ATTR_SUPPORT_P2P_DEVICE,
|
||||||
|
HWSIM_ATTR_USE_CHANCTX,
|
||||||
|
HWSIM_ATTR_DESTROY_RADIO_ON_CLOSE,
|
||||||
|
HWSIM_ATTR_RADIO_NAME,
|
||||||
|
HWSIM_ATTR_NO_VIF,
|
||||||
|
HWSIM_ATTR_FREQ,
|
||||||
|
HWSIM_ATTR_PAD,
|
||||||
|
HWSIM_ATTR_TX_INFO_FLAGS,
|
||||||
|
HWSIM_ATTR_PERM_ADDR,
|
||||||
|
HWSIM_ATTR_IFTYPE_SUPPORT,
|
||||||
|
HWSIM_ATTR_CIPHER_SUPPORT,
|
||||||
|
HWSIM_ATTR_MLO_SUPPORT,
|
||||||
|
HWSIM_ATTR_PMSR_SUPPORT,
|
||||||
|
HWSIM_ATTR_PMSR_REQUEST,
|
||||||
|
HWSIM_ATTR_PMSR_RESULT,
|
||||||
|
HWSIM_ATTR_MULTI_RADIO,
|
||||||
|
__HWSIM_ATTR_MAX,
|
||||||
|
};
|
||||||
|
#define HWSIM_ATTR_MAX (__HWSIM_ATTR_MAX - 1)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct hwsim_tx_rate - rate selection/status
|
||||||
|
*
|
||||||
|
* @idx: rate index to attempt to send with
|
||||||
|
* @count: number of tries in this rate before going to the next rate
|
||||||
|
*
|
||||||
|
* A value of -1 for @idx indicates an invalid rate and, if used
|
||||||
|
* in an array of retry rates, that no more rates should be tried.
|
||||||
|
*
|
||||||
|
* When used for transmit status reporting, the driver should
|
||||||
|
* always report the rate and number of retries used.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
struct hwsim_tx_rate {
|
||||||
|
s8 idx;
|
||||||
|
u8 count;
|
||||||
|
} __packed;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* enum hwsim_tx_rate_flags - per-rate flags set by the rate control algorithm.
|
||||||
|
* Inspired by structure mac80211_rate_control_flags. New flags may be
|
||||||
|
* appended, but old flags not deleted, to keep compatibility for
|
||||||
|
* userspace.
|
||||||
|
*
|
||||||
|
* These flags are set by the Rate control algorithm for each rate during tx,
|
||||||
|
* in the @flags member of struct ieee80211_tx_rate.
|
||||||
|
*
|
||||||
|
* @MAC80211_HWSIM_TX_RC_USE_RTS_CTS: Use RTS/CTS exchange for this rate.
|
||||||
|
* @MAC80211_HWSIM_TX_RC_USE_CTS_PROTECT: CTS-to-self protection is required.
|
||||||
|
* This is set if the current BSS requires ERP protection.
|
||||||
|
* @MAC80211_HWSIM_TX_RC_USE_SHORT_PREAMBLE: Use short preamble.
|
||||||
|
* @MAC80211_HWSIM_TX_RC_MCS: HT rate.
|
||||||
|
* @MAC80211_HWSIM_TX_RC_VHT_MCS: VHT MCS rate, in this case the idx field is
|
||||||
|
* split into a higher 4 bits (Nss) and lower 4 bits (MCS number)
|
||||||
|
* @MAC80211_HWSIM_TX_RC_GREEN_FIELD: Indicates whether this rate should be used
|
||||||
|
* in Greenfield mode.
|
||||||
|
* @MAC80211_HWSIM_TX_RC_40_MHZ_WIDTH: Indicates if the Channel Width should be
|
||||||
|
* 40 MHz.
|
||||||
|
* @MAC80211_HWSIM_TX_RC_80_MHZ_WIDTH: Indicates 80 MHz transmission
|
||||||
|
* @MAC80211_HWSIM_TX_RC_160_MHZ_WIDTH: Indicates 160 MHz transmission
|
||||||
|
* (80+80 isn't supported yet)
|
||||||
|
* @MAC80211_HWSIM_TX_RC_DUP_DATA: The frame should be transmitted on both of
|
||||||
|
* the adjacent 20 MHz channels, if the current channel type is
|
||||||
|
* NL80211_CHAN_HT40MINUS or NL80211_CHAN_HT40PLUS.
|
||||||
|
* @MAC80211_HWSIM_TX_RC_SHORT_GI: Short Guard interval should be used for this
|
||||||
|
* rate.
|
||||||
|
*/
|
||||||
|
enum hwsim_tx_rate_flags {
|
||||||
|
MAC80211_HWSIM_TX_RC_USE_RTS_CTS = BIT(0),
|
||||||
|
MAC80211_HWSIM_TX_RC_USE_CTS_PROTECT = BIT(1),
|
||||||
|
MAC80211_HWSIM_TX_RC_USE_SHORT_PREAMBLE = BIT(2),
|
||||||
|
|
||||||
|
/* rate index is an HT/VHT MCS instead of an index */
|
||||||
|
MAC80211_HWSIM_TX_RC_MCS = BIT(3),
|
||||||
|
MAC80211_HWSIM_TX_RC_GREEN_FIELD = BIT(4),
|
||||||
|
MAC80211_HWSIM_TX_RC_40_MHZ_WIDTH = BIT(5),
|
||||||
|
MAC80211_HWSIM_TX_RC_DUP_DATA = BIT(6),
|
||||||
|
MAC80211_HWSIM_TX_RC_SHORT_GI = BIT(7),
|
||||||
|
MAC80211_HWSIM_TX_RC_VHT_MCS = BIT(8),
|
||||||
|
MAC80211_HWSIM_TX_RC_80_MHZ_WIDTH = BIT(9),
|
||||||
|
MAC80211_HWSIM_TX_RC_160_MHZ_WIDTH = BIT(10),
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct hwsim_tx_rate_flag - rate selection/status
|
||||||
|
*
|
||||||
|
* @idx: rate index to attempt to send with
|
||||||
|
* @flags: the rate flags according to &enum hwsim_tx_rate_flags
|
||||||
|
*
|
||||||
|
* A value of -1 for @idx indicates an invalid rate and, if used
|
||||||
|
* in an array of retry rates, that no more rates should be tried.
|
||||||
|
*
|
||||||
|
* When used for transmit status reporting, the driver should
|
||||||
|
* always report the rate and number of retries used.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
struct hwsim_tx_rate_flag {
|
||||||
|
s8 idx;
|
||||||
|
u16 flags;
|
||||||
|
} __packed;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DOC: Frame transmission support over virtio
|
||||||
|
*
|
||||||
|
* Frame transmission is also supported over virtio to allow communication
|
||||||
|
* with external entities.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* enum hwsim_vqs - queues for virtio frame transmission
|
||||||
|
*
|
||||||
|
* @HWSIM_VQ_TX: send frames to external entity
|
||||||
|
* @HWSIM_VQ_RX: receive frames and transmission info reports
|
||||||
|
* @HWSIM_NUM_VQS: enum limit
|
||||||
|
*/
|
||||||
|
enum hwsim_vqs {
|
||||||
|
HWSIM_VQ_TX,
|
||||||
|
HWSIM_VQ_RX,
|
||||||
|
HWSIM_NUM_VQS,
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* enum hwsim_rate_info_attributes - bitrate information.
|
||||||
|
*
|
||||||
|
* Information about a receiving or transmitting bitrate
|
||||||
|
* that can be mapped to struct rate_info
|
||||||
|
*
|
||||||
|
* @__HWSIM_RATE_INFO_ATTR_INVALID: reserved, netlink attribute 0 is invalid
|
||||||
|
* @HWSIM_RATE_INFO_ATTR_FLAGS: bitflag of flags from &enum rate_info_flags
|
||||||
|
* @HWSIM_RATE_INFO_ATTR_MCS: mcs index if struct describes an HT/VHT/HE rate
|
||||||
|
* @HWSIM_RATE_INFO_ATTR_LEGACY: bitrate in 100kbit/s for 802.11abg
|
||||||
|
* @HWSIM_RATE_INFO_ATTR_NSS: number of streams (VHT & HE only)
|
||||||
|
* @HWSIM_RATE_INFO_ATTR_BW: bandwidth (from &enum rate_info_bw)
|
||||||
|
* @HWSIM_RATE_INFO_ATTR_HE_GI: HE guard interval (from &enum nl80211_he_gi)
|
||||||
|
* @HWSIM_RATE_INFO_ATTR_HE_DCM: HE DCM value
|
||||||
|
* @HWSIM_RATE_INFO_ATTR_HE_RU_ALLOC: HE RU allocation (from &enum nl80211_he_ru_alloc,
|
||||||
|
* only valid if bw is %RATE_INFO_BW_HE_RU)
|
||||||
|
* @HWSIM_RATE_INFO_ATTR_N_BOUNDED_CH: In case of EDMG the number of bonded channels (1-4)
|
||||||
|
* @HWSIM_RATE_INFO_ATTR_EHT_GI: EHT guard interval (from &enum nl80211_eht_gi)
|
||||||
|
* @HWSIM_RATE_INFO_ATTR_EHT_RU_ALLOC: EHT RU allocation (from &enum nl80211_eht_ru_alloc,
|
||||||
|
* only valid if bw is %RATE_INFO_BW_EHT_RU)
|
||||||
|
* @NUM_HWSIM_RATE_INFO_ATTRS: internal
|
||||||
|
* @HWSIM_RATE_INFO_ATTR_MAX: highest attribute number
|
||||||
|
*/
|
||||||
|
enum hwsim_rate_info_attributes {
|
||||||
|
__HWSIM_RATE_INFO_ATTR_INVALID,
|
||||||
|
|
||||||
|
HWSIM_RATE_INFO_ATTR_FLAGS,
|
||||||
|
HWSIM_RATE_INFO_ATTR_MCS,
|
||||||
|
HWSIM_RATE_INFO_ATTR_LEGACY,
|
||||||
|
HWSIM_RATE_INFO_ATTR_NSS,
|
||||||
|
HWSIM_RATE_INFO_ATTR_BW,
|
||||||
|
HWSIM_RATE_INFO_ATTR_HE_GI,
|
||||||
|
HWSIM_RATE_INFO_ATTR_HE_DCM,
|
||||||
|
HWSIM_RATE_INFO_ATTR_HE_RU_ALLOC,
|
||||||
|
HWSIM_RATE_INFO_ATTR_N_BOUNDED_CH,
|
||||||
|
HWSIM_RATE_INFO_ATTR_EHT_GI,
|
||||||
|
HWSIM_RATE_INFO_ATTR_EHT_RU_ALLOC,
|
||||||
|
|
||||||
|
/* keep last */
|
||||||
|
NUM_HWSIM_RATE_INFO_ATTRS,
|
||||||
|
HWSIM_RATE_INFO_ATTR_MAX = NUM_HWSIM_RATE_INFO_ATTRS - 1
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* __MAC80211_HWSIM_H */
|
||||||
@@ -0,0 +1,71 @@
|
|||||||
|
#include <cstddef> // NULL
|
||||||
|
#include <arpa/inet.h> // struct sockaddr_in & inet_ntoa & ntohs
|
||||||
|
|
||||||
|
#include "tools.h"
|
||||||
|
|
||||||
|
#include <assert.h> // assert
|
||||||
|
|
||||||
|
bool HashUsesPort=false;
|
||||||
|
|
||||||
|
unsigned long hash_ipaddr(struct sockaddr_in* addr)
|
||||||
|
{
|
||||||
|
unsigned long res;
|
||||||
|
|
||||||
|
assert( addr != NULL );
|
||||||
|
|
||||||
|
res = (((addr->sin_addr.s_addr >> 24) & 0xff) * 256) +
|
||||||
|
(((addr->sin_addr.s_addr >> 16) & 0xff) * 256) +
|
||||||
|
(((addr->sin_addr.s_addr >> 8) & 0xff)* 256) +
|
||||||
|
(addr->sin_addr.s_addr & 0xff);
|
||||||
|
|
||||||
|
if( HashUsesPort )
|
||||||
|
res += addr->sin_port;
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isInt(const char *str) {
|
||||||
|
|
||||||
|
if( *str == '-' || *str == '+' )
|
||||||
|
str++;
|
||||||
|
|
||||||
|
while (*str) {
|
||||||
|
if( *str < '0' || *str > '9' )
|
||||||
|
return false;
|
||||||
|
str++;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isPositiveInt(const char *str)
|
||||||
|
{
|
||||||
|
if( *str == '-' )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return isInt(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isIntOrFloat(const char *str) {
|
||||||
|
bool seeDot=false;
|
||||||
|
bool seeDigit=false;
|
||||||
|
|
||||||
|
if (*str == '-' || *str == '+')
|
||||||
|
str++;
|
||||||
|
|
||||||
|
while (*str) {
|
||||||
|
if( *str == '.' )
|
||||||
|
{
|
||||||
|
if( seeDot )
|
||||||
|
return false;
|
||||||
|
seeDot=true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if( *str < '0' || *str > '9' )
|
||||||
|
return false;
|
||||||
|
seeDigit=true;
|
||||||
|
}
|
||||||
|
str++;
|
||||||
|
}
|
||||||
|
return seeDigit;
|
||||||
|
}
|
||||||
+14
@@ -0,0 +1,14 @@
|
|||||||
|
#ifndef _TOOLS_H_
|
||||||
|
#define _TOOLS_H_
|
||||||
|
|
||||||
|
extern bool HashUsesPort;
|
||||||
|
|
||||||
|
unsigned long hash_ipaddr(struct sockaddr_in* addr);
|
||||||
|
|
||||||
|
bool isInt(const char *str);
|
||||||
|
|
||||||
|
bool isPositiveInt(const char *str);
|
||||||
|
|
||||||
|
bool isIntOrFloat(const char *str);
|
||||||
|
|
||||||
|
#endif
|
||||||
+54
@@ -0,0 +1,54 @@
|
|||||||
|
#ifndef _TYPES_H_
|
||||||
|
#define _TYPES_H_
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
typedef int8_t s8;
|
||||||
|
typedef uint8_t u8;
|
||||||
|
typedef uint16_t u16;
|
||||||
|
typedef uint64_t u64;
|
||||||
|
typedef int32_t s32;
|
||||||
|
typedef uint32_t u32;
|
||||||
|
|
||||||
|
// int
|
||||||
|
typedef s32 TValue;
|
||||||
|
|
||||||
|
// unsigned int
|
||||||
|
typedef u32 TCID;
|
||||||
|
|
||||||
|
enum TOrder {
|
||||||
|
TORDER_NO, TORDER_LIST, TORDER_SHOW, TORDER_CHANGE_COORDINATE, TORDER_SETNAME, TORDER_PACKET_LOSS, TORDER_STATUS, TORDER_DISTANCE_BETWEEN_CID, TORDER_SET_SCALE, TORDER_CLOSE_ALL_CLIENT
|
||||||
|
};
|
||||||
|
|
||||||
|
// int
|
||||||
|
typedef s32 TDescriptor;
|
||||||
|
|
||||||
|
// unsigned int
|
||||||
|
typedef u32 TIndex;
|
||||||
|
|
||||||
|
// int
|
||||||
|
typedef s32 TSocket;
|
||||||
|
// AF_INET : use IP
|
||||||
|
// AF_VSOCK : use vsock
|
||||||
|
|
||||||
|
// unsigned short
|
||||||
|
typedef u16 TPort;
|
||||||
|
|
||||||
|
// char
|
||||||
|
typedef s8 TPower; // empirical observed values with int : [-123,20]
|
||||||
|
const TPower TPower_MAX=-10; // dBm is always negative. -10 is an empirical value
|
||||||
|
const TPower TPower_MIN=INT8_MIN;
|
||||||
|
|
||||||
|
// double
|
||||||
|
typedef double TDistance; // in meters
|
||||||
|
typedef double TScale;
|
||||||
|
|
||||||
|
// u32
|
||||||
|
typedef u32 TFrequency; // Hz
|
||||||
|
|
||||||
|
// unsigned short
|
||||||
|
typedef u16 TMinimalSize;
|
||||||
|
|
||||||
|
typedef u8 TByte;
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,107 @@
|
|||||||
|
/*
|
||||||
|
From : https://android.googlesource.com/device/generic/goldfish/+/refs/heads/master/wifi/mac80211_create_radios/main.cpp
|
||||||
|
Licence http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <netlink/genl/ctrl.h>
|
||||||
|
#include <netlink/genl/genl.h>
|
||||||
|
#include <netlink/netlink.h>
|
||||||
|
#include <net/ethernet.h>
|
||||||
|
|
||||||
|
#include <climits>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <unistd.h> // getuid
|
||||||
|
|
||||||
|
#include "config_hwsim.h"
|
||||||
|
#include "addinterfaces.h"
|
||||||
|
#include "config.h" // DEFAULT_MAC_PREFIX
|
||||||
|
|
||||||
|
int ParseInt(const char* str, int* result)
|
||||||
|
{
|
||||||
|
return sscanf(str, "%d", result);
|
||||||
|
}
|
||||||
|
|
||||||
|
int help(FILE* dst, const int ret)
|
||||||
|
{
|
||||||
|
fprintf(dst, "%s",
|
||||||
|
"Usage:\n"
|
||||||
|
" vwifi-add-interfaces [-h] [-v] n_radios mac_prefix\n"
|
||||||
|
" vwifi-add-interfaces [--help] [--version] n_radios mac_prefix\n"
|
||||||
|
" where\n"
|
||||||
|
" n_radios - int, [1,100], e.g. 2\n"
|
||||||
|
" mac_prefix - xx:xx:xx:xx:xx (if n_radios > 1 then only the first 5 bytes are used\n"
|
||||||
|
" then all bytes are used)\n\n"
|
||||||
|
" vwifi-add-interfaces will create n_radios with MAC addresses xx:xx:xx:xx:xx:nn\n"
|
||||||
|
" where xx:xx:xx:xx:xx is the mac_prefix specified\n"
|
||||||
|
" and nn is incremented (from zero, and only if n_radios > 1)\n");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char* argv[])
|
||||||
|
{
|
||||||
|
int nRadios;
|
||||||
|
TByte macPrefix[ETH_ALEN]= {};
|
||||||
|
|
||||||
|
if( argc == 1 )
|
||||||
|
return help(stdout,0);
|
||||||
|
|
||||||
|
if( ! ParseAddress(DEFAULT_MAC_PREFIX,macPrefix) )
|
||||||
|
return help(stderr, 6);
|
||||||
|
if( strlen(DEFAULT_MAC_PREFIX) <= 8 )
|
||||||
|
{ // if possible, randomize the 4th byte
|
||||||
|
srand(time(NULL));
|
||||||
|
macPrefix[3]=rand()%100;
|
||||||
|
}
|
||||||
|
|
||||||
|
int arg_idx = 1;
|
||||||
|
int arg_used = 1;
|
||||||
|
while (arg_idx < argc)
|
||||||
|
{
|
||||||
|
if( ! strcmp("-v", argv[arg_idx]) || ! strcmp("--version", argv[arg_idx]) )
|
||||||
|
{
|
||||||
|
fprintf(stdout,"Version : %s\n",VERSION);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if( ! strcmp("-h", argv[arg_idx]) || ! strcmp("--help", argv[arg_idx]) )
|
||||||
|
{
|
||||||
|
return help(stdout,0);
|
||||||
|
}
|
||||||
|
if( argv[arg_idx][0] == '-' )
|
||||||
|
{
|
||||||
|
fprintf(stderr,"Error : unknown parameter : %s\n",argv[arg_idx]);
|
||||||
|
return help(stderr, 1);
|
||||||
|
}
|
||||||
|
switch ( arg_used )
|
||||||
|
{
|
||||||
|
case 1 :
|
||||||
|
if (!ParseInt(argv[arg_idx], &nRadios))
|
||||||
|
return help(stderr, 2);
|
||||||
|
if (nRadios < 1)
|
||||||
|
return help(stderr, 3);
|
||||||
|
if (nRadios > 100)
|
||||||
|
return help(stderr, 4);
|
||||||
|
|
||||||
|
arg_used++;
|
||||||
|
break;
|
||||||
|
case 2 :
|
||||||
|
if( strlen(argv[arg_idx]) > 17 )
|
||||||
|
return help(stderr, 5);
|
||||||
|
if( ! ParseAddress(argv[arg_idx],macPrefix) )
|
||||||
|
return help(stderr, 6);
|
||||||
|
|
||||||
|
arg_used++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
arg_idx++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( getuid() )
|
||||||
|
{
|
||||||
|
fprintf(stderr,"Error : This program must be run as root!!\n");
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ManageRadios(nRadios, macPrefix);
|
||||||
|
}
|
||||||
@@ -0,0 +1,223 @@
|
|||||||
|
#include <signal.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <iostream>
|
||||||
|
#include <string.h> // strcmp
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
#include "config.h" // DEFAULT_WIFI_CLIENT_PORT_VHOST / DEFAULT_WIFI_CLIENT_PORT_INET
|
||||||
|
#include "tools.h" // isInt
|
||||||
|
|
||||||
|
#include "cwificlient.h"
|
||||||
|
#ifdef ENABLE_VHOST
|
||||||
|
#include "csocketclientvtcp.h"
|
||||||
|
#endif
|
||||||
|
#include "csocketclientitcp.h"
|
||||||
|
|
||||||
|
#include "addinterfaces.h"
|
||||||
|
|
||||||
|
enum STATE {
|
||||||
|
|
||||||
|
STARTED=1,
|
||||||
|
STOPPED ,
|
||||||
|
SUSPENDED
|
||||||
|
};
|
||||||
|
|
||||||
|
CKernelWifi* wifiClient;
|
||||||
|
|
||||||
|
enum STATE _state = STOPPED ;
|
||||||
|
|
||||||
|
|
||||||
|
void signal_handler(int signal_num)
|
||||||
|
{
|
||||||
|
|
||||||
|
switch(signal_num)
|
||||||
|
{
|
||||||
|
case SIGINT :
|
||||||
|
case SIGTERM :
|
||||||
|
case SIGQUIT :
|
||||||
|
|
||||||
|
std::cout << signal_num << std::endl ;
|
||||||
|
wifiClient->stop() ;
|
||||||
|
_state = STOPPED ;
|
||||||
|
break ;
|
||||||
|
|
||||||
|
case SIGTSTP:
|
||||||
|
|
||||||
|
std::cout << "This signal is ignored" << std::endl ;
|
||||||
|
break ;
|
||||||
|
|
||||||
|
|
||||||
|
default :
|
||||||
|
std::cerr << "Signal not handled" << std::endl ;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << "OUT SWITCH" << std::endl ;
|
||||||
|
}
|
||||||
|
|
||||||
|
void help()
|
||||||
|
{
|
||||||
|
#ifdef ENABLE_VHOST
|
||||||
|
std::cout<<"Usage: vwifi-client [-h] [-v] [-s] [IP_ADDR] [-p PORT] [-u] [-n NUMBER_INTERFACE] [-m MAC_PREFIX]"<<std::endl;
|
||||||
|
std::cout<<" [--help] [--version] [--spy] [IP_ADDR] [--port PORT] [--use-port-in-hash] [--number NUMBER_INTERFACE] [--mac MAC_PREFIX]"<<std::endl;
|
||||||
|
std::cout<<" By default : client mode : TCP : IP_ADDR="<<DEFAULT_ADDRESS_IP <<" PORT="<< DEFAULT_WIFI_CLIENT_PORT_INET << std::endl;
|
||||||
|
std::cout<<" client mode : VHOST : PORT="<< DEFAULT_WIFI_CLIENT_PORT_VHOST << std::endl;
|
||||||
|
std::cout<<" spy mode (--spy) : IP_ADDR="<< DEFAULT_ADDRESS_IP <<" PORT="<< DEFAULT_WIFI_SPY_PORT << std::endl;
|
||||||
|
std::cout<<" NUMBER_INTERFACE="<< DEFAULT_NUMBER_WLAN_INTERFACE <<" MAC_PREFIX="<< DEFAULT_MAC_PREFIX << std::endl;
|
||||||
|
#else
|
||||||
|
std::cout<<"Usage: vwifi-client [-h] [-v] [-s] IP_ADDR [-p PORT] [-u] [-n NUMBER_INTERFACE] [-m MAC_PREFIX]"<<std::endl;
|
||||||
|
std::cout<<" [--help] [--version] [--spy] IP_ADDR [--port PORT] [--use-port-in-hash] [--number NUMBER_INTERFACE] [--mac MAC_PREFIX]"<<std::endl;
|
||||||
|
std::cout<<" By default : client mode : TCP : IP_ADDR="<<DEFAULT_ADDRESS_IP <<" PORT="<< DEFAULT_WIFI_CLIENT_PORT_INET << std::endl;
|
||||||
|
std::cout<<" spy mode (--spy) : IP_ADDR="<< DEFAULT_ADDRESS_IP <<" PORT="<< DEFAULT_WIFI_SPY_PORT << std::endl;
|
||||||
|
std::cout<<" NUMBER_INTERFACE="<< DEFAULT_NUMBER_WLAN_INTERFACE <<" MAC_PREFIX="<< DEFAULT_MAC_PREFIX << std::endl;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
int main (int argc , char ** argv){
|
||||||
|
|
||||||
|
bool spy = false;
|
||||||
|
|
||||||
|
std::string ip_addr;
|
||||||
|
TPort port_number = 0;
|
||||||
|
|
||||||
|
int number_interface=DEFAULT_NUMBER_WLAN_INTERFACE;
|
||||||
|
TByte mac_prefix[ETH_ALEN]={};
|
||||||
|
ParseAddress(DEFAULT_MAC_PREFIX, mac_prefix);
|
||||||
|
if( strlen(DEFAULT_MAC_PREFIX) <= 8 )
|
||||||
|
{ // if possible, randomize the 4th byte
|
||||||
|
srand(time(NULL));
|
||||||
|
mac_prefix[3]=rand()%100;
|
||||||
|
}
|
||||||
|
|
||||||
|
int arg_idx = 1;
|
||||||
|
while (arg_idx < argc)
|
||||||
|
{
|
||||||
|
if( ! strcmp("-v", argv[arg_idx]) || ! strcmp("--version", argv[arg_idx]) )
|
||||||
|
{
|
||||||
|
std::cout<<"Version : "<<VERSION<<std::endl;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if( ! strcmp("-h", argv[arg_idx]) || ! strcmp("--help", argv[arg_idx]) )
|
||||||
|
{
|
||||||
|
help();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if( ( ! strcmp("-p", argv[arg_idx]) || ! strcmp("--port", argv[arg_idx]) ) && (arg_idx + 1) < argc && isPositiveInt(argv[arg_idx+1]) )
|
||||||
|
{
|
||||||
|
port_number = std::stoi(argv[arg_idx+1]);
|
||||||
|
arg_idx++;
|
||||||
|
}
|
||||||
|
else if( ! strcmp("-u", argv[arg_idx]) || ! strcmp("--use-port-in-hash", argv[arg_idx]) )
|
||||||
|
{
|
||||||
|
HashUsesPort=true;
|
||||||
|
}
|
||||||
|
else if( ! strcmp("-s", argv[arg_idx]) || ! strcmp("--spy", argv[arg_idx]) )
|
||||||
|
{
|
||||||
|
spy=true;
|
||||||
|
}
|
||||||
|
else if( ( ! strcmp("-n", argv[arg_idx]) || ! strcmp("--number", argv[arg_idx]) ) && (arg_idx + 1) < argc && isPositiveInt(argv[arg_idx+1]) )
|
||||||
|
{
|
||||||
|
number_interface = std::stoi(argv[arg_idx+1]);
|
||||||
|
if (number_interface > 100)
|
||||||
|
{
|
||||||
|
std::cerr<<"Error : NUMBER > 100"<<std::endl;
|
||||||
|
return 4;
|
||||||
|
}
|
||||||
|
arg_idx++;
|
||||||
|
}
|
||||||
|
else if( ( ! strcmp("-m", argv[arg_idx]) || ! strcmp("--mac", argv[arg_idx]) ) && (arg_idx + 1) < argc)
|
||||||
|
{
|
||||||
|
std::string string = std::string(argv[arg_idx+1]);
|
||||||
|
if( string.size() > 17 )
|
||||||
|
{
|
||||||
|
std::cerr<<"Error : the MAC_PREFIX is too long"<<std::endl;
|
||||||
|
return 5;
|
||||||
|
}
|
||||||
|
if( ! ParseAddress(string.c_str(), mac_prefix) )
|
||||||
|
return 6;
|
||||||
|
arg_idx++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if( ip_addr.empty() )
|
||||||
|
ip_addr = std::string(argv[arg_idx]);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::cerr<<"Error : problem with this parameter : "<< argv[arg_idx] <<std::endl;
|
||||||
|
help();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
arg_idx++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( getuid() )
|
||||||
|
{
|
||||||
|
std::cerr<<"Error : This program must be run as root!!"<<std::endl;
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( number_interface )
|
||||||
|
if( ManageRadios(number_interface,mac_prefix) )
|
||||||
|
return 7;
|
||||||
|
|
||||||
|
/* Handle signals */
|
||||||
|
signal(SIGINT, signal_handler);
|
||||||
|
signal(SIGTERM, signal_handler);
|
||||||
|
signal(SIGQUIT, signal_handler);
|
||||||
|
signal(SIGHUP, SIG_IGN);
|
||||||
|
signal(SIGTSTP, signal_handler);
|
||||||
|
//signal(SIGCONT, signal_handler);
|
||||||
|
|
||||||
|
if( spy )
|
||||||
|
{ // mode TCP
|
||||||
|
|
||||||
|
if( ip_addr.empty() )
|
||||||
|
ip_addr = std::string(DEFAULT_ADDRESS_IP);
|
||||||
|
|
||||||
|
if( ! port_number )
|
||||||
|
port_number = DEFAULT_WIFI_SPY_PORT;
|
||||||
|
|
||||||
|
std::cout<<"Type : AF_INET"<<std::endl;
|
||||||
|
wifiClient=new CWifiClient<CSocketClientITCP>;
|
||||||
|
static_cast<CWifiClient<CSocketClientITCP>*>(wifiClient)->Init(ip_addr.c_str(), port_number);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if( ip_addr.empty() )
|
||||||
|
{ // IP not set -> mode VHOST
|
||||||
|
#ifdef ENABLE_VHOST
|
||||||
|
if( ! port_number )
|
||||||
|
port_number = DEFAULT_WIFI_CLIENT_PORT_VHOST;
|
||||||
|
|
||||||
|
std::cout<<"Type : AF_VSOCK"<<std::endl;
|
||||||
|
wifiClient=new CWifiClient<CSocketClientVTCP>;
|
||||||
|
static_cast<CWifiClient<CSocketClientVTCP>*>(wifiClient)->Init(port_number);
|
||||||
|
#else
|
||||||
|
std::cerr<<"Error : This program is not build with VHOST!!"<<std::endl;
|
||||||
|
return 8;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{ // mode TCP
|
||||||
|
if( ! port_number )
|
||||||
|
port_number = DEFAULT_WIFI_CLIENT_PORT_INET;
|
||||||
|
|
||||||
|
std::cout<<"Type : AF_INET"<<std::endl;
|
||||||
|
wifiClient=new CWifiClient<CSocketClientITCP>;
|
||||||
|
static_cast<CWifiClient<CSocketClientITCP>*>(wifiClient)->Init(ip_addr.c_str(), port_number);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!wifiClient->start())
|
||||||
|
std::cout << "Starting process aborted" << std::endl ;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
std::cout << "Good Bye (:-)" << std::endl ;
|
||||||
|
|
||||||
|
_exit(EXIT_SUCCESS);
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,807 @@
|
|||||||
|
#include <iostream> // cout
|
||||||
|
|
||||||
|
#include <string.h> //strlen
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
#include "tools.h" // isInt isPositiveInt isIntOrFloat
|
||||||
|
#include "csocketclientitcp.h"
|
||||||
|
#include "types.h"
|
||||||
|
#include "ccoordinate.h" // CCoordinate
|
||||||
|
#include "cinfowifi.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
std::string IP_Ctrl = std::string(DEFAULT_ADDRESS_IP);
|
||||||
|
TPort Port_Ctrl = DEFAULT_CTRL_PORT;
|
||||||
|
|
||||||
|
char* NameOfProg;
|
||||||
|
|
||||||
|
void Help()
|
||||||
|
{
|
||||||
|
cout<<NameOfProg<<" [order]"<<endl;
|
||||||
|
cout<<" with [order] :"<<endl;
|
||||||
|
cout<<" ls"<<endl;
|
||||||
|
cout<<" - List the Clients"<<endl;
|
||||||
|
cout<<" set CID X Y Z"<<endl;
|
||||||
|
cout<<" - Change the coordinate of the Client with CID"<<endl;
|
||||||
|
cout<<" setname CID NAME"<<endl;
|
||||||
|
cout<<" - Set the NAME of the Client with CID"<<endl;
|
||||||
|
cout<<" loss yes/no"<<endl;
|
||||||
|
cout<<" - loss yes : packets can be lost"<<endl;
|
||||||
|
cout<<" - loss no : no packets can be lost"<<endl;
|
||||||
|
cout<<" show"<<endl;
|
||||||
|
cout<<" - Display the status of loss and list of Clients"<<endl;
|
||||||
|
cout<<" status"<<endl;
|
||||||
|
cout<<" - Display the status of the configuration of vwifi-server"<<endl;
|
||||||
|
cout<<" distance CID1 CID2"<<endl;
|
||||||
|
cout<<" - Display the distance in meters between the Client with CID1 and the Client with CID2"<<endl;
|
||||||
|
cout<<" scale VALUE"<<endl;
|
||||||
|
cout<<" - Set the scale of the distances between the clients to VALUE"<<endl;
|
||||||
|
cout<<" - VALUE can be a decimal number"<<endl;
|
||||||
|
cout<<" close"<<endl;
|
||||||
|
cout<<" - Close all the connections with Wifi Clients"<<endl;
|
||||||
|
cout<<endl;
|
||||||
|
cout<<" [-p PORT] or [--port PORT] : Set the port used by the vwifi-server (by default PORT="<< Port_Ctrl <<")"<<endl;
|
||||||
|
cout<<" [-i IP] or [--ip IP] : Set the IP used by the vwifi-server (by default IP="<< IP_Ctrl <<")"<<endl;
|
||||||
|
cout<<" [-v] or [--version] : Display the version of "<<NameOfProg<<endl;
|
||||||
|
cout<<" [-h] or [--help] : this help"<<endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
int GetCInfoWifi(CSocketClientITCP & socket, CInfoWifi* infoWifi)
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
|
||||||
|
TCID cid;
|
||||||
|
err=socket.Read(reinterpret_cast<char*>(&cid),sizeof(cid));
|
||||||
|
if( err == SOCKET_ERROR )
|
||||||
|
{
|
||||||
|
cerr<<"Error : GetCInfoWifi : socket.Read : cid"<<endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
CCoordinate coo;
|
||||||
|
err=socket.Read(reinterpret_cast<char*>(&coo),sizeof(coo));
|
||||||
|
if( err == SOCKET_ERROR )
|
||||||
|
{
|
||||||
|
cerr<<"Error : GetCInfoWifi : socket.Read : CCoordinate (cid:"<<cid<<")"<<endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sizeName;
|
||||||
|
err=socket.Read(reinterpret_cast<char*>(&sizeName),sizeof(sizeName));
|
||||||
|
if( err == SOCKET_ERROR )
|
||||||
|
{
|
||||||
|
cerr<<"Error : GetCInfoWifi : socket.Read : size of name (cid:"<<cid<<")"<<endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if( sizeName > MAX_SIZE_NAME )
|
||||||
|
{
|
||||||
|
cerr<<"Error : GetCInfoWifi : size of name > "<<MAX_SIZE_NAME<<" (cid:"<<cid<<")"<<endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
char strName[MAX_SIZE_NAME+1]; // +1 : \0
|
||||||
|
if( sizeName > 0 )
|
||||||
|
{
|
||||||
|
err=socket.Read(reinterpret_cast<char*>(strName),sizeName+1); // +1 : \0
|
||||||
|
if( err == SOCKET_ERROR )
|
||||||
|
{
|
||||||
|
cerr<<"Error : GetCInfoWifi : socket.Read : size of name (cid:"<<cid<<")"<<endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
strName[0]='\0';
|
||||||
|
|
||||||
|
infoWifi->SetCid(cid);
|
||||||
|
infoWifi->Set(coo);
|
||||||
|
|
||||||
|
string name(strName);
|
||||||
|
infoWifi->SetName(name);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int AskList()
|
||||||
|
{
|
||||||
|
CSocketClientITCP socket;
|
||||||
|
|
||||||
|
socket.Init(IP_Ctrl.c_str(),Port_Ctrl);
|
||||||
|
|
||||||
|
if( ! socket.ConnectLoop() )
|
||||||
|
{
|
||||||
|
cerr<<"Error : ls : socket.Connect error"<<endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int err;
|
||||||
|
|
||||||
|
TOrder order=TORDER_LIST;
|
||||||
|
err=socket.Send(reinterpret_cast<char*>(&order),sizeof(order));
|
||||||
|
if( err == SOCKET_ERROR )
|
||||||
|
{
|
||||||
|
cerr<<"Error : ls : socket.Send : order"<<endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Spies :
|
||||||
|
|
||||||
|
TIndex number;
|
||||||
|
err=socket.Read(reinterpret_cast<char*>(&number),sizeof(number));
|
||||||
|
if( err == SOCKET_ERROR )
|
||||||
|
{
|
||||||
|
cerr<<"Error : ls : socket.Read : number"<<endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
CInfoWifi info;
|
||||||
|
for(TIndex i=0; i<number;i++)
|
||||||
|
{
|
||||||
|
err=GetCInfoWifi(socket,&info);
|
||||||
|
if( err == SOCKET_ERROR )
|
||||||
|
{
|
||||||
|
cerr<<"Error : ls : socket.Read : CInfoWifi"<<endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
cout<<"S:"<<info.GetCid();
|
||||||
|
if( info.HasName() )
|
||||||
|
cout<<" ("<<info.GetName()<<")";
|
||||||
|
cout<<endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clients :
|
||||||
|
|
||||||
|
err=socket.Read(reinterpret_cast<char*>(&number),sizeof(number));
|
||||||
|
if( err == SOCKET_ERROR )
|
||||||
|
{
|
||||||
|
cerr<<"Error : ls : socket.Read : number"<<endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(TIndex i=0; i<number;i++)
|
||||||
|
{
|
||||||
|
err=GetCInfoWifi(socket,&info);
|
||||||
|
if( err == SOCKET_ERROR )
|
||||||
|
{
|
||||||
|
cerr<<"Error : ls : socket.Read : CInfoWifi"<<endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
cout<<info<<endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
socket.Close();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ChangeCoordinate(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
if( argc != 5 )
|
||||||
|
{
|
||||||
|
cerr<<"Error : set : the number of parameter is uncorrect"<<endl;
|
||||||
|
Help();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( ! isPositiveInt(argv[1]) )
|
||||||
|
{
|
||||||
|
cerr<<"Error : set : the CID is not an integer"<<endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
TCID cid=atoi(argv[1]);
|
||||||
|
|
||||||
|
if( cid < TCID_GUEST_MIN )
|
||||||
|
{
|
||||||
|
cerr<<"Error : set : the CID must be greater than or equal to "<<TCID_GUEST_MIN<<endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( ! isInt(argv[2]) )
|
||||||
|
{
|
||||||
|
cerr<<"Error : set : the x coordinate is not an integer"<<endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if( ! isInt(argv[3]) )
|
||||||
|
{
|
||||||
|
cerr<<"Error : set : the y coordinate is not an integer"<<endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if( ! isInt(argv[4]) )
|
||||||
|
{
|
||||||
|
cerr<<"Error : set : the z coordinate is not an integer"<<endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
TValue x=atoi(argv[2]);
|
||||||
|
TValue y=atoi(argv[3]);
|
||||||
|
TValue z=atoi(argv[4]);
|
||||||
|
CCoordinate coo(x,y,z);
|
||||||
|
|
||||||
|
cout<<cid<<" "<<coo<<" "<<endl;
|
||||||
|
|
||||||
|
CSocketClientITCP socket;
|
||||||
|
|
||||||
|
socket.Init(IP_Ctrl.c_str(),Port_Ctrl);
|
||||||
|
|
||||||
|
if( ! socket.ConnectLoop() )
|
||||||
|
{
|
||||||
|
cerr<<"Error : set : socket.Connect error"<<endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int err;
|
||||||
|
|
||||||
|
TOrder order=TORDER_CHANGE_COORDINATE;
|
||||||
|
err=socket.Send(reinterpret_cast<char*>(&order),sizeof(order));
|
||||||
|
if( err == SOCKET_ERROR )
|
||||||
|
{
|
||||||
|
cerr<<"Error : set : socket.Send : order"<<endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
err=socket.Send(reinterpret_cast<char*>(&cid),sizeof(cid));
|
||||||
|
if( err == SOCKET_ERROR )
|
||||||
|
{
|
||||||
|
cerr<<"Error : set : socket.Send : cid"<<endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
err=socket.Send(reinterpret_cast<char*>(&coo),sizeof(coo));
|
||||||
|
if( err == SOCKET_ERROR )
|
||||||
|
{
|
||||||
|
cerr<<"Error : set : socket.Send : "<<coo<<endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
socket.Close();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int SetName(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
if( argc != 3 )
|
||||||
|
{
|
||||||
|
cerr<<"Error : setname : the number of parameter is uncorrect"<<endl;
|
||||||
|
Help();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( ! isPositiveInt(argv[1]) )
|
||||||
|
{
|
||||||
|
cerr<<"Error : setname : the CID is not an integer"<<endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
TCID cid=atoi(argv[1]);
|
||||||
|
|
||||||
|
if( cid < TCID_GUEST_MIN )
|
||||||
|
{
|
||||||
|
cerr<<"Error : setname : the CID must be greater than or equal to "<<TCID_GUEST_MIN<<endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
string name(argv[2]);
|
||||||
|
int sizeName=name.size();
|
||||||
|
if( name.length() > MAX_SIZE_NAME )
|
||||||
|
{
|
||||||
|
name.resize(MAX_SIZE_NAME);
|
||||||
|
sizeName=MAX_SIZE_NAME;
|
||||||
|
}
|
||||||
|
|
||||||
|
cout<<cid<<" "<<name<<" "<<endl;
|
||||||
|
|
||||||
|
CSocketClientITCP socket;
|
||||||
|
|
||||||
|
socket.Init(IP_Ctrl.c_str(),Port_Ctrl);
|
||||||
|
|
||||||
|
if( ! socket.ConnectLoop() )
|
||||||
|
{
|
||||||
|
cerr<<"Error : setname : socket.Connect error"<<endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int err;
|
||||||
|
|
||||||
|
TOrder order=TORDER_SETNAME;
|
||||||
|
err=socket.Send(reinterpret_cast<char*>(&order),sizeof(order));
|
||||||
|
if( err == SOCKET_ERROR )
|
||||||
|
{
|
||||||
|
cerr<<"Error : setname : socket.Send : order"<<endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
err=socket.Send(reinterpret_cast<char*>(&cid),sizeof(cid));
|
||||||
|
if( err == SOCKET_ERROR )
|
||||||
|
{
|
||||||
|
cerr<<"Error : setname : socket.Send : cid"<<endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
err=socket.Send(reinterpret_cast<char*>(&sizeName),sizeof(sizeName));
|
||||||
|
if( err == SOCKET_ERROR )
|
||||||
|
{
|
||||||
|
cerr<<"Error : setname : socket.Send : size of name"<<endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
err=socket.Send(const_cast<char*>(name.c_str()),sizeName+1); // +1 : \0
|
||||||
|
if( err == SOCKET_ERROR )
|
||||||
|
{
|
||||||
|
cerr<<"Error : setname : socket.Send : name"<<name<<endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
socket.Close();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ChangePacketLoss(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
if( argc != 2 )
|
||||||
|
{
|
||||||
|
cerr<<"Error : loss : the number of parameter is uncorrect"<<endl;
|
||||||
|
Help();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int value;
|
||||||
|
if ( ! strcmp(argv[1],"yes") )
|
||||||
|
value=1;
|
||||||
|
else if ( ! strcmp(argv[1],"no") )
|
||||||
|
value=0;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cerr<<"Error : loss : the value can only be \"yes\" or \"no\""<<endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
CSocketClientITCP socket;
|
||||||
|
|
||||||
|
socket.Init(IP_Ctrl.c_str(),Port_Ctrl);
|
||||||
|
|
||||||
|
if( ! socket.ConnectLoop() )
|
||||||
|
{
|
||||||
|
cerr<<"Error : loss : socket.Connect error"<<endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int err;
|
||||||
|
|
||||||
|
TOrder order=TORDER_PACKET_LOSS;
|
||||||
|
err=socket.Send(reinterpret_cast<char*>(&order),sizeof(order));
|
||||||
|
if( err == SOCKET_ERROR )
|
||||||
|
{
|
||||||
|
cerr<<"Error : loss : socket.Send : order"<<endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
err=socket.Send(reinterpret_cast<char*>(&value),sizeof(value));
|
||||||
|
if( err == SOCKET_ERROR )
|
||||||
|
{
|
||||||
|
if ( value )
|
||||||
|
cerr<<"Error : loss : socket.Send : yes"<<endl;
|
||||||
|
else
|
||||||
|
cerr<<"Error : loss : socket.Send : no"<<endl;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
socket.Close();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int AskStatus()
|
||||||
|
{
|
||||||
|
cout<<"CTRL : IP : "<<IP_Ctrl.c_str()<<endl;
|
||||||
|
cout<<"CTRL : Port : "<<Port_Ctrl<<endl;
|
||||||
|
|
||||||
|
CSocketClientITCP socket;
|
||||||
|
|
||||||
|
socket.Init(IP_Ctrl.c_str(),Port_Ctrl);
|
||||||
|
|
||||||
|
if( ! socket.ConnectLoop() )
|
||||||
|
{
|
||||||
|
cerr<<"Error : status : socket.Connect error"<<endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int err;
|
||||||
|
|
||||||
|
TOrder order=TORDER_STATUS;
|
||||||
|
err=socket.Send(reinterpret_cast<char*>(&order),sizeof(order));
|
||||||
|
if( err == SOCKET_ERROR )
|
||||||
|
{
|
||||||
|
cerr<<"Error : status : socket.Send : Order"<<endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool loss;
|
||||||
|
err=socket.Read(reinterpret_cast<char*>(&loss),sizeof(loss));
|
||||||
|
if( err == SOCKET_ERROR )
|
||||||
|
{
|
||||||
|
cerr<<"Error : status : socket.Read : Loss"<<endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
cout<<"SRV : PacketLoss : ";
|
||||||
|
if ( loss )
|
||||||
|
cout<<"Enable"<<endl;
|
||||||
|
else
|
||||||
|
cout<<"Disable"<<endl;
|
||||||
|
|
||||||
|
TScale scale;
|
||||||
|
err=socket.Read(reinterpret_cast<char*>(&scale),sizeof(scale));
|
||||||
|
if( err == SOCKET_ERROR )
|
||||||
|
{
|
||||||
|
cerr<<"Error : status : socket.Read : scale"<<endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
cout<<"SRV : Scale : "<<scale<<endl;
|
||||||
|
|
||||||
|
// VHOST
|
||||||
|
|
||||||
|
TPort port;
|
||||||
|
err=socket.Read(reinterpret_cast<char*>(&port),sizeof(port));
|
||||||
|
if( err == SOCKET_ERROR )
|
||||||
|
{
|
||||||
|
cerr<<"Error : status : socket.Read : Port VHOST"<<endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
cout<<"SRV VHOST : Port : "<<port<<endl;
|
||||||
|
|
||||||
|
// INET
|
||||||
|
|
||||||
|
err=socket.Read(reinterpret_cast<char*>(&port),sizeof(port));
|
||||||
|
if( err == SOCKET_ERROR )
|
||||||
|
{
|
||||||
|
cerr<<"Error : status : socket.Read : Port INET"<<endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
cout<<"SRV INET : Port : "<<port<<endl;
|
||||||
|
|
||||||
|
// SizeOfDisconnected
|
||||||
|
// becareful : the same List is shared by WifiServerVTCP and WifiServerITCP
|
||||||
|
|
||||||
|
TIndex size;
|
||||||
|
err=socket.Read(reinterpret_cast<char*>(&size),sizeof(size));
|
||||||
|
if( err == SOCKET_ERROR )
|
||||||
|
{
|
||||||
|
cerr<<"Error : status : socket.Read : Size INET"<<endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
cout<<"SRV : SizeOfDisconnected : "<<size<<endl;
|
||||||
|
|
||||||
|
// SPY
|
||||||
|
|
||||||
|
bool spyIsConnected;
|
||||||
|
err=socket.Read(reinterpret_cast<char*>(&spyIsConnected),sizeof(spyIsConnected));
|
||||||
|
if( err == SOCKET_ERROR )
|
||||||
|
{
|
||||||
|
cerr<<"Error : status : socket.Read : spyIsConnected"<<endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
cout<<"SPY : ";
|
||||||
|
if ( spyIsConnected )
|
||||||
|
cout<<"Connected"<<endl;
|
||||||
|
else
|
||||||
|
cout<<"Disconnected"<<endl;
|
||||||
|
|
||||||
|
socket.Close();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int AskShow()
|
||||||
|
{
|
||||||
|
CSocketClientITCP socket;
|
||||||
|
|
||||||
|
socket.Init(IP_Ctrl.c_str(),Port_Ctrl);
|
||||||
|
|
||||||
|
if( ! socket.ConnectLoop() )
|
||||||
|
{
|
||||||
|
cerr<<"Error : show : socket.Connect error"<<endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int err;
|
||||||
|
|
||||||
|
TOrder order=TORDER_SHOW;
|
||||||
|
err=socket.Send(reinterpret_cast<char*>(&order),sizeof(order));
|
||||||
|
if( err == SOCKET_ERROR )
|
||||||
|
{
|
||||||
|
cerr<<"Error : show : socket.Send : Order"<<endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool loss;
|
||||||
|
err=socket.Read(reinterpret_cast<char*>(&loss),sizeof(loss));
|
||||||
|
if( err == SOCKET_ERROR )
|
||||||
|
{
|
||||||
|
cerr<<"Error : show : socket.Read : Loss"<<endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
cout<<"PacketLoss : ";
|
||||||
|
if ( loss )
|
||||||
|
cout<<"Enable"<<endl;
|
||||||
|
else
|
||||||
|
cout<<"Disable"<<endl;
|
||||||
|
|
||||||
|
TScale scale;
|
||||||
|
err=socket.Read(reinterpret_cast<char*>(&scale),sizeof(scale));
|
||||||
|
if( err == SOCKET_ERROR )
|
||||||
|
{
|
||||||
|
cerr<<"Error : show : socket.Read : scale"<<endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
cout<<"Scale : "<<scale<<endl;
|
||||||
|
|
||||||
|
bool spyIsConnected;
|
||||||
|
err=socket.Read(reinterpret_cast<char*>(&spyIsConnected),sizeof(spyIsConnected));
|
||||||
|
if( err == SOCKET_ERROR )
|
||||||
|
{
|
||||||
|
cerr<<"Error : show : socket.Read : spyIsConnected"<<endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
cout<<"Spy : ";
|
||||||
|
if ( spyIsConnected )
|
||||||
|
cout<<"Connected"<<endl;
|
||||||
|
else
|
||||||
|
cout<<"Disconnected"<<endl;
|
||||||
|
|
||||||
|
socket.Close();
|
||||||
|
|
||||||
|
cout<<"----------------"<<endl;
|
||||||
|
|
||||||
|
return AskList();
|
||||||
|
}
|
||||||
|
|
||||||
|
int DistanceBetweenCID(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
if( argc != 3 )
|
||||||
|
{
|
||||||
|
cerr<<"Error : distance : the number of parameter is uncorrect"<<endl;
|
||||||
|
Help();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( ! isPositiveInt(argv[1]) )
|
||||||
|
{
|
||||||
|
cerr<<"Error : distance : the CID 1 is not an integer"<<endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
TCID cid1=atoi(argv[1]);
|
||||||
|
|
||||||
|
if( cid1 < TCID_GUEST_MIN )
|
||||||
|
{
|
||||||
|
cerr<<"Error : distance : the CID 1 must be greater than or equal to "<<TCID_GUEST_MIN<<endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( ! isPositiveInt(argv[2]) )
|
||||||
|
{
|
||||||
|
cerr<<"Error : distance : the CID 2 is not an integer"<<endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
TCID cid2=atoi(argv[2]);
|
||||||
|
|
||||||
|
if( cid2 < TCID_GUEST_MIN )
|
||||||
|
{
|
||||||
|
cerr<<"Error : distance : the CID2 must be greater than or equal to "<<TCID_GUEST_MIN<<endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
CSocketClientITCP socket;
|
||||||
|
|
||||||
|
socket.Init(IP_Ctrl.c_str(),Port_Ctrl);
|
||||||
|
|
||||||
|
if( ! socket.ConnectLoop() )
|
||||||
|
{
|
||||||
|
cerr<<"Error : distance : socket.Connect error"<<endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int err;
|
||||||
|
|
||||||
|
TOrder order=TORDER_DISTANCE_BETWEEN_CID;
|
||||||
|
err=socket.Send(reinterpret_cast<char*>(&order),sizeof(order));
|
||||||
|
if( err == SOCKET_ERROR )
|
||||||
|
{
|
||||||
|
cerr<<"Error : distance : socket.Send : order"<<endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
err=socket.Send(reinterpret_cast<char*>(&cid1),sizeof(cid1));
|
||||||
|
if( err == SOCKET_ERROR )
|
||||||
|
{
|
||||||
|
cerr<<"Error : distance : socket.Send : cid 1"<<endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
err=socket.Send(reinterpret_cast<char*>(&cid2),sizeof(cid2));
|
||||||
|
if( err == SOCKET_ERROR )
|
||||||
|
{
|
||||||
|
cerr<<"Error : distance : socket.Send : cid 2"<<endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int codeError;
|
||||||
|
err=socket.Read(reinterpret_cast<char*>(&codeError),sizeof(codeError));
|
||||||
|
if( err == SOCKET_ERROR )
|
||||||
|
{
|
||||||
|
cerr<<"Error : distance : socket.Read : codeError"<<endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( codeError == -1 )
|
||||||
|
{
|
||||||
|
cerr<<"Error : distance : unknown cid 1 : "<<cid1<<endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if ( codeError == -2 )
|
||||||
|
{
|
||||||
|
cerr<<"Error : distance : unknown cid 2 : "<<cid2<<endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
TDistance distance;
|
||||||
|
err=socket.Read(reinterpret_cast<char*>(&distance),sizeof(distance));
|
||||||
|
if( err == SOCKET_ERROR )
|
||||||
|
{
|
||||||
|
cerr<<"Error : distance : socket.Read : distance"<<endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
cout<<distance<<endl;
|
||||||
|
|
||||||
|
socket.Close();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int SetScale(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
if( argc != 2)
|
||||||
|
{
|
||||||
|
cerr<<"Error : scale : the number of parameter is uncorrect"<<endl;
|
||||||
|
Help();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( ! isIntOrFloat(argv[1]) )
|
||||||
|
{
|
||||||
|
cerr<<"Error : scale : the format of the value is uncorrect"<<endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
TScale scale=atof(argv[1]);
|
||||||
|
if( scale <= 0 )
|
||||||
|
{
|
||||||
|
cerr<<"Error : scale : the value must be greater than 0"<<endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
CSocketClientITCP socket;
|
||||||
|
|
||||||
|
socket.Init(IP_Ctrl.c_str(),Port_Ctrl);
|
||||||
|
|
||||||
|
if( ! socket.ConnectLoop() )
|
||||||
|
{
|
||||||
|
cerr<<"Error : scale : socket.Connect error"<<endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int err;
|
||||||
|
|
||||||
|
TOrder order=TORDER_SET_SCALE;
|
||||||
|
err=socket.Send(reinterpret_cast<char*>(&order),sizeof(order));
|
||||||
|
if( err == SOCKET_ERROR )
|
||||||
|
{
|
||||||
|
cerr<<"Error : scale : socket.Send : order"<<endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
err=socket.Send(reinterpret_cast<char*>(&scale),sizeof(scale));
|
||||||
|
if( err == SOCKET_ERROR )
|
||||||
|
{
|
||||||
|
cerr<<"Error : scale : socket.Send : scale"<<endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
socket.Close();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CloseAllClient()
|
||||||
|
{
|
||||||
|
CSocketClientITCP socket;
|
||||||
|
|
||||||
|
socket.Init(IP_Ctrl.c_str(),Port_Ctrl);
|
||||||
|
|
||||||
|
if( ! socket.ConnectLoop() )
|
||||||
|
{
|
||||||
|
cerr<<"Error : close : socket.Connect error"<<endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int err;
|
||||||
|
|
||||||
|
TOrder order=TORDER_CLOSE_ALL_CLIENT;
|
||||||
|
err=socket.Send(reinterpret_cast<char*>(&order),sizeof(order));
|
||||||
|
if( err == SOCKET_ERROR )
|
||||||
|
{
|
||||||
|
cerr<<"Error : close : socket.Send : order"<<endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
socket.Close();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc , char *argv[])
|
||||||
|
{
|
||||||
|
char** param_cmd = new char*[argc];
|
||||||
|
int nbr_param_cmd=0;
|
||||||
|
|
||||||
|
NameOfProg=argv[0];
|
||||||
|
|
||||||
|
int arg_idx = 1;
|
||||||
|
while (arg_idx < argc)
|
||||||
|
{
|
||||||
|
if( ! strcmp("-v", argv[arg_idx]) || ! strcmp("--version", argv[arg_idx]) )
|
||||||
|
{
|
||||||
|
std::cout<<"Version : "<<VERSION<<std::endl;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if( ! strcmp("-h", argv[arg_idx]) || ! strcmp("--help", argv[arg_idx]) )
|
||||||
|
{
|
||||||
|
Help();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if( ( ! strcmp("-p", argv[arg_idx]) || ! strcmp("--port", argv[arg_idx]) ) && (arg_idx + 1) < argc && isPositiveInt(argv[arg_idx+1]) )
|
||||||
|
{
|
||||||
|
Port_Ctrl = std::stoi(argv[arg_idx+1]);
|
||||||
|
arg_idx++;
|
||||||
|
}
|
||||||
|
else if( ( ! strcmp("-i", argv[arg_idx]) || ! strcmp("--ip", argv[arg_idx]) ) && (arg_idx + 1) < argc)
|
||||||
|
{
|
||||||
|
IP_Ctrl = std::string(argv[arg_idx+1]);
|
||||||
|
arg_idx++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
param_cmd[nbr_param_cmd++]=argv[arg_idx];
|
||||||
|
}
|
||||||
|
|
||||||
|
arg_idx++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( nbr_param_cmd == 0 )
|
||||||
|
{
|
||||||
|
Help();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( ! strcasecmp(param_cmd[0],"ls") )
|
||||||
|
return AskList();
|
||||||
|
|
||||||
|
if( ! strcasecmp(param_cmd[0],"set") )
|
||||||
|
return ChangeCoordinate(nbr_param_cmd, param_cmd);
|
||||||
|
|
||||||
|
if( ! strcasecmp(param_cmd[0],"setname") )
|
||||||
|
return SetName(nbr_param_cmd, param_cmd);
|
||||||
|
|
||||||
|
if( ! strcasecmp(param_cmd[0],"loss") )
|
||||||
|
return ChangePacketLoss(nbr_param_cmd, param_cmd);
|
||||||
|
|
||||||
|
if( ! strcasecmp(param_cmd[0],"show") )
|
||||||
|
return AskShow();
|
||||||
|
|
||||||
|
if( ! strcasecmp(param_cmd[0],"status") )
|
||||||
|
return AskStatus();
|
||||||
|
|
||||||
|
if( ! strcasecmp(param_cmd[0],"distance") )
|
||||||
|
return DistanceBetweenCID(nbr_param_cmd, param_cmd);
|
||||||
|
|
||||||
|
if( ! strcasecmp(param_cmd[0],"scale") )
|
||||||
|
return SetScale(nbr_param_cmd, param_cmd);
|
||||||
|
|
||||||
|
if( ! strcasecmp(param_cmd[0],"close") )
|
||||||
|
return CloseAllClient();
|
||||||
|
|
||||||
|
cerr<<NameOfProg<<" : Error : unknown order : "<<param_cmd[0]<<endl;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
#include "cwirelessdevice.h"
|
||||||
|
#include "cmonwirelessdevice.h"
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <signal.h>
|
||||||
|
|
||||||
|
|
||||||
|
MonitorWirelessDevice monitor ;
|
||||||
|
|
||||||
|
|
||||||
|
void signal_handler([[maybe_unused]] int signal_num)
|
||||||
|
{
|
||||||
|
std::cout << __func__ << std::endl ;
|
||||||
|
monitor.stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int main (){
|
||||||
|
|
||||||
|
|
||||||
|
/* Handle signals */
|
||||||
|
signal(SIGINT, signal_handler);
|
||||||
|
signal(SIGTERM, signal_handler);
|
||||||
|
signal(SIGQUIT, signal_handler);
|
||||||
|
signal(SIGHUP, SIG_IGN);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* struct ether_addr mac { 0xff, 0x00, 0x00,0x00, 0xfe, 0x00 };
|
||||||
|
struct ether_addr mac3 { 0xaa, 0xbb, 0x00,0x00, 0xfe, 0x00 };
|
||||||
|
|
||||||
|
WirelessDevice wdevice("wlan0",4,5,mac);
|
||||||
|
std::cout << wdevice << std::endl ;
|
||||||
|
|
||||||
|
WirelessDevice wdevice2 ;
|
||||||
|
wdevice2 = wdevice;
|
||||||
|
|
||||||
|
wdevice.setMacaddr(mac3);
|
||||||
|
|
||||||
|
std::cout << wdevice2 << std::endl ;
|
||||||
|
std::cout << wdevice << std::endl ;
|
||||||
|
*/
|
||||||
|
|
||||||
|
monitor.start();
|
||||||
|
|
||||||
|
pause();
|
||||||
|
|
||||||
|
std::cout << "end" << std::endl ;
|
||||||
|
|
||||||
|
return 0 ;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,309 @@
|
|||||||
|
#include <iostream> // cout
|
||||||
|
|
||||||
|
#include <string.h> // strcmp
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
#include "tools.h" // isPositiveInt
|
||||||
|
#include "cwifiserveritcp.h"
|
||||||
|
#ifdef ENABLE_VHOST
|
||||||
|
#include "cwifiservervtcp.h"
|
||||||
|
#endif
|
||||||
|
#include "cctrlserver.h"
|
||||||
|
#include "cselect.h"
|
||||||
|
#include "cdynbuffer.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
CDynBuffer Buffer; // Buffer to stock received values
|
||||||
|
#ifdef ENABLE_VHOST
|
||||||
|
TPort Port_VHOST = DEFAULT_WIFI_CLIENT_PORT_VHOST;
|
||||||
|
#endif
|
||||||
|
TPort Port_TCP = DEFAULT_WIFI_CLIENT_PORT_INET;
|
||||||
|
TPort Port_Spy = DEFAULT_WIFI_SPY_PORT;
|
||||||
|
TPort Port_Ctrl = DEFAULT_CTRL_PORT;
|
||||||
|
|
||||||
|
CSelect Scheduler;
|
||||||
|
|
||||||
|
void RemoveClient(CWifiServer* srv, bool srvIsSpy, TIndex i, TDescriptor socket)
|
||||||
|
{
|
||||||
|
if( ! srvIsSpy )
|
||||||
|
{
|
||||||
|
cout<<"Client disconnected : "; srv->ShowInfoWifi(i) ; cout<<endl;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
cout<<"Spy disconnected : "<< srv->GetReferenceOnInfoWifiByIndex(i)->GetCid() <<endl;
|
||||||
|
|
||||||
|
srv->CloseClient(i);
|
||||||
|
|
||||||
|
//del master socket to set
|
||||||
|
Scheduler.DelNode(socket);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ForwardData(bool srcIsSpy, CWifiServer* src, CWifiServer* otherDst)
|
||||||
|
{
|
||||||
|
int valread;
|
||||||
|
TPower power;
|
||||||
|
|
||||||
|
for ( TIndex i = 0 ; i < src->GetNumberClient() ; )
|
||||||
|
{
|
||||||
|
TDescriptor socket = (*src)[i];
|
||||||
|
|
||||||
|
if( ! src->IsEnable(i) )
|
||||||
|
{
|
||||||
|
RemoveClient(src, srcIsSpy , i, socket);
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( Scheduler.DescriptorHasAction(socket) )
|
||||||
|
{
|
||||||
|
//Check if it was for closing , and also read the
|
||||||
|
//incoming message
|
||||||
|
|
||||||
|
valread=src->RecvSignal(socket,&power,&Buffer);
|
||||||
|
if( valread <=0 )
|
||||||
|
{
|
||||||
|
RemoveClient(src, srcIsSpy , i, socket);
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( ! srcIsSpy )
|
||||||
|
{
|
||||||
|
src->SendAllOtherClients(i,power,Buffer.GetBuffer(),valread);
|
||||||
|
otherDst->SendAllClientsWithoutLoss(power,Buffer.GetBuffer(),valread);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
src->SendAllOtherClientsWithoutLoss(i,power,Buffer.GetBuffer(),valread);
|
||||||
|
otherDst->SendAllClientsWithoutLoss(power,Buffer.GetBuffer(),valread);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int vwifi_server()
|
||||||
|
{
|
||||||
|
TDescriptor socket;
|
||||||
|
|
||||||
|
CListInfo<CInfoSocket> infoSockets;
|
||||||
|
CListInfo<CInfoWifi> infoWifis;
|
||||||
|
CListInfo<CInfoWifi> infoWifisDeconnected;
|
||||||
|
|
||||||
|
#ifdef ENABLE_VHOST
|
||||||
|
CWifiServerVTCP wifiServerVTCP(&infoSockets,&infoWifis,&infoWifisDeconnected);
|
||||||
|
cout<<"CLIENT VHOST : ";
|
||||||
|
wifiServerVTCP.Init(Port_VHOST);
|
||||||
|
if( ! wifiServerVTCP.Listen(WIFI_MAX_DECONNECTED_CLIENT) )
|
||||||
|
{
|
||||||
|
cerr<<"Error : wifiServerVTCP.Listen"<<endl;
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
CWifiServerITCP wifiServerITCP(&infoSockets,&infoWifis,&infoWifisDeconnected);
|
||||||
|
cout<<"CLIENT TCP : ";
|
||||||
|
wifiServerITCP.Init(Port_TCP);
|
||||||
|
if( ! wifiServerITCP.Listen(WIFI_MAX_DECONNECTED_CLIENT) )
|
||||||
|
{
|
||||||
|
cerr<<"Error : wifiServerITCP.Listen"<<endl;
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
CWifiServer* wifiServer=&wifiServerITCP; // or wifiServerVTCP, if exist, it doesn't change anything
|
||||||
|
|
||||||
|
cout<<"SPY : ";
|
||||||
|
CWifiServerITCP wifiServerSPY;
|
||||||
|
wifiServerSPY.Init(Port_Spy);
|
||||||
|
if( ! wifiServerSPY.Listen(1) )
|
||||||
|
{
|
||||||
|
cerr<<"Error : wifiServerSPY.Listen"<<endl;
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
cout<<"CTRL : ";
|
||||||
|
#ifdef ENABLE_VHOST
|
||||||
|
CCTRLServer ctrlServer(&wifiServerVTCP, &wifiServerITCP, &wifiServerSPY,&Scheduler);
|
||||||
|
#else
|
||||||
|
CCTRLServer ctrlServer(NULL, &wifiServerITCP, &wifiServerSPY,&Scheduler);
|
||||||
|
#endif
|
||||||
|
ctrlServer.Init(Port_Ctrl);
|
||||||
|
if( ! ctrlServer.Listen() )
|
||||||
|
{
|
||||||
|
cerr<<"Error : ctrlServer.Listen"<<endl;
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
cout<<"Size of disconnected : "<<WIFI_MAX_DECONNECTED_CLIENT<<endl;
|
||||||
|
|
||||||
|
if( CanLostPackets )
|
||||||
|
cout<<"Packet loss : Enable"<<endl;
|
||||||
|
else
|
||||||
|
cout<<"Packet loss : disable"<<endl;
|
||||||
|
|
||||||
|
cout<<"Scale : "<<Scale<<endl;
|
||||||
|
|
||||||
|
//add master socket to set
|
||||||
|
#ifdef ENABLE_VHOST
|
||||||
|
Scheduler.AddNode(wifiServerVTCP);
|
||||||
|
#endif
|
||||||
|
Scheduler.AddNode(wifiServerITCP);
|
||||||
|
Scheduler.AddNode(wifiServerSPY);
|
||||||
|
Scheduler.AddNode(ctrlServer);
|
||||||
|
|
||||||
|
while( true )
|
||||||
|
{
|
||||||
|
//wait for an activity on one of the sockets , timeout is NULL ,
|
||||||
|
//so wait indefinitely
|
||||||
|
if( Scheduler.Wait() == SCHEDULER_ERROR )
|
||||||
|
{
|
||||||
|
cerr<<"Error : scheduler.Wait"<<endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
|
||||||
|
//If something happened on the master socket ,
|
||||||
|
//then its an incoming connection
|
||||||
|
#ifdef ENABLE_VHOST
|
||||||
|
if( Scheduler.DescriptorHasAction(wifiServerVTCP) )
|
||||||
|
{
|
||||||
|
socket = wifiServerVTCP.Accept();
|
||||||
|
if ( socket == SOCKET_ERROR )
|
||||||
|
{
|
||||||
|
cerr<<"Error : wifiServerVTCP.Accept"<<endl;
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
//add child sockets to set
|
||||||
|
Scheduler.AddNode(socket);
|
||||||
|
|
||||||
|
//inform user of socket number - used in send and receive commands
|
||||||
|
cout<<"New connection from Client VHost : "; wifiServer->ShowInfoWifi(wifiServer->GetNumberClient()-1) ; cout<<endl;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if( Scheduler.DescriptorHasAction(wifiServerITCP) )
|
||||||
|
{
|
||||||
|
socket = wifiServerITCP.Accept();
|
||||||
|
if ( socket == SOCKET_ERROR )
|
||||||
|
{
|
||||||
|
cerr<<"Error : wifiServerITCP.Accept"<<endl;
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
//add child sockets to set
|
||||||
|
Scheduler.AddNode(socket);
|
||||||
|
|
||||||
|
//inform user of socket number - used in send and receive commands
|
||||||
|
cout<<"New connection from Client TCP : "; wifiServer->ShowInfoWifi(wifiServer->GetNumberClient()-1) ; cout<<endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( Scheduler.DescriptorHasAction(wifiServerSPY) )
|
||||||
|
{
|
||||||
|
socket = wifiServerSPY.Accept();
|
||||||
|
if ( socket == SOCKET_ERROR )
|
||||||
|
{
|
||||||
|
cerr<<"Error : wifiSpyServer.Accept"<<endl;
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
//add child sockets to set
|
||||||
|
Scheduler.AddNode(socket);
|
||||||
|
|
||||||
|
//inform user of socket number - used in send and receive commands
|
||||||
|
cout<<"New connection from Spy : "<<wifiServerSPY.GetReferenceOnInfoWifiByIndex(wifiServerSPY.GetNumberClient()-1)->GetCid()<<endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( Scheduler.DescriptorHasAction(ctrlServer) )
|
||||||
|
{
|
||||||
|
ctrlServer.ReceiveOrder();
|
||||||
|
}
|
||||||
|
|
||||||
|
//else its some IO operation on some other socket
|
||||||
|
|
||||||
|
ForwardData(false, wifiServer, &wifiServerSPY);
|
||||||
|
ForwardData(true, &wifiServerSPY, wifiServer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void help()
|
||||||
|
{
|
||||||
|
#ifdef ENABLE_VHOST
|
||||||
|
cout<<"Usage: vwifi-server [-h] [-v] [-l] [-u] [-p PORT_VHOST] [-t PORT_TCP] [-s PORT_SPY] [-c PORT_CTRL]"<<endl;
|
||||||
|
cout<<" [--help] [--version] [--lost-packets] [--use-port-in-hash] [--port-vhost PORT_VHOST] [--port-tcp PORT_TCP] [--port-spy PORT_SPY] [--port-ctrl PORT_CTRL]"<<endl;
|
||||||
|
cout<<" By default : PORT_VHOST="<< DEFAULT_WIFI_CLIENT_PORT_VHOST <<
|
||||||
|
" PORT_TCP=" << DEFAULT_WIFI_CLIENT_PORT_INET <<
|
||||||
|
" PORT_SPY=" << DEFAULT_WIFI_SPY_PORT <<
|
||||||
|
" PORT_CTRL=" << DEFAULT_CTRL_PORT <<endl;
|
||||||
|
#else
|
||||||
|
cout<<"Usage: vwifi-server [-h] [-v] [-l] [-u] [-t PORT_TCP] [-s PORT_SPY] [-c PORT_CTRL]"<<endl;
|
||||||
|
cout<<" [--help] [--version] [--lost-packets] [--use-port-in-hash] [--port-tcp PORT_TCP] [--port-spy PORT_SPY] [--port-ctrl PORT_CTRL]"<<endl;
|
||||||
|
cout<<" By default : PORT_TCP=" << DEFAULT_WIFI_CLIENT_PORT_INET <<
|
||||||
|
" PORT_SPY=" << DEFAULT_WIFI_SPY_PORT <<
|
||||||
|
" PORT_CTRL=" << DEFAULT_CTRL_PORT <<endl;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int main(int argc, char** argv)
|
||||||
|
{
|
||||||
|
int arg_idx = 1;
|
||||||
|
while (arg_idx < argc)
|
||||||
|
{
|
||||||
|
if( ! strcmp("-v", argv[arg_idx]) || ! strcmp("--version", argv[arg_idx]) )
|
||||||
|
{
|
||||||
|
cout<<"Version : "<<VERSION<<endl;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if( ! strcmp("-h", argv[arg_idx]) || ! strcmp("--help", argv[arg_idx]) )
|
||||||
|
{
|
||||||
|
help();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if( ! strcmp("-l", argv[arg_idx]) || ! strcmp("--lost-packets", argv[arg_idx]) )
|
||||||
|
{
|
||||||
|
CanLostPackets=true;
|
||||||
|
}
|
||||||
|
else if( ! strcmp("-u", argv[arg_idx]) || ! strcmp("--use-port-in-hash", argv[arg_idx]) )
|
||||||
|
{
|
||||||
|
HashUsesPort=true;
|
||||||
|
}
|
||||||
|
#ifdef ENABLE_VHOST
|
||||||
|
else if( ( ! strcmp("-p", argv[arg_idx]) || ! strcmp("--port-vhost", argv[arg_idx]) ) && (arg_idx + 1) < argc && isPositiveInt(argv[arg_idx+1]) )
|
||||||
|
{
|
||||||
|
Port_VHOST = stoi(argv[arg_idx+1]);
|
||||||
|
arg_idx++;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
else if( ( ! strcmp("-t", argv[arg_idx]) || ! strcmp("--port-tcp", argv[arg_idx]) ) && (arg_idx + 1) < argc && isPositiveInt(argv[arg_idx+1]) )
|
||||||
|
{
|
||||||
|
Port_TCP = stoi(argv[arg_idx+1]);
|
||||||
|
arg_idx++;
|
||||||
|
}
|
||||||
|
else if( ( ! strcmp("-s", argv[arg_idx]) || ! strcmp("--port-spy", argv[arg_idx]) ) && (arg_idx + 1) < argc && isPositiveInt(argv[arg_idx+1]) )
|
||||||
|
{
|
||||||
|
Port_Spy = stoi(argv[arg_idx+1]);
|
||||||
|
arg_idx++;
|
||||||
|
}
|
||||||
|
else if( ( ! strcmp("-c", argv[arg_idx]) || ! strcmp("--port-ctrl", argv[arg_idx]) ) && (arg_idx + 1) < argc && isPositiveInt(argv[arg_idx+1]) )
|
||||||
|
{
|
||||||
|
Port_Ctrl = stoi(argv[arg_idx+1]);
|
||||||
|
arg_idx++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cerr<<"Error : problem with this parameter : "<< argv[arg_idx] <<endl;
|
||||||
|
help();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
arg_idx++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return vwifi_server();
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
interface=wlan0
|
||||||
|
driver=nl80211
|
||||||
|
|
||||||
|
hw_mode=g
|
||||||
|
channel=1
|
||||||
|
ssid=mac80211_open
|
||||||
|
auth_algs=1
|
||||||
|
wpa=0
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
interface=wlan0
|
||||||
|
driver=nl80211
|
||||||
|
ssid=AP_WEP
|
||||||
|
hw_mode=g
|
||||||
|
channel=1
|
||||||
|
ignore_broadcast_ssid=0
|
||||||
|
wep_default_key=0
|
||||||
|
wep_key0="12345"
|
||||||
|
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
interface=wlan0
|
||||||
|
driver=nl80211
|
||||||
|
|
||||||
|
hw_mode=g
|
||||||
|
channel=1
|
||||||
|
ssid=mac80211_wpa
|
||||||
|
|
||||||
|
wpa=2
|
||||||
|
wpa_key_mgmt=WPA-PSK
|
||||||
|
wpa_pairwise=CCMP
|
||||||
|
wpa_passphrase=12345678
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
ctrl_interface=/var/run/wpa_supplicant
|
||||||
|
|
||||||
|
network={
|
||||||
|
ssid="mac80211_wpa"
|
||||||
|
psk="12345678"
|
||||||
|
key_mgmt=WPA-PSK
|
||||||
|
proto=WPA2
|
||||||
|
pairwise=CCMP
|
||||||
|
group=CCMP
|
||||||
|
}
|
||||||
@@ -0,0 +1,83 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
MODE="d" # dhcp , s : static
|
||||||
|
INET="wlan1"
|
||||||
|
CONN="o" # wpa : w , open : o
|
||||||
|
|
||||||
|
WPA_CONF_FILE_PATH="tests/wpa_supplicant.conf"
|
||||||
|
IP="10.0.0.2/8"
|
||||||
|
|
||||||
|
help(){
|
||||||
|
|
||||||
|
echo "Help : $0 -m s|d -c o|w interface IP_STATIC/MASQUE"
|
||||||
|
|
||||||
|
echo " -m : IP Configuration mode"
|
||||||
|
echo " d : dhcp "
|
||||||
|
echo " s : static"
|
||||||
|
|
||||||
|
echo " -c : Connection mode"
|
||||||
|
echo " o : open "
|
||||||
|
echo " w : wpa"
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if (( $# == 0 ))
|
||||||
|
then
|
||||||
|
|
||||||
|
help
|
||||||
|
exit 1
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
while getopts "m:c:" option ; do
|
||||||
|
|
||||||
|
case $option in
|
||||||
|
|
||||||
|
m) MODE="${OPTARG}"
|
||||||
|
;;
|
||||||
|
|
||||||
|
c) CONN="${OPTARG}"
|
||||||
|
;;
|
||||||
|
|
||||||
|
*) help
|
||||||
|
;;
|
||||||
|
|
||||||
|
esac
|
||||||
|
|
||||||
|
done
|
||||||
|
|
||||||
|
shift $(($OPTIND - 1))
|
||||||
|
|
||||||
|
INET=$1
|
||||||
|
IP="$2"
|
||||||
|
|
||||||
|
|
||||||
|
#######################
|
||||||
|
|
||||||
|
if [ $CONN == "w" ] ; then
|
||||||
|
|
||||||
|
wpa_supplicant -Dnl80211 -i ${INET} -c ${WPA_CONF_FILE_PATH} &
|
||||||
|
|
||||||
|
else
|
||||||
|
ip link set up ${INET}
|
||||||
|
iw dev ${INET} connect mac80211_open
|
||||||
|
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
sleep 3
|
||||||
|
|
||||||
|
if [ ${MODE} == "s" ] ; then
|
||||||
|
|
||||||
|
ip a a ${IP} dev wlan0
|
||||||
|
else
|
||||||
|
dhclient -v -i ${INET}
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,90 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Script : fast-vwifi-update
|
||||||
|
# Ecris par : David Ansart
|
||||||
|
# Ecris pour : Live Raizo / http://live-raizo.sourceforge.net
|
||||||
|
# But : Mettre à jour vwifi-server avec les positions des VMs dans GNS3
|
||||||
|
|
||||||
|
LOGIN=user
|
||||||
|
PASSWORD=user
|
||||||
|
SERVER=localhost
|
||||||
|
|
||||||
|
CERROR='\e[0;1;31m' # Rouge
|
||||||
|
SansCouleur='\e[0;m'
|
||||||
|
|
||||||
|
OptionVWifiQEmu=vwifi0
|
||||||
|
|
||||||
|
if [ -z "$(pgrep -xf '/usr/bin/python3 /usr/bin/gns3.*')" ]
|
||||||
|
then
|
||||||
|
>&2 echo -e "${CERROR}Error: Your GNS3 project must be open !!!${SansCouleur}"
|
||||||
|
exit 2
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "$(pgrep 'vwifi-server')" ]
|
||||||
|
then
|
||||||
|
>&2 echo -e "${CERROR}Error: vwifi-server is not started !!!${SansCouleur}"
|
||||||
|
exit 2
|
||||||
|
fi
|
||||||
|
|
||||||
|
# récupère l'identifiant du projet
|
||||||
|
IdProjet=$(wget -q --user="$LOGIN" --password="$PASSWORD" "http://${SERVER}:3080/v2/projects" -O - | jq -M -r --unbuffered '.[] | select (.status=="opened") | .project_id')
|
||||||
|
if [ -z "${IdProjet}" ]
|
||||||
|
then
|
||||||
|
>&2 echo -e "${CERROR}Error: No project is open !!!${SansCouleur}"
|
||||||
|
exit 2
|
||||||
|
fi
|
||||||
|
|
||||||
|
# récupère la configuration du projet
|
||||||
|
ConfigProjectGNS3="$(mktemp fast-vwifi-update.XXXXXXXXXX --tmpdir=/tmp)"
|
||||||
|
wget -q --user="$LOGIN" --password="$PASSWORD" "http://${SERVER}:3080/v2/projects/${IdProjet}/nodes" -O "${ConfigProjectGNS3}"
|
||||||
|
|
||||||
|
NbValue=0
|
||||||
|
VMWithWifi=false
|
||||||
|
|
||||||
|
IFS=$'\n'
|
||||||
|
for line in $(jq -M '.[] | select (.node_type=="qemu") | {name: .name, x: .x, y: .y, z: .z , option: .command_line} ' "${ConfigProjectGNS3}")
|
||||||
|
do
|
||||||
|
if [[ "${line}" =~ ^[[:space:]]+\"name\":.* ]]
|
||||||
|
then
|
||||||
|
((NbValue++))
|
||||||
|
# attention au decallage du print (?)
|
||||||
|
Name=$(echo "${line}" | awk -F '[:, ]' '{print $5}' | tr -d '"' )
|
||||||
|
elif [[ "${line}" =~ ^[[:space:]]+\"x\":.* ]]
|
||||||
|
then
|
||||||
|
((NbValue++))
|
||||||
|
# attention au decallage du print (?)
|
||||||
|
X=$(echo "${line}" | awk -F '[:, ]' '{print $5}')
|
||||||
|
elif [[ "${line}" =~ ^[[:space:]]+\"y\":.* ]]
|
||||||
|
then
|
||||||
|
((NbValue++))
|
||||||
|
# attention au decallage du print (?)
|
||||||
|
Y=$(echo "${line}" | awk -F '[:, ]' '{print $5}')
|
||||||
|
elif [[ "${line}" =~ ^[[:space:]]+\"z\":.* ]]
|
||||||
|
then
|
||||||
|
((NbValue++))
|
||||||
|
# attention au decallage du print (?)
|
||||||
|
Z=$(echo "${line}" | awk -F '[:, ]' '{print $5}')
|
||||||
|
elif [[ "${line}" =~ ^[[:space:]]+\"option\":.* ]]
|
||||||
|
then
|
||||||
|
((NbValue++))
|
||||||
|
CID=$(echo "${line}" | grep -E -o 'id='${OptionVWifiQEmu}',guest-cid=[[:digit:]]+' | sed 's/id='${OptionVWifiQEmu}',guest-cid=//')
|
||||||
|
if [ -n "${CID}" ]
|
||||||
|
then
|
||||||
|
VMWithWifi=true
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if (( NbValue == 5 ))
|
||||||
|
then
|
||||||
|
NbValue=0
|
||||||
|
if ${VMWithWifi}
|
||||||
|
then
|
||||||
|
echo "${CID}" "(${Name})" "${X}" "${Y}" "${Z}"
|
||||||
|
vwifi-ctrl setname "${CID}" "${Name}" > /dev/null
|
||||||
|
vwifi-ctrl set "${CID}" "${X}" "${Y}" "${Z}" > /dev/null
|
||||||
|
VMWithWifi=false
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
rm -f "${ConfigProjectGNS3}"
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
FOLDER_VWIFI='/hosthome/vwifi'
|
||||||
|
|
||||||
|
DEFAULT_PREFIX_MAC_ADDRESS='74:F8:F6'
|
||||||
|
|
||||||
|
# -------------------
|
||||||
|
|
||||||
|
cd "${FOLDER_VWIFI}"
|
||||||
|
|
||||||
|
if (( $# == 0 ))
|
||||||
|
then
|
||||||
|
NbrWifi=2
|
||||||
|
else
|
||||||
|
NbrWifi="$1"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -e /sys/module/mac80211_hwsim ]
|
||||||
|
then
|
||||||
|
OldNbrWifi=$(cat /sys/module/mac80211_hwsim/parameters/radios)
|
||||||
|
if (( NbrWifi != OldNbrWifi ))
|
||||||
|
then
|
||||||
|
modprobe -r mac80211_hwsim
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
modprobe mac80211_hwsim radios=0
|
||||||
|
|
||||||
|
hexchars="0123456789ABCDEF"
|
||||||
|
middle=$( for i in {1..4} ; do echo -n ${hexchars:$(( $RANDOM % 16 )):1} ; done | sed -e 's/\(..\)/:\1/g' )
|
||||||
|
MAC_ADDRESS="${DEFAULT_PREFIX_MAC_ADDRESS}${middle}"
|
||||||
|
|
||||||
|
./vwifi-add-interfaces "${NbrWifi}" "${MAC_ADDRESS}"
|
||||||
|
|
||||||
|
if [ "$(tty)" = '/dev/ttyS0' ]
|
||||||
|
then
|
||||||
|
# In Console Mode -> Tmux can be usefull
|
||||||
|
if [ -v TMUX ]
|
||||||
|
then
|
||||||
|
# Already in tmux
|
||||||
|
./vwifi-client
|
||||||
|
else
|
||||||
|
tmux new-session -s vwifi "bash --rcfile <(echo '. ~/.bashrc; ./vwifi-client')" ; detach &> /dev/null
|
||||||
|
|
||||||
|
tmux attach -t vwifi
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
./vwifi-client
|
||||||
|
fi
|
||||||
Reference in New Issue
Block a user