diff --git a/Dockerfile b/Dockerfile
index 58171e8..4e21df0 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,34 +1,16 @@
FROM debian:jessie
-RUN apt-get update \
- && apt-get install -y curl \
- && curl -s https://packagecloud.io/install/repositories/rolandoislas/drc-sim/script.deb.sh | bash
-RUN apt-get update \
- && apt-get install -y \
- wpasupplicant-drc \
- python3 \
- python3-dev \
- python3-pip \
- libffi-dev \
- zlib1g-dev \
- libjpeg-dev \
- net-tools \
- wireless-tools \
- sysvinit-utils \
- psmisc \
- libavcodec-dev \
- libswscale-dev \
- rfkill \
- isc-dhcp-client \
- ifmetric
-
ADD drc*.py /root/
ADD setup.py /root/
ADD src/ /root/src/
ADD resources/ /root/resources/
ADD MANIFEST.in /root/
-RUN cd /root/ && python3 setup.py install
+ADD install.sh /root/
+
+RUN apt-get update \
+ && cd /root/ \
+ && ./install.sh local
ENV TERM xterm
-ENTRYPOINT ["drc-sim-backend.py", "--cli"]
+ENTRYPOINT ["drc-sim-backend", "--cli"]
CMD ["-h"]
diff --git a/drc-info.py b/drc-info.py
index 5b75e87..2b6de27 100644
--- a/drc-info.py
+++ b/drc-info.py
@@ -6,19 +6,24 @@
import time
from threading import Thread
-from src.server.data import constants
from src.server.data.struct import input, command
+PORT_WII_MSG = 50010
+PORT_WII_VID = 50020
+PORT_WII_AUD = 50021
+PORT_WII_HID = 50022
+PORT_WII_CMD = 50023
+
sock_cmd = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
-sock_cmd.bind(("192.168.1.10", constants.PORT_WII_CMD))
+sock_cmd.bind(("192.168.1.10", PORT_WII_CMD))
sock_msg = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
-sock_msg.bind(("192.168.1.10", constants.PORT_WII_MSG))
+sock_msg.bind(("192.168.1.10", PORT_WII_MSG))
sock_hid = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
-sock_hid.bind(("192.168.1.10", constants.PORT_WII_HID))
+sock_hid.bind(("192.168.1.10", PORT_WII_HID))
sock_vid = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
-sock_vid.bind(("192.168.1.10", constants.PORT_WII_VID))
+sock_vid.bind(("192.168.1.10", PORT_WII_VID))
sock_aud = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
-sock_aud.bind(("192.168.1.10", constants.PORT_WII_AUD))
+sock_aud.bind(("192.168.1.10", PORT_WII_AUD))
json_dump = {}
@@ -50,7 +55,7 @@ def print_packet_cmd(sock):
def send_cmd(data):
- sock_cmd.sendto(data, ("192.168.1.11", constants.PORT_WII_CMD + 100))
+ sock_cmd.sendto(data, ("192.168.1.11", PORT_WII_CMD + 100))
def send_command_from_string(command_string, sid):
diff --git a/drc-sim-backend.py b/drc-sim-backend.py
index 09ce87c..d2fdbf1 100644
--- a/drc-sim-backend.py
+++ b/drc-sim-backend.py
@@ -1,12 +1,12 @@
from src.server.data import constants
-from src.server.data.config_server import ConfigServer
-from src.server.util.logging.logger_wpa import LoggerWpa
from src.server.data.args import Args
+from src.server.data.config_general import ConfigGeneral
from src.server.ui.cli.cli_main import CliMain
from src.server.util.logging.logger import Logger
from src.server.util.logging.logger_backend import LoggerBackend
from src.server.util.logging.logger_cli import LoggerCli
from src.server.util.logging.logger_gui import LoggerGui
+from src.server.util.logging.logger_wpa import LoggerWpa
from src.server.util.os_util import OsUtil
@@ -74,8 +74,8 @@ def main():
:return: None
"""
Args.parse_args()
- ConfigServer.load()
- ConfigServer.save()
+ ConfigGeneral.load()
+ ConfigGeneral.save()
init_loggers()
Logger.info("Initializing drc-sim-backend version %s", constants.VERSION)
Logger.info("Using \"%s\" as home folder.", constants.PATH_ROOT)
diff --git a/install.sh b/install.sh
index 36127ee..12a078d 100755
--- a/install.sh
+++ b/install.sh
@@ -6,6 +6,7 @@
REPO_DRC_SIM="https://github.com/rolandoislas/drc-sim.git"
REPO_WPA_SUPPLICANT_DRC="https://github.com/rolandoislas/drc-hostap.git"
+REPO_DRC_SIM_C="https://github.com/rolandoislas/drc-sim-c.git"
INSTALL_DIR="/opt/drc_sim/"
PATH_APPLICATION_LAUNCHER="/usr/share/applications/drc-sim-backend.desktop"
PATH_ICON="/usr/share/icons/hicolor/512x512/apps/drcsimbackend.png"
@@ -19,11 +20,13 @@ check_os() {
if command -v apt-get &> /dev/null; then
echo "Command apt-get found."
# Backend dependencies
- dependencies=("python3" "python3-dev" "python3-pip" "libffi-dev" "zlib1g-dev" "libjpeg-dev"
- "net-tools" "wireless-tools" "sysvinit-utils" "psmisc" "libavcodec-dev" "libswscale-dev" "rfkill"
+ dependencies=("python3" "python3-pip"
+ "net-tools" "wireless-tools" "sysvinit-utils" "psmisc" "rfkill"
"isc-dhcp-client" "ifmetric" "python3-tk" "gksu")
# Wpa supplicant compile dependencies
dependencies+=("git" "libssl-dev" "libnl-genl-3-dev" "gcc" "make")
+ # DRC Sim Server C++
+ dependencies+=("libavcodec-dev" "libswscale-dev" "libjpeg-dev" "cmake")
else
echo "The command apt-get was not found. This OS is not supported."
exit 1
@@ -108,18 +111,13 @@ get_git() {
# Compiles wpa_supplicant after fetching it from git
compile_wpa() {
- if command -v wpa_supplicant_drc &> /dev/null && command -v wpa_cli_drc &> /dev/null; then
- echo "Skipping wpa_supplicant compile"
- return 0
- fi
get_git ${REPO_WPA_SUPPLICANT_DRC} "wpa"
- echo "drc-hostap"
echo "Compiling wpa_supplicant_drc"
- wpa_dir="${INSTALL_DIR}wpa/wpa_supplicant/"
+ compile_dir="${INSTALL_DIR}wpa/wpa_supplicant/"
cur_dir="${PWD}"
- cd "${wpa_dir}" &> /dev/null || return 1
+ cd "${compile_dir}" &> /dev/null || return 1
cp ../conf/wpa_supplicant.config ./.config &> /dev/null || return 1
- compile_log="${wpa_dir}make.log"
+ compile_log="${compile_dir}make.log"
echo "Compile log at ${compile_log}"
make &> ${compile_log} || return 1
echo "Installing wpa_supplicant_drc and wpa_cli_drc to /usr/local/bin"
@@ -129,8 +127,26 @@ compile_wpa() {
return 0
}
+# Compiles drc_sim_c after fetching it from git
+compile_drc_sim_c() {
+ get_git ${REPO_DRC_SIM_C} "drc_sim_c"
+ echo "Compiling drc_sim_c"
+ compile_dir="${INSTALL_DIR}drc_sim_c/"
+ cur_dir="${PWD}"
+ cd "${compile_dir}" &> /dev/null || return 1
+ compile_log="${compile_dir}make.log"
+ echo "Compile log at ${compile_log}"
+ cmake "$compile_dir" &> /dev/null || return 1
+ make &> ${compile_log} || return 1
+ echo "Installing drc_sim_c to /usr/local/bin"
+ make install &> /dev/null || return 1
+ cd "${cur_dir}" &> /dev/null || return 1
+ return 0
+}
+
# Installs drc-sim in a virtualenv
install_drc_sim() {
+ echo "Installing DRC Sim Server GUI/CLI Utility"
# Paths
drc_dir="${INSTALL_DIR}drc/"
cur_dir="${PWD}"
@@ -158,8 +174,9 @@ install_drc_sim() {
echo "Activating virtualenv"
source "${venv_dir}bin/activate" || return 1
# Remove an existing install of drc-sim
- #echo "Attempting to remove previous installations"
- #pip uninstall drc-sim &> /dev/null || return 1
+ echo "Attempting to remove previous installations"
+ pip uninstall -y drcsim &> /dev/null || \
+ echo "Failed to remove the previous installation. Attempting to install anyway."
# Set the directory
cd "${drc_dir}" &> /dev/null || return 1
# Branch to checkout
@@ -268,6 +285,7 @@ post_install() {
install() {
install_dependencies
pass_fail compile_wpa "Compiled wpa_supplicant" "Failed to compile wpa_supplicant"
+ pass_fail compile_drc_sim_c "Compiled drc_sim_c" "Failed to compile drc_sim_c"
pass_fail install_drc_sim "Created virtualenv for drc-sim" "Failed to create virtualenv for drc-sim"
pass_fail install_launch_script "Launch script installed." "Failed to install launch script"
pass_fail install_desktop_launcher "Installed application launcher" "Failed to install desktop application launcher"
diff --git a/license.txt b/license.txt
new file mode 100644
index 0000000..f0d12d6
--- /dev/null
+++ b/license.txt
@@ -0,0 +1,358 @@
+Copyright (C) 2017 Rolando Islas
+
+This file is part of DRC Sim Server.
+
+DRC Sim Server is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 2 of the License, or
+(at your option) any later version.
+
+DRC Sim Server is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with DRC Sim Server. If not, see .
+
+---------------------------------------------------------------------------
+
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the 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 Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ {description}
+ Copyright (C) {year} {fullname}
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) year name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ {signature of Ty Coon}, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.
\ No newline at end of file
diff --git a/readme.md b/readme.md
index 4e310f4..394e3c3 100644
--- a/readme.md
+++ b/readme.md
@@ -4,7 +4,7 @@ DRC Sim Server
Stable: [![Build Status](https://travis-ci.org/rolandoislas/drc-sim.svg?branch=master)](https://travis-ci.org/rolandoislas/drc-sim)
Dev: [![Build Status](https://travis-ci.org/rolandoislas/drc-sim.svg?branch=develop)](https://travis-ci.org/rolandoislas/drc-sim)
-Fork of drc-sim with a server/client implementation. This allows for a broader range of clients.
+DRC Sim Server is a utility for pairing a computer to a Wii U to emulate a gamepad.
It needs a [client] for full functionality.
@@ -16,9 +16,24 @@ See the [wiki] for more info.
# Credits
-[drc-sim] \(original\) by memahaxx
+[drc-sim] \(original\) by [memahaxx]
+- The original Python codebase
+
+[libdrc documentation] by memahaxx
+- Gamepad and Wii U software and hardware details
[drc-sim-keyboard] by justjake
+- The readme that got me set up initially
+
+# Additional Software
+
+[wpa_supplicant] modified by memahaxx
+
+[drc_sim_c] drc-sim rewritten in C++
+
+[netifaces] Python network interfaces library
+
+[pexpect] Python process interaction library
@@ -27,3 +42,9 @@ See the [wiki] for more info.
[Installation instructions]: https://github.com/rolandoislas/drc-sim/wiki/Install
[client]: https://github.com/rolandoislas/drc-sim-client/wiki/Home
[wiki]: https://github.com/rolandoislas/drc-sim/wiki/Home
+[wpa_supplicant]: https://github.com/rolandoislas/drc-hostap
+[drc_sim_c]: https://github.com/rolandoislas/drc-sim-c
+[memahaxx]: https://bitbucket.org/memahaxx/
+[libdrc documentation]: http://libdrc.org/docs/index.html
+[netifaces]: https://pypi.python.org/pypi/netifaces
+[pexpect]: https://pypi.python.org/pypi/pexpect
\ No newline at end of file
diff --git a/setup.py b/setup.py
index 176be67..93e78a8 100644
--- a/setup.py
+++ b/setup.py
@@ -9,7 +9,7 @@
setup(name='drcsim',
version=constants.VERSION,
description='Wii U gamepad simulator.',
- install_requires=['construct==2.8.11', 'Pillow==3.4.2', 'cffi==1.9.1', 'netifaces==0.10.5', 'pexpect==4.2.1'],
+ install_requires=['netifaces==0.10.5', 'pexpect==4.2.1'],
packages=find_packages(),
include_package_data=True,
data_files=[('resources/config', ['resources/config/get_psk.conf']),
diff --git a/src/server/control/__init__.py b/src/server/control/__init__.py
deleted file mode 100644
index e69de29..0000000
diff --git a/src/server/control/gamepad.py b/src/server/control/gamepad.py
deleted file mode 100644
index c22cd7d..0000000
--- a/src/server/control/gamepad.py
+++ /dev/null
@@ -1,164 +0,0 @@
-import select
-import socket
-import time
-from threading import Thread
-
-from src.server.control.server import Server
-from src.server.control.util.controller import Controller
-from src.server.data.args import Args
-from src.server.data.config_server import ConfigServer
-from src.server.net import socket_handlers
-from src.server.net import sockets
-from src.server.util.logging.logger_backend import LoggerBackend
-from src.server.util.status_sending_thread import StatusSendingThread
-
-
-class Gamepad(StatusSendingThread):
- NO_PACKETS = "NO_PACKETS"
- STOPPED = "STOPPED"
- RUNNING = "RUNNING"
- WAITING_FOR_PACKET = "WAITING_FOR_PACKET"
- CRASHED = "CRASHED"
-
- def __init__(self):
- """
- Backend server handler. Processes packets from the Wii U and servers clients.
- """
- super().__init__()
- self.backend_thread = None
- self.set_status(self.STOPPED)
- self.running = False
- self.wii_packet_time = time.time()
- self.has_received_packet = False
- self.server = Server()
-
- def start(self):
- """
- Start the main thread
- :return: None
- """
- ConfigServer.load()
- ConfigServer.save()
- self.print_init()
- sockets.Sockets.connect()
- socket_handlers.SocketHandlers.create()
- self.running = True
- LoggerBackend.debug("Starting backend thread")
- self.backend_thread = Thread(target=self.update, name="Backend Thread")
- self.backend_thread.start()
- LoggerBackend.debug("Post backend thread")
-
- def print_init(self):
- """
- Log the initialization messages
- :return: None
- """
- LoggerBackend.info("Started drc-sim-backend")
- self.print_config()
- LoggerBackend.info("Waiting for Wii U packets")
-
- @staticmethod
- def handle_wii_packet(sock):
- """
- Receive data from a socket and pass it to the appropriate packet handler.
- :param sock: Wii U datagram Socket
- :return: None
- """
- data = sock.recv(2048)
- # Dump packet
- if Args.args.dump:
- if sock == sockets.Sockets.WII_VID_S:
- with open("video.bin", "ab") as video_packet:
- video_packet.write(data + b"|\n")
- # Handle packet
- try:
- socket_handlers.SocketHandlers.wii_handlers[sock].update(data)
- except socket.error as e:
- LoggerBackend.warn(str(e) + str(e.errno))
-
- def handle_sockets(self):
- """
- Check if any sockets have data and pass then to their handler.
- :return: None
- """
- # Group all sockets
- rlist, wlist, xlist = select.select(socket_handlers.SocketHandlers.get_handler_keys(),
- (), (), 0.001)
- if rlist:
- # Notify once first packet is received
- if not self.has_received_packet:
- self.has_received_packet = True
- LoggerBackend.info("Received Wii U packet")
- # Update last packet time
- self.wii_packet_time = time.time()
- for sock in rlist:
- # Wii socket
- if sock in socket_handlers.SocketHandlers.wii_handlers.keys():
- self.handle_wii_packet(sock)
- # Server media socket
- if sock in socket_handlers.SocketHandlers.server_media_handlers.keys():
- self.server.add_media_client(sock)
- # Command socket
- if sock in socket_handlers.SocketHandlers.server_command_handlers.keys():
- self.server.handle_client_command_packet(sock)
-
- def update(self):
- """
- Main loop
- :return: None
- """
- while self.running:
- try:
- self.check_last_packet_time()
- self.handle_sockets()
- Controller.update()
- except Exception as e:
- self.set_status(self.CRASHED)
- LoggerBackend.throw(e)
-
- def close(self):
- """
- Stop the backend thread
- :return: None
- """
- if not self.running:
- LoggerBackend.debug("Ignored stop request: already stopped")
- return
- LoggerBackend.debug("Stopping backend")
- self.running = False
- try:
- self.backend_thread.join()
- except RuntimeError as e:
- LoggerBackend.exception(e)
- LoggerBackend.debug("Closing handlers")
- if socket_handlers.SocketHandlers.wii_handlers:
- for s in socket_handlers.SocketHandlers.wii_handlers.values():
- s.close()
- LoggerBackend.debug("Closing sockets")
- sockets.Sockets.close()
- self.clear_status_change_listeners()
- LoggerBackend.debug("Backend closed")
-
- def check_last_packet_time(self):
- """
- Checks if the server should shutdown after not receiving packets for more than a minute
- :return: None
- """
- if not self.has_received_packet:
- status = self.WAITING_FOR_PACKET
- elif time.time() - self.wii_packet_time >= 60:
- status = Gamepad.NO_PACKETS
- else:
- status = Gamepad.RUNNING
- self.set_status(status)
-
- @staticmethod
- def print_config():
- """
- Logs the server configuration info
- :return: None
- """
- LoggerBackend.info("Config: FPS %d", ConfigServer.fps)
- LoggerBackend.info("Config: Input Delay %f", ConfigServer.input_delay)
- LoggerBackend.info("Config: Image Quality %d", ConfigServer.quality)
- LoggerBackend.info("Config: Stream Audio %s", ConfigServer.stream_audio)
diff --git a/src/server/control/server.py b/src/server/control/server.py
deleted file mode 100644
index 8b55629..0000000
--- a/src/server/control/server.py
+++ /dev/null
@@ -1,26 +0,0 @@
-import socket
-
-from src.server.net.codec import Codec
-from src.server.net import socket_handlers
-from src.server.net import sockets
-from src.server.util.logging.logger_backend import LoggerBackend
-
-
-class Server:
- def __init__(self):
- pass
-
- @staticmethod
- def handle_client_command_packet(sock):
- try:
- data, address = sock.recvfrom(2048)
- command, data = Codec.decode_command(data)
- socket_handlers.SocketHandlers.server_command_handlers[sock].update(address, command, data)
- except socket.error as e:
- LoggerBackend.warn(e.strerror)
-
- @staticmethod
- def add_media_client(sock):
- client, address = sock.accept()
- client.settimeout(1)
- sockets.Sockets.add_client_socket((client, address), socket_handlers.SocketHandlers.server_media_handlers[sock])
diff --git a/src/server/control/util/__init__.py b/src/server/control/util/__init__.py
deleted file mode 100644
index e69de29..0000000
diff --git a/src/server/control/util/controller.py b/src/server/control/util/controller.py
deleted file mode 100644
index f11efa8..0000000
--- a/src/server/control/util/controller.py
+++ /dev/null
@@ -1,138 +0,0 @@
-import time
-
-import array
-
-from src.server.data import constants
-from src.server.data.config_server import ConfigServer
-from src.server.data.struct import input
-from src.server.net import sockets
-from src.server.net.codec import Codec
-
-
-class Controller:
- hid_seq_id = 0
- hid_update_timestamp = 0
- HID_UPDATE_INTERVAL = int((1 / 10) * 1000) # should be 180 per second FIXME python 3 sockets are slow
- # Button buffers
- button_buffer = (0, 0)
- extra_button_buffer = (0, 0)
- joystick_buffer = ((0, 0, 0, 0), 0)
- touch_buffer = (((-1, -1), (-1, -1)), 0)
- send_audio = (False, 0)
-
- def __init__(self):
- pass
-
- @classmethod
- def scale_stick(cls, old_value, old_min, old_max, new_min, new_max):
- return int((((old_value - old_min) * (new_max - new_min)) / (old_max - old_min)) + new_min)
-
- @classmethod
- def get_touch_input_report(cls, report):
- point, screen = cls.get_touch_input()
- if point[0] >= 0 and point[1] >= 0:
- x = cls.scale_stick(point[0], 0, screen[0], 200, 3800)
- y = cls.scale_stick(point[1], 0, screen[1], 3800, 200)
- z1 = 2000
-
- for i in range(10):
- report[18 + i * 2 + 0] = 0x8000 | x
- report[18 + i * 2 + 1] = 0x8000 | y
-
- report[18 + 0 * 2 + 0] |= ((z1 >> 0) & 7) << 12
- report[18 + 0 * 2 + 1] |= ((z1 >> 3) & 7) << 12
- report[18 + 1 * 2 + 0] |= ((z1 >> 6) & 7) << 12
- report[18 + 1 * 2 + 1] |= ((z1 >> 9) & 7) << 12
- return report
-
- # Getters
-
- @classmethod
- def is_input_within_timeframe(cls, input_buffer):
- if time.time() - input_buffer[1] <= ConfigServer.input_delay:
- return True
- return False
-
- @classmethod
- def get_button_input(cls):
- if not cls.is_input_within_timeframe(cls.button_buffer):
- return 0
- return cls.button_buffer[0]
-
- @classmethod
- def get_extra_button_input(cls):
- if not cls.is_input_within_timeframe(cls.extra_button_buffer):
- return 0
- return cls.extra_button_buffer[0]
-
- @classmethod
- def get_joystick_input(cls, joystick_id):
- if not cls.is_input_within_timeframe(cls.joystick_buffer):
- return 0
- return cls.joystick_buffer[0][joystick_id]
-
- @classmethod
- def get_touch_input(cls):
- if not cls.is_input_within_timeframe(cls.touch_buffer):
- return (-1, -1), (-1, -1)
- return cls.touch_buffer[0]
-
- @classmethod
- def get_send_audio(cls):
- if not cls.is_input_within_timeframe(cls.send_audio):
- return False
- return cls.send_audio
-
- @classmethod
- def set_button_input(cls, data):
- cls.button_buffer = Codec.decode_input(data)
-
- @classmethod
- def set_extra_button_input(cls, data):
- cls.extra_button_buffer = Codec.decode_input(data)
-
- @classmethod
- def set_touch_input(cls, data):
- cls.touch_buffer = Codec.decode_input(data)
-
- @classmethod
- def set_joystick_input(cls, data):
- cls.joystick_buffer = Codec.decode_input(data)
-
- @classmethod
- def set_send_audio(cls, data):
- cls.send_audio = Codec.decode_input(data)
-
- @classmethod
- def send_hid_update(cls):
- report_array = array.array("H", b"\x00" * input.input_data.sizeof())
- report_array = cls.get_touch_input_report(report_array) # TODO handle this in the struct
- report = input.input_data.parse(report_array.tobytes())
-
- report.sequence_id = cls.hid_seq_id
- report.buttons = cls.get_button_input()
- report.power_status = 0
- report.battery_charge = 0
- report.extra_buttons = cls.get_extra_button_input()
- report.left_stick_x = 8 + int(cls.get_joystick_input(0) * 8)
- report.left_stick_y = 8 - int(cls.get_joystick_input(1) * 8)
- report.right_stick_x = 8 + int(cls.get_joystick_input(2) * 8)
- report.right_stick_y = 8 - int(cls.get_joystick_input(3) * 8)
- report.audio_volume = 0
- report.accel_x = 0
- report.accel_y = 0
- report.accel_z = 0
- report.gyro_roll = 0
- report.gyro_yaw = 0
- report.gyro_pitch = 0
- report.fw_version_neg = 215
-
- sockets.Sockets.WII_HID_S.sendto(input.input_data.build(report), ('192.168.1.10', constants.PORT_WII_HID))
- cls.hid_seq_id = (cls.hid_seq_id + 1) % 65535
-
- @classmethod
- def update(cls):
- timestamp = time.time() * 1000.
- if timestamp - cls.hid_update_timestamp >= cls.HID_UPDATE_INTERVAL:
- cls.hid_update_timestamp = timestamp
- cls.send_hid_update()
diff --git a/src/server/data/args.py b/src/server/data/args.py
index 1e32e3a..d7b4434 100644
--- a/src/server/data/args.py
+++ b/src/server/data/args.py
@@ -2,6 +2,8 @@
import sys
+from src.server.data import constants
+
class Args:
args = None
@@ -11,7 +13,8 @@ def __init__(self):
@staticmethod
def parse_args():
- arg_parser = argparse.ArgumentParser(description="Drc-sim backend decodes packets and serves clients")
+ arg_parser = argparse.ArgumentParser(description="%s provides an easy launcher for drc_sim_c and "
+ "wpa_supplicant_drc" % constants.NAME)
# Logging
arg_parser.add_argument("-d", "--debug", action="store_const", const=True, default=False,
help="debug output")
@@ -23,9 +26,9 @@ def parse_args():
help="verbose debug output")
arg_parser.add_argument("-c", "--cli", action="store_const", const=True, default=False,
help="disable gui")
- # Dump
- arg_parser.add_argument("-p", "--dump", action="store_const", const=True, default=False,
- help="Dumps Wii U packets")
+ # Disable server
+ arg_parser.add_argument("--disable-server", "--disable_server", action="store_const", const=True, default=False,
+ help="dev: disable packet handling and serving")
# CLI
args = ["-c", "--cli", "-h", "--help"]
found = False
@@ -38,6 +41,7 @@ def parse_args():
run_server = subparsers.add_parser("run_server")
run_server.add_argument("wii_u_interface", type=str)
run_server.add_argument("normal_interface", type=str)
+ run_server.add_argument("-region", type=str, default="none")
# Get Key
get_key = subparsers.add_parser("get_key")
get_key.add_argument("wii_u_interface", type=str)
diff --git a/src/server/data/buttons.py b/src/server/data/buttons.py
deleted file mode 100644
index 3991cd9..0000000
--- a/src/server/data/buttons.py
+++ /dev/null
@@ -1,18 +0,0 @@
-# Buttons
-BUTTON_A = 0x8000
-BUTTON_B = 0x4000
-BUTTON_X = 0x2000
-BUTTON_Y = 0x1000
-BUTTON_L = 0x0020
-BUTTON_R = 0x0010
-BUTTON_ZL = 0x0080
-BUTTON_ZR = 0x0040
-BUTTON_MINUS = 0x0004
-BUTTON_PLUS = 0x0008
-BUTTON_HOME = 0x0002
-BUTTON_L3 = 0x08
-BUTTON_R3 = 0x04
-BUTTON_LEFT = 0x800
-BUTTON_RIGHT = 0x400
-BUTTON_DOWN = 0x100
-BUTTON_UP = 0x200
diff --git a/src/server/data/config_server.py b/src/server/data/config_general.py
similarity index 60%
rename from src/server/data/config_server.py
rename to src/server/data/config_general.py
index 208eeb7..2edac4d 100644
--- a/src/server/data/config_server.py
+++ b/src/server/data/config_general.py
@@ -1,13 +1,12 @@
from src.server.data.config import Config
-class ConfigServer:
+class ConfigGeneral:
scan_timeout = None
config = Config()
stream_audio = None
input_delay = None
- quality = None
- fps = None
+ video_quality = None
stream_video = None
def __init__(self):
@@ -19,18 +18,17 @@ def load(cls):
# Audio
cls.stream_audio = cls.config.get_boolean("AUDIO", "stream", True, "Stream audio to clients")
# Input
- cls.input_delay = cls.config.get_float("INPUT", "delay", 0, 1, 0.1, "Amount of time to send input to Wii")
+ cls.input_delay = cls.config.get_int("INPUT", "delay", 0, 1000, 100, "Amount of time in milliseconds to send "
+ "input to the Wii U")
# Video
- cls.quality = cls.config.get_int("VIDEO", "quality", 1, 100, 75, "Quality of video stream. Sends uncompressed "
- "data at 100\n"
- "5/10/15 low - 75 lan - 100 loopback")
- cls.fps = cls.config.get_int("VIDEO", "fps", 1, 60, 30, "FPS of video stream. No limit if set to 60\n"
- "10 low - 30 lan - 60 loopback")
+ cls.video_quality = cls.config.get_int("VIDEO", "quality", 0, 100, 75, "Quality of video stream.\n"
+ "5/10/15 low - 75 lan - 100 loopback\n"
+ "There is latency at 100.")
cls.stream_video = cls.config.get_boolean("VIDEO", "stream", True, "Stream video to clients")
# General
- cls.scan_timeout = cls.config.get_int("GENERAL", "scan_timeout", 0, 60 * 5, 60 * 2, "Sets the time they server "
- "is allowed to scan for the"
- "Wii U network")
+ cls.scan_timeout = cls.config.get_int("GENERAL", "scan_timeout", 0, 60 * 5, 60 * 2, "Sets the time "
+ "allowed to scan for the "
+ "Wii U")
@classmethod
def save(cls):
diff --git a/src/server/data/constants.py b/src/server/data/constants.py
index 538d534..21bafec 100644
--- a/src/server/data/constants.py
+++ b/src/server/data/constants.py
@@ -1,36 +1,9 @@
import os
# Info
-VERSION = "1.6"
+VERSION = "2.0"
NAME = "DRC SIM Server"
-# Port
-PORT_WII_MSG = 50010
-PORT_WII_VID = 50020
-PORT_WII_AUD = 50021
-PORT_WII_HID = 50022
-PORT_WII_CMD = 50023
-PORT_SERVER_VID = 50000
-PORT_SERVER_AUD = 50001
-PORT_SERVER_CMD = 50002
-
-# Video
-WII_VIDEO_WIDTH = 848
-WII_VIDEO_HEIGHT = 480
-WII_CAMERA_WIDTH = 640
-WII_CAMERA_HEIGHT = 480
-
-# Command
-COMMAND_REGISTER = b"REGISTER"
-COMMAND_INPUT_BUTTON = b"INPUT_BUTTON"
-COMMAND_INPUT_L3R3 = b"INPUT_L3R3"
-COMMAND_INPUT_TOUCH = b"INPUT_TOUCH"
-COMMAND_INPUT_JOYSTICK = b"INPUT_JOYSTICK"
-COMMAND_VIBRATE = b"VIBRATE"
-COMMAND_PING = b"PING"
-COMMAND_PONG = b"PONG"
-COMMAND_INPUT_MIC_BLOW = b"INPUT_MIC_BLOW"
-
# Paths
PATH_ROOT = os.path.expanduser("~/.drc-sim/")
PATH_LOG_DIR = os.path.join(PATH_ROOT, "log/")
@@ -39,3 +12,4 @@
PATH_CONF_NETWORK_MANAGER = "/etc/NetworkManager/NetworkManager.conf"
PATH_TMP = "/tmp/drc-sim/"
PATH_CONF_CONNECT_TMP = os.path.join(PATH_TMP, "get_psk.conf")
+PATH_LOG_DRC_SIM_C = os.path.join(PATH_LOG_DIR, "drc_sim_c.log")
diff --git a/src/server/data/h264decoder.py b/src/server/data/h264decoder.py
deleted file mode 100644
index fc7c47c..0000000
--- a/src/server/data/h264decoder.py
+++ /dev/null
@@ -1,147 +0,0 @@
-from cffi import FFI
-from cffi import VerificationError
-
-from src.server.data import constants
-from src.server.util.logging.logger import Logger
-
-
-# TODO static alloc in_data and make interface for reading/writing directly to it
-# remove array.array usage of calling code
-
-
-class H264Decoder:
- def __init_ffi(self):
- self.ffi = FFI()
- self.ffi.cdef('''
- // AVCODEC
-
- enum AVPixelFormat { AV_PIX_FMT_YUV420P, AV_PIX_FMT_RGB24, ... };
-
- void avcodec_register_all(void);
-
- struct AVPacket { ...; uint8_t *data; int size; ...; };
- void av_init_packet(struct AVPacket *pkt);
-
- enum AVCodecID { AV_CODEC_ID_H264, ... };
- struct AVCodec *avcodec_find_decoder(enum AVCodecID id);
-
- struct AVCodecContext *avcodec_alloc_context3(struct AVCodec *codec);
-
- int avcodec_open2(struct AVCodecContext *avctx, struct AVCodec *codec,
- struct AVDictionary **options);
-
- struct AVFrame { uint8_t *data[8]; int linesize[8]; ...; int key_frame; ...; };
- struct AVFrame *av_frame_alloc(void);
-
- int avcodec_decode_video2(struct AVCodecContext *avctx, struct AVFrame *picture,
- int *got_picture_ptr, struct AVPacket *avpkt);
-
- int avcodec_close(struct AVCodecContext *avctx);
-
- void av_free(void *ptr);
-
- int av_image_get_buffer_size(enum AVPixelFormat pix_fmt, int width, int height, int align);
-
- int av_image_fill_arrays(uint8_t *dst_data[4], int dst_linesize[4], const uint8_t *src,
- enum AVPixelFormat pix_fmt, int width, int height, int align);
-
- // SWSCALE
-
- #define SWS_BILINEAR ...
- #define SWS_FAST_BILINEAR ...
- struct SwsContext *sws_getContext(int srcW, int srcH, enum AVPixelFormat srcFormat,
- int dstW, int dstH, enum AVPixelFormat dstFormat,
- int flags, struct SwsFilter *srcFilter,
- struct SwsFilter *dstFilter, const double *param);
-
- int sws_scale(struct SwsContext *c, const uint8_t *const srcSlice[],
- const int srcStride[], int srcSliceY,
- int srcSliceH, uint8_t *const dst[],
- const int dstStride[]);
-
- void sws_freeContext(struct SwsContext *c);
- ''')
- try:
- self.ns = self.ffi.verify(source='''
- #include
- #include
- ''', libraries=['avcodec', 'swscale'])
- except VerificationError as e:
- Logger.throw(e, "Decoder error. Please open an issue on GitHub with the crash info.")
- raise e # Base logger does not raise thrown errors
-
- def __init_avcodec(self):
- self.ns.avcodec_register_all()
-
- self.av_packet = self.ffi.new('struct AVPacket *')
- self.ns.av_init_packet(self.av_packet)
-
- self.codec = self.ns.avcodec_find_decoder(self.ns.AV_CODEC_ID_H264)
- assert self.codec
-
- self.context = self.ns.avcodec_alloc_context3(self.codec)
- assert self.context
-
- assert self.ns.avcodec_open2(self.context, self.codec, self.ffi.NULL) >= 0
-
- self.frame = self.ns.av_frame_alloc()
- assert self.frame
- self.got_frame = self.ffi.new('int *')
- self.out_frame = self.ns.av_frame_alloc()
-
- def __init__(self):
- self.out_buffer, self.sws_context = None, None
- self.__init_ffi()
- self.__init_avcodec()
- self.update_dimensions()
-
- def close(self):
- self.ns.sws_freeContext(self.sws_context)
- self.ns.av_free(self.out_frame)
-
- self.ns.avcodec_close(self.context)
- self.ns.av_free(self.context)
- self.ns.av_free(self.frame)
-
- def update_dimensions(self):
- if self.sws_context is not None:
- self.ns.sws_freeContext(self.sws_context)
- self.sws_context = self.ns.sws_getContext(
- constants.WII_VIDEO_WIDTH, constants.WII_VIDEO_HEIGHT, self.ns.AV_PIX_FMT_YUV420P,
- constants.WII_VIDEO_WIDTH, constants.WII_VIDEO_HEIGHT, self.ns.AV_PIX_FMT_RGB24,
- self.ns.SWS_FAST_BILINEAR,
- self.ffi.NULL,
- self.ffi.NULL, self.ffi.NULL)
-
- bytes_req = self.ns.av_image_get_buffer_size(self.ns.AV_PIX_FMT_RGB24, constants.WII_VIDEO_WIDTH,
- constants.WII_VIDEO_HEIGHT, 1)
- self.out_buffer = self.ffi.new('uint8_t [%i]' % bytes_req)
- self.ns.av_image_fill_arrays(
- self.out_frame.data,
- self.out_frame.linesize,
- self.out_buffer,
- self.ns.AV_PIX_FMT_RGB24,
- constants.WII_VIDEO_WIDTH, constants.WII_VIDEO_HEIGHT, 1)
-
- def get_image_buffer(self, encoded_nalu):
- in_data = self.ffi.new('uint8_t []', encoded_nalu)
- self.av_packet.data = in_data
- self.av_packet.size = len(encoded_nalu)
-
- length = self.ns.avcodec_decode_video2(self.context, self.frame, self.got_frame, self.av_packet)
- if length < 0:
- raise Exception('avcodec_decode_video2')
- elif length != self.av_packet.size:
- raise Exception('expected to decode a single complete frame')
- elif self.got_frame[0]:
- # print 'keyframe:', s.frame.key_frame
- # convert from YUV to RGB
- self.ns.sws_scale(
- self.sws_context,
- self.frame.data, self.frame.linesize,
- 0, constants.WII_VIDEO_HEIGHT,
- self.out_frame.data, self.out_frame.linesize)
-
- image_buffer = \
- self.ffi.buffer(self.out_frame.data[0], self.out_frame.linesize[0] * constants.WII_VIDEO_HEIGHT)
- return image_buffer
diff --git a/src/server/data/h264decoder6.py b/src/server/data/h264decoder6.py
deleted file mode 100644
index a7c0cfe..0000000
--- a/src/server/data/h264decoder6.py
+++ /dev/null
@@ -1,146 +0,0 @@
-from cffi import FFI
-from cffi import VerificationError
-
-from src.server.data import constants
-from src.server.util.logging.logger import Logger
-
-
-# TODO static alloc in_data and make interface for reading/writing directly to it
-# remove array.array usage of calling code
-
-
-class H264Decoder6:
- def __init_ffi(self):
- self.ffi = FFI()
- self.ffi.cdef('''
- // AVCODEC
-
- enum PixelFormat { AV_PIX_FMT_YUV420P, AV_PIX_FMT_RGB24, ... };
-
- void avcodec_register_all(void);
-
- struct AVPacket { ...; uint8_t *data; int size; ...; };
- void av_init_packet(struct AVPacket *pkt);
-
- enum AVCodecID { AV_CODEC_ID_H264, ... };
- struct AVCodec *avcodec_find_decoder(enum AVCodecID id);
-
- struct AVCodecContext *avcodec_alloc_context3(struct AVCodec *codec);
-
- int avcodec_open2(struct AVCodecContext *avctx, struct AVCodec *codec,
- struct AVDictionary **options);
-
- struct AVFrame { uint8_t *data[8]; int linesize[8]; ...; int key_frame; ...; };
- struct AVFrame *avcodec_alloc_frame(void);
-
- int avcodec_decode_video2(struct AVCodecContext *avctx, struct AVFrame *picture,
- int *got_picture_ptr, struct AVPacket *avpkt);
-
- int avcodec_close(struct AVCodecContext *avctx);
-
- void av_free(void *ptr);
-
- int avpicture_get_size(enum PixelFormat pix_fmt, int width, int height);
-
- int avpicture_fill(struct AVPicture *picture, uint8_t *ptr,
- int pix_fmt, int width, int height);
-
- // SWSCALE
-
- #define SWS_BILINEAR ...
- #define SWS_FAST_BILINEAR ...
- struct SwsContext *sws_getContext(int srcW, int srcH, enum PixelFormat srcFormat,
- int dstW, int dstH, enum PixelFormat dstFormat,
- int flags, struct SwsFilter *srcFilter,
- struct SwsFilter *dstFilter, const double *param);
-
- int sws_scale(struct SwsContext *c, const uint8_t *const srcSlice[],
- const int srcStride[], int srcSliceY,
- int srcSliceH, uint8_t *const dst[],
- const int dstStride[]);
-
- void sws_freeContext(struct SwsContext *c);
- ''')
- try:
- self.ns = self.ffi.verify(source='''
- #include
- #include
- ''', libraries=['avcodec', 'swscale'])
- except VerificationError as e:
- Logger.throw(e, "Decoder error. Please open an issue on GitHub with the crash info.")
- raise e
-
- def __init_avcodec(self):
- self.ns.avcodec_register_all()
-
- self.av_packet = self.ffi.new('struct AVPacket *')
- self.ns.av_init_packet(self.av_packet)
-
- self.codec = self.ns.avcodec_find_decoder(self.ns.AV_CODEC_ID_H264)
- assert self.codec
-
- self.context = self.ns.avcodec_alloc_context3(self.codec)
- assert self.context
-
- assert self.ns.avcodec_open2(self.context, self.codec, self.ffi.NULL) >= 0
-
- self.frame = self.ns.avcodec_alloc_frame()
- assert self.frame
- self.got_frame = self.ffi.new('int *')
- self.out_frame = self.ns.avcodec_alloc_frame()
-
- def __init__(self):
- self.out_buffer, self.sws_context = None, None
- self.__init_ffi()
- self.__init_avcodec()
- self.update_dimensions()
-
- def close(self):
- self.ns.sws_freeContext(self.sws_context)
- self.ns.av_free(self.out_frame)
-
- self.ns.avcodec_close(self.context)
- self.ns.av_free(self.context)
- self.ns.av_free(self.frame)
-
- def update_dimensions(self):
- if self.sws_context is not None:
- self.ns.sws_freeContext(self.sws_context)
- self.sws_context = self.ns.sws_getContext(
- constants.WII_VIDEO_WIDTH, constants.WII_VIDEO_HEIGHT, self.ns.AV_PIX_FMT_YUV420P,
- constants.WII_VIDEO_WIDTH, constants.WII_VIDEO_HEIGHT, self.ns.AV_PIX_FMT_RGB24,
- self.ns.SWS_FAST_BILINEAR,
- self.ffi.NULL,
- self.ffi.NULL, self.ffi.NULL)
-
- bytes_req = self.ns.avpicture_get_size(self.ns.AV_PIX_FMT_RGB24, constants.WII_VIDEO_WIDTH,
- constants.WII_VIDEO_HEIGHT)
- self.out_buffer = self.ffi.new('uint8_t [%i]' % bytes_req)
- self.ns.avpicture_fill(
- self.ffi.cast('struct AVPicture *', self.out_frame),
- self.out_buffer,
- self.ns.AV_PIX_FMT_RGB24,
- constants.WII_VIDEO_WIDTH, constants.WII_VIDEO_HEIGHT)
-
- def get_image_buffer(self, encoded_nalu):
- in_data = self.ffi.new('uint8_t []', encoded_nalu)
- self.av_packet.data = in_data
- self.av_packet.size = len(encoded_nalu)
-
- length = self.ns.avcodec_decode_video2(self.context, self.frame, self.got_frame, self.av_packet)
- if length < 0:
- raise Exception('avcodec_decode_video2')
- elif length != self.av_packet.size:
- raise Exception('expected to decode a single complete frame')
- elif self.got_frame[0]:
- # print 'keyframe:', s.frame.key_frame
- # convert from YUV to RGB
- self.ns.sws_scale(
- self.sws_context,
- self.frame.data, self.frame.linesize,
- 0, constants.WII_VIDEO_HEIGHT,
- self.out_frame.data, self.out_frame.linesize)
-
- image_buffer = \
- self.ffi.buffer(self.out_frame.data[0], self.out_frame.linesize[0] * constants.WII_VIDEO_HEIGHT)
- return image_buffer
diff --git a/src/server/data/struct/audio.py b/src/server/data/struct/audio.py
deleted file mode 100644
index ec953e9..0000000
--- a/src/server/data/struct/audio.py
+++ /dev/null
@@ -1,35 +0,0 @@
-import construct
-
-header_base = construct.BitStruct(
- 'fmt' / construct.BitsInteger(3),
- 'channel' / construct.Bit,
- 'vibrate' / construct.Flag,
- 'packet_type' / construct.Bit,
- 'seq_id' / construct.BitsInteger(10),
- 'payload_size' / construct.BitsInteger(16)
-)
-header_aud = construct.Struct(
- 'timestamp' / construct.Int32ul
-)
-header_msg = construct.Struct(
- # This is kind of a hack, (there are two timestamp fields, which one is used
- # depends on packet_type
- 'timestamp_audio' / construct.Int32ul,
- 'timestamp' / construct.Int32ul,
- construct.Array(2, 'freq_0' / construct.Int32ul), # -> mc_video
- construct.Array(2, 'freq_1' / construct.Int32ul), # -> mc_sync
- 'vid_format' / construct.Int8ub,
- construct.Padding(3)
-)
-header = construct.Struct(
- construct.Embedded(header_base),
- construct.Embedded(
- construct.Switch(lambda ctx: ctx.packet_type,
- {
- 0: header_aud,
- 1: header_msg
- },
- default=construct.Pass
- )
- )
-)
diff --git a/src/server/data/struct/video.py b/src/server/data/struct/video.py
deleted file mode 100644
index 9f247f2..0000000
--- a/src/server/data/struct/video.py
+++ /dev/null
@@ -1,14 +0,0 @@
-import construct
-
-header = construct.BitStruct(
- 'magic' / construct.Nibble,
- 'packet_type' / construct.BitsInteger(2),
- 'seq_id' / construct.BitsInteger(10),
- 'init' / construct.Flag,
- 'frame_begin' / construct.Flag,
- 'chunk_end' / construct.Flag,
- 'frame_end' / construct.Flag,
- 'has_timestamp' / construct.Flag,
- 'payload_size' / construct.BitsInteger(11),
- 'timestamp' / construct.BitsInteger(32)
-)
diff --git a/src/server/net/__init__.py b/src/server/net/__init__.py
deleted file mode 100644
index e69de29..0000000
diff --git a/src/server/net/codec.py b/src/server/net/codec.py
deleted file mode 100644
index 5ce8cf6..0000000
--- a/src/server/net/codec.py
+++ /dev/null
@@ -1,49 +0,0 @@
-import codecs
-import json
-
-import time
-
-
-# TODO use structs
-class Codec:
- command_delimiter = b"cwaffle"
- start_delimiter = b"swaffle"
- end_delimiter = b"ewaffle"
-
- def __init__(self):
- pass
-
- @classmethod
- def encode(cls, data=b""):
- """
- Encode stream "packet"
- :param data: data to encapsulate
- :return: "packet"
- """
- return cls.start_delimiter + data + cls.end_delimiter
-
- @classmethod
- def encode_command(cls, name=b"", data=b""):
- """
- Encode command
- :param name: command name
- :param data: extra command data
- :return: packet string
- """
- return name + cls.command_delimiter + data
-
- @classmethod
- def decode_command(cls, packet=b""):
- """
- Decode command packet
- :param packet: command packet encoded with encode_command(...)
- :return: command, data
- """
- parts = packet.split(cls.command_delimiter)
- return parts[0], parts[1]
-
- @classmethod
- def decode_input(cls, packet=""):
- data = json.loads(packet)
- data[1] = time.time()
- return data
diff --git a/src/server/net/server/__init__.py b/src/server/net/server/__init__.py
deleted file mode 100644
index e69de29..0000000
diff --git a/src/server/net/server/audio.py b/src/server/net/server/audio.py
deleted file mode 100644
index 859874e..0000000
--- a/src/server/net/server/audio.py
+++ /dev/null
@@ -1,15 +0,0 @@
-from src.server.net import sockets
-
-
-class ServiceAUD:
- __name__ = "ServiceAUD"
-
- def __init__(self):
- pass
-
- def update(self, packet, address):
- pass
-
- @classmethod
- def broadcast(cls, packet):
- sockets.Sockets.broadcast_media_packet(packet, ServiceAUD.__name__)
diff --git a/src/server/net/server/command.py b/src/server/net/server/command.py
deleted file mode 100644
index d87b504..0000000
--- a/src/server/net/server/command.py
+++ /dev/null
@@ -1,41 +0,0 @@
-from src.server.control.util.controller import Controller
-from src.server.data import constants
-from src.server.net import sockets
-from src.server.net.codec import Codec
-from src.server.util.logging.logger_backend import LoggerBackend
-
-
-class ServiceCMD:
- __name__ = "ServiceCMD"
-
- def __init__(self):
- pass
-
- def update(self, address, command, data):
- data = data.decode() # to string
- LoggerBackend.finer("Received command packet of type %s from client %s: %s" % (command, address, data))
- if command == constants.COMMAND_REGISTER:
- self.register_client(address)
- elif command == constants.COMMAND_INPUT_BUTTON:
- Controller.set_button_input(data)
- elif command == constants.COMMAND_INPUT_L3R3:
- Controller.set_extra_button_input(data)
- elif command == constants.COMMAND_INPUT_TOUCH:
- Controller.set_touch_input(data)
- elif command == constants.COMMAND_INPUT_JOYSTICK:
- Controller.set_joystick_input(data)
- elif command == constants.COMMAND_PING:
- sockets.Sockets.SERVER_CMD_S.sendto(Codec.encode_command(constants.COMMAND_PONG), address)
- elif command == constants.COMMAND_INPUT_MIC_BLOW:
- Controller.set_send_audio(data)
-
- @staticmethod
- def register_client(address):
- sockets.Sockets.add_client_socket(address, ServiceCMD)
-
- @classmethod
- def broadcast(cls, command, data=b""):
- sockets.Sockets.broadcast_command_packet(command, data, ServiceCMD.__name__)
-
-
-ServiceCMD = ServiceCMD()
diff --git a/src/server/net/server/video.py b/src/server/net/server/video.py
deleted file mode 100644
index 66280d1..0000000
--- a/src/server/net/server/video.py
+++ /dev/null
@@ -1,15 +0,0 @@
-from src.server.net import sockets
-
-
-class ServiceVID:
- __name__ = "ServiceVID"
-
- def __init__(self):
- pass
-
- def update(self, packet, address):
- pass
-
- @classmethod
- def broadcast(cls, packet):
- sockets.Sockets.broadcast_media_packet(packet, ServiceVID.__name__)
diff --git a/src/server/net/socket_handlers.py b/src/server/net/socket_handlers.py
deleted file mode 100644
index 7df472f..0000000
--- a/src/server/net/socket_handlers.py
+++ /dev/null
@@ -1,40 +0,0 @@
-from src.server.net import sockets
-from src.server.net.server.audio import ServiceAUD
-from src.server.net.server.command import ServiceCMD
-from src.server.net.server.video import ServiceVID
-from src.server.net.wii.audio import AudioHandler
-from src.server.net.wii.command import CommandHandler
-from src.server.net.wii.message import MessageHandler
-from src.server.net.wii.video import VideoHandler
-
-
-class SocketHandlers:
- def __init__(self):
- self.wii_handlers = None
- self.server_media_handlers = None
- self.server_command_handlers = None
-
- def create(self):
- self.wii_handlers = {
- sockets.Sockets.WII_MSG_S: MessageHandler(),
- sockets.Sockets.WII_VID_S: VideoHandler(),
- sockets.Sockets.WII_AUD_S: AudioHandler(),
- sockets.Sockets.WII_CMD_S: CommandHandler()
- }
- self.server_media_handlers = {
- sockets.Sockets.SERVER_VID_S: ServiceVID(),
- sockets.Sockets.SERVER_AUD_S: ServiceAUD()
- }
- self.server_command_handlers = {
- sockets.Sockets.SERVER_CMD_S: ServiceCMD
- }
-
- def get_handler_keys(self):
- return list(
- list(self.wii_handlers.keys()) +
- list(self.server_media_handlers.keys()) +
- list(self.server_command_handlers.keys())
- )
-
-
-SocketHandlers = SocketHandlers()
diff --git a/src/server/net/sockets.py b/src/server/net/sockets.py
deleted file mode 100644
index 688874b..0000000
--- a/src/server/net/sockets.py
+++ /dev/null
@@ -1,149 +0,0 @@
-import socket
-
-from src.server.data import constants
-from src.server.net.codec import Codec
-from src.server.util.logging.logger_backend import LoggerBackend
-
-
-class Sockets:
- def __init__(self):
- self.WII_MSG_S = None
- self.WII_VID_S = None
- self.WII_AUD_S = None
- self.WII_HID_S = None
- self.WII_CMD_S = None
- self.SERVER_VID_S = None
- self.SERVER_AUD_S = None
- self.SERVER_CMD_S = None
- self.client_sockets = {}
-
- @staticmethod
- def service_addend(ip): # TODO this is unnecessary ip is always 192.168.1.11 or empty string
- """
- Client should listen to ports of 100 higher than client
- constants list client ports which commands are sent to
- :param ip: ip of client
- :return: 0 or 100
- """
- if ip == "" or int(ip.split('.')[3]) == 10:
- return 0
- else:
- return 100
-
- def udp_service(self, ip, port):
- sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
- try:
- sock.bind((ip, port + self.service_addend(ip)))
- except socket.error as e:
- LoggerBackend.throw(e, "Could not create socket for ip %s with port %s" % (ip, port))
- return sock
-
- # hack for now, replace with dhcp result
- WII_LOCAL_IP = '192.168.1.11'
- SERVER_IP = ''
-
- @staticmethod
- def tcp_server(ip, port):
- sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
- sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
- sock.bind((ip, port))
- sock.listen(5)
- return sock
-
- def connect(self):
- self.WII_MSG_S = self.udp_service(self.WII_LOCAL_IP, constants.PORT_WII_MSG)
- self.WII_VID_S = self.udp_service(self.WII_LOCAL_IP, constants.PORT_WII_VID)
- self.WII_AUD_S = self.udp_service(self.WII_LOCAL_IP, constants.PORT_WII_AUD)
- self.WII_HID_S = self.udp_service(self.WII_LOCAL_IP, constants.PORT_WII_HID)
- self.WII_CMD_S = self.udp_service(self.WII_LOCAL_IP, constants.PORT_WII_CMD)
- self.SERVER_VID_S = self.tcp_server(self.SERVER_IP, constants.PORT_SERVER_VID)
- self.SERVER_AUD_S = self.tcp_server(self.SERVER_IP, constants.PORT_SERVER_AUD)
- self.SERVER_CMD_S = self.udp_service(self.SERVER_IP, constants.PORT_SERVER_CMD)
-
- def close(self):
- LoggerBackend.debug("Closing sockets")
- if self.WII_MSG_S:
- # self.WII_MSG_S.shutdown(socket.SHUT_RDWR)
- self.WII_MSG_S.close()
- if self.WII_VID_S:
- # self.WII_VID_S.shutdown(socket.SHUT_RDWR)
- self.WII_VID_S.close()
- if self.WII_AUD_S:
- # self.WII_AUD_S.shutdown(socket.SHUT_RDWR)
- self.WII_AUD_S.close()
- if self.WII_CMD_S:
- # self.WII_CMD_S.shutdown(socket.SHUT_RDWR)
- self.WII_CMD_S.close()
- if self.WII_HID_S:
- # self.WII_HID_S.shutdown(socket.SHUT_RDWR)
- self.WII_HID_S.close()
- if self.SERVER_VID_S:
- # self.SERVER_VID_S.shutdown(socket.SHUT_RDWR)
- self.SERVER_VID_S.close()
- if self.SERVER_AUD_S:
- # self.SERVER_AUD_S.shutdown(socket.SHUT_RDWR)
- self.SERVER_AUD_S.close()
- if self.SERVER_CMD_S:
- # self.SERVER_CMD_S.shutdown(socket.SHUT_RDWR)
- self.SERVER_CMD_S.close()
- LoggerBackend.debug("Closed sockets")
-
- @classmethod
- def remove_client_socket(cls, address):
- ip = address[0]
- LoggerBackend.debug("Removing client: " + str(ip))
- to_del = []
- for sock_addr in Sockets.client_sockets.keys():
- ip2 = sock_addr[0] if not isinstance(sock_addr[0], socket.socket) else sock_addr[1][0]
- if ip == ip2:
- to_del.append(sock_addr)
- for item in to_del:
- del Sockets.client_sockets[item]
- cls.log_clients()
-
- @staticmethod
- def log_clients():
- clients = len(Sockets.client_sockets)
- LoggerBackend.debug("Client sockets: %d", clients)
- if clients % 3 == 0:
- LoggerBackend.info("Clients: %d", int(clients / 3))
-
- @classmethod
- def add_client_socket(cls, sock_addr, handler):
- """
- Add client sockets
- :param sock_addr: tuple (sockeu, address) or address, where address is a tuple (ip, port)
- :param handler: The packet handler
- :return: None
- """
- LoggerBackend.debug("Registered client: " + str(sock_addr))
- Sockets.client_sockets[sock_addr] = handler
- cls.log_clients()
-
- @staticmethod
- def broadcast_media_packet(packet, socket_type):
- encoded_packet = None
- for sock_addr_pair in list(Sockets.client_sockets.keys()):
- if sock_addr_pair in Sockets.client_sockets.keys() and \
- Sockets.client_sockets[sock_addr_pair].__name__ == socket_type:
- if not encoded_packet:
- encoded_packet = Codec.encode(packet)
- try:
- LoggerBackend.verbose("Broadcast media packet type: %s size: %d" % (socket_type,
- len(encoded_packet)))
- sock_addr_pair[0].sendall(encoded_packet)
- except socket.error:
- LoggerBackend.verbose("Broadcast media packet failed")
- Sockets.remove_client_socket(sock_addr_pair[1])
-
- @staticmethod
- def broadcast_command_packet(command, data, socket_type):
- for address in Sockets.client_sockets.keys():
- if Sockets.client_sockets[address].__name__ == socket_type:
- try:
- Sockets.SERVER_CMD_S.sendto(Codec.encode_command(command, data), address)
- except socket.error:
- Sockets.remove_client_socket(address)
-
-
-Sockets = Sockets()
diff --git a/src/server/net/wii/__init__.py b/src/server/net/wii/__init__.py
deleted file mode 100644
index e69de29..0000000
diff --git a/src/server/net/wii/audio.py b/src/server/net/wii/audio.py
deleted file mode 100644
index 044dc74..0000000
--- a/src/server/net/wii/audio.py
+++ /dev/null
@@ -1,66 +0,0 @@
-import codecs
-import random
-
-from src.server.control.util.controller import Controller
-from src.server.data import constants
-from src.server.data.config_server import ConfigServer
-from src.server.data.struct import audio
-from src.server.net import sockets
-from src.server.net.server.audio import ServiceAUD
-from src.server.net.server.command import ServiceCMD
-from src.server.net.wii.base import ServiceBase
-from src.server.util.logging.logger_backend import LoggerBackend
-
-
-class AudioHandler(ServiceBase):
- def __init__(self):
- super(AudioHandler, self).__init__()
- self.random_audio = ""
- for byte in range(0, 512):
- random_byte = hex(random.randint(0, 255)).replace("0x", "", 1)
- if len(random_byte) == 1:
- self.random_audio += "0"
- self.random_audio += random_byte
- LoggerBackend.debug("Random audio (%d bytes)", len(self.random_audio) / 2)
- LoggerBackend.extra("Random audio: %s", self.random_audio)
-
- def close(self):
- pass
-
- def update(self, packet):
- if not ConfigServer.stream_audio:
- return
- LoggerBackend.verbose("Received audio packet")
- h = audio.header.parse(packet)
-
- # ignore vid_format packets for now
- if h.packet_type == 0:
- seq_ok = self.update_seq_id(h.seq_id)
- if not seq_ok:
- LoggerBackend.debug('astrm bad seq_id')
- if h.fmt != 1 or h.channel != 0:
- LoggerBackend.throw(Exception('astrm currently only handles 48kHz PCM stereo'))
- if len(packet) != 8 + h.payload_size:
- LoggerBackend.throw(Exception('astrm bad payload_size'))
-
- if h.vibrate:
- ServiceCMD.broadcast(constants.COMMAND_VIBRATE)
-
- if ConfigServer.stream_audio:
- ServiceAUD.broadcast(packet[8:])
-
- if Controller.get_send_audio():
- self.send_audio(h.seq_id)
-
- def send_audio(self, sid):
- header = audio.header.build(dict(
- fmt=6,
- channel=1,
- vibrate=False,
- packet_type=0,
- seq_id=sid,
- payload_size=512,
- timestamp=0
- ))
- data = codecs.decode(self.random_audio, "hex")
- sockets.Sockets.WII_AUD_S.sendto(header + data, ('192.168.1.10', constants.PORT_WII_AUD))
diff --git a/src/server/net/wii/base.py b/src/server/net/wii/base.py
deleted file mode 100644
index a0da45b..0000000
--- a/src/server/net/wii/base.py
+++ /dev/null
@@ -1,18 +0,0 @@
-class ServiceBase(object):
- def __init__(self):
- self.seq_id_expect = None
-
- def update_seq_id(self, seq_id):
- ret = True
- if self.seq_id_expect is None:
- self.seq_id_expect = seq_id
- elif self.seq_id_expect != seq_id:
- ret = False
- self.seq_id_expect = (seq_id + 1) & 0x3ff
- return ret
-
- def close(self):
- pass
-
- def update(self, packet):
- pass
diff --git a/src/server/net/wii/command.py b/src/server/net/wii/command.py
deleted file mode 100644
index 874f280..0000000
--- a/src/server/net/wii/command.py
+++ /dev/null
@@ -1,109 +0,0 @@
-import ast
-import codecs
-
-import construct
-
-from src.server.data import constants
-from src.server.data.resource import Resource
-from src.server.data.struct import command
-from src.server.net import sockets
-from src.server.util.logging.logger_backend import LoggerBackend
-
-
-class CommandHandler:
- PT_REQ = 0
- PT_REQ_ACK = 1
- PT_RESP = 2
- PT_RESP_ACK = 3
-
- CMD0_OK = 0
-
- def __init__(self):
- self.cmd_handlers = {
- 0: self.cmd0,
- 1: self.cmd1,
- 2: self.cmd2
- }
- self.command_responses = {}
- self.set_region()
-
- def set_region(self, region=None):
- # Empty command data
- if not region or region.upper() == "NONE":
- self.command_responses = ast.literal_eval(Resource("command/na.json").resource)
- for response in self.command_responses.keys():
- if isinstance(self.command_responses[response], str):
- self.command_responses[response] = "0" * len(self.command_responses[response])
- else:
- for id_primary in self.command_responses[response].keys():
- for id_secondary in self.command_responses[response][id_primary].keys():
- self.command_responses[response][id_primary][id_secondary] = \
- "0" * len(self.command_responses[response][id_primary][id_secondary])
- # Region specific command data
- else:
- self.command_responses = ast.literal_eval(Resource("command/%s.json" % region.lower()).resource)
-
- def cmd0(self, h):
- id_primary = str(h.id_primary)
- id_secondary = str(h.id_secondary)
- LoggerBackend.debug('CMD0:%s:%s' % (id_primary, id_secondary))
- if id_primary not in self.command_responses["0"] or id_secondary not in self.command_responses["0"][id_primary]:
- LoggerBackend.debug('unhandled CMD0 %s %s', id_primary, id_secondary)
- return
- response = self.command_responses["0"][id_primary][id_secondary]
- response = codecs.decode(response, "hex")
- self.send_response_cmd0(h, response)
-
- def cmd1(self, h):
- response = self.command_responses["1"]
- response = codecs.decode(response, "hex")
- self.send_response(h, response)
-
- def cmd2(self, h):
- LoggerBackend.extra('TIME base {:04x} seconds {:08x}'.format(h.JDN_base, h.seconds))
- self.send_response(h)
-
- def ack(self, h):
- ack = command.header.build(
- construct.Container(
- packet_type=self.PT_REQ_ACK if h.packet_type == self.PT_REQ else self.PT_RESP_ACK,
- cmd_id=h.cmd_id,
- payload_size=0,
- seq_id=h.seq_id
- )
- )
- sockets.Sockets.WII_CMD_S.sendto(ack, ('192.168.1.10', constants.PORT_WII_CMD))
-
- def send_request(self, h, data=b''):
- self.send_cmd(h, self.PT_REQ, data)
-
- def send_response(self, h, data=b''):
- self.send_cmd(h, self.PT_RESP, data)
-
- def send_response_cmd0(self, h, data=b'', result=CMD0_OK):
- assert h.cmd_id == 0
- h.flags = ((h.flags >> 3) & 0xfc) | 1
- h.error_code = result
- h.payload_size_cmd0 = len(data)
- self.send_response(h, data)
-
- @staticmethod
- def send_cmd(h, packet_type, data):
- h.packet_type = packet_type
- h.payload_size = len(data)
- # compensate for the fact that data doesn't include cmd0 header
- if h.cmd_id == 0:
- h.payload_size += command.header_cmd0.sizeof()
- sockets.Sockets.WII_CMD_S.sendto(command.header.build(h) + data, ('192.168.1.10', constants.PORT_WII_CMD))
-
- def update(self, packet):
- h = command.header.parse(packet)
- # don't track acks from the console for now
- if h.packet_type in (self.PT_REQ, self.PT_RESP):
- LoggerBackend.finer('CMD (%d): %s', h.cmd_id, codecs.encode(packet, "hex").decode())
- LoggerBackend.finer(h)
- self.ack(h)
- self.cmd_handlers[h.cmd_id](h)
-
- def close(self):
- pass
diff --git a/src/server/net/wii/message.py b/src/server/net/wii/message.py
deleted file mode 100644
index a013f78..0000000
--- a/src/server/net/wii/message.py
+++ /dev/null
@@ -1,13 +0,0 @@
-from src.server.util.logging.logger_backend import LoggerBackend
-
-
-class MessageHandler:
- def __init__(self):
- pass
-
- @staticmethod
- def update(packet):
- LoggerBackend.debug('MSG: ' + packet.encode('hex'))
-
- def close(self):
- pass
diff --git a/src/server/net/wii/video.py b/src/server/net/wii/video.py
deleted file mode 100644
index bd4b02d..0000000
--- a/src/server/net/wii/video.py
+++ /dev/null
@@ -1,124 +0,0 @@
-import array
-import time
-from io import BytesIO
-
-from PIL import Image
-
-from src.server.data import constants
-from src.server.data.config_server import ConfigServer
-from src.server.data.h264decoder import H264Decoder
-from src.server.data.h264decoder6 import H264Decoder6
-from src.server.data.struct import video
-from src.server.net.server.video import ServiceVID
-from src.server.net.sockets import Sockets
-from src.server.net.wii.base import ServiceBase
-from src.server.util.logging.logger_backend import LoggerBackend
-from src.server.util.process_util import ProcessUtil
-
-
-class VideoHandler(ServiceBase):
- def __init__(self):
- super(VideoHandler, self).__init__()
- self.last_sent_time = 0
-
- # There is probably a better way to do this, but this method is easy...until something breaks.
- avcodec_version = int(self.get_installed_package_version("libavcodec-dev").split(":")[0])
- LoggerBackend.info("AVCodec version %d" % avcodec_version)
- if avcodec_version <= 6:
- LoggerBackend.info("Using old AVCodec definitions.")
- self.decoder = H264Decoder6()
- else:
- LoggerBackend.info("Using new AVCodec definitions.")
- self.decoder = H264Decoder()
- self.frame = array.array('B')
- self.is_streaming = False
- self.frame_decode_num = 0
-
- def close(self):
- self.decoder.close()
-
- @staticmethod
- def get_installed_package_version(package_name):
- output = ProcessUtil.get_output(["dpkg", "-s", package_name])
- return output.split("Version:")[1].split("\n")[0].strip() if "Version:" in output else "0:0"
-
- @staticmethod
- def packet_is_idr(packet):
- return "x80" in str(packet[8:16])
-
- def h264_nal_encapsulate(self, is_idr, vstrm):
- slice_header = 0x25b804ff if is_idr else (0x21e003ff | ((self.frame_decode_num & 0xff) << 13))
- self.frame_decode_num += 1
-
- nals = array.array('B')
- # TODO shouldn't really need this after the first IDR
- # TODO hardcoded for gamepad for now
- # allow decoder to know stream parameters
- if is_idr:
- nals.extend([
- # sps
- 0x00, 0x00, 0x00, 0x01,
- 0x67, 0x64, 0x00, 0x20, 0xac, 0x2b, 0x40, 0x6c, 0x1e, 0xf3, 0x68,
- # pps
- 0x00, 0x00, 0x00, 0x01,
- 0x68, 0xee, 0x06, 0x0c, 0xe8
- ])
-
- # begin slice nalu
- nals.extend([0x00, 0x00, 0x00, 0x01])
- nals.extend([(slice_header >> 24) & 0xff,
- (slice_header >> 16) & 0xff,
- (slice_header >> 8) & 0xff,
- slice_header & 0xff])
-
- # add escape codes
- nals.extend(vstrm[:2])
- for i in range(2, len(vstrm)):
- if vstrm[i] <= 3 and nals[-2] == 0 and nals[-1] == 0:
- nals.extend([3])
- nals.extend([vstrm[i]])
-
- return nals
-
- def update(self, packet, test=False):
- if not ConfigServer.stream_video:
- return
- LoggerBackend.verbose("Received video packet")
- h = video.header.parse(packet)
- is_idr = self.packet_is_idr(packet)
-
- seq_ok = self.update_seq_id(h.seq_id)
-
- if not seq_ok:
- self.is_streaming = False
-
- if h.frame_begin:
- self.frame = array.array('B')
- if not self.is_streaming:
- if is_idr:
- self.is_streaming = True
- else:
- # request a new IDR frame
- if not test:
- Sockets.WII_MSG_S.sendto(b'\x01\x00\x00\x00', ('192.168.1.10', constants.PORT_WII_MSG))
- return
-
- self.frame.fromstring(packet[16:])
-
- if self.is_streaming and h.frame_end:
- # Get image
- nals = self.h264_nal_encapsulate(is_idr, self.frame)
- image_buffer = self.decoder.get_image_buffer(nals.tostring())
- if not image_buffer:
- return
- # Check fps limit
- if time.time() - self.last_sent_time < 1. / ConfigServer.fps:
- return
- # Reduce quality at the expense of CPU
- image = Image.frombuffer("RGB", (constants.WII_VIDEO_WIDTH, constants.WII_CAMERA_HEIGHT),
- bytes(image_buffer), "raw", "RGB", 0, 1)
- ib = BytesIO()
- image.save(ib, "JPEG", quality=ConfigServer.quality)
- ServiceVID.broadcast(ib.getvalue())
- # Update time
- self.last_sent_time = time.time()
diff --git a/src/server/ui/cli/cli_main.py b/src/server/ui/cli/cli_main.py
index 57720b8..2d4a181 100644
--- a/src/server/ui/cli/cli_main.py
+++ b/src/server/ui/cli/cli_main.py
@@ -1,10 +1,10 @@
import os
import time
-from src.server.control.gamepad import Gamepad
from src.server.data import constants
from src.server.data.args import Args
from src.server.data.resource import Resource
+from src.server.util.drc_sim_c import DrcSimC
from src.server.util.interface_util import InterfaceUtil
from src.server.util.logging.logger_cli import LoggerCli
from src.server.util.process_util import ProcessUtil
@@ -14,12 +14,10 @@
class CliMain:
def __init__(self):
self.getting_key = False
- self.gamepad = None
+ self.drc_sim_c = None
self.wpa_supplicant = None
def start(self):
- LoggerCli.warn("The CLI not user friendly. It is here to provide a way to automate"
- " the server via a shell. The GUI is a better alternative for normal use.")
if Args.args.run_server:
self.run_server()
elif Args.args.get_key:
@@ -31,8 +29,8 @@ def stop(self):
LoggerCli.info("Stopping")
ProcessUtil.call(["killall", "dhclient"])
self.getting_key = False
- if self.gamepad and self.gamepad.running:
- self.gamepad.close()
+ if self.drc_sim_c:
+ self.drc_sim_c.stop()
if self.wpa_supplicant:
self.wpa_supplicant.stop()
@@ -48,11 +46,17 @@ def run_server(self):
InterfaceUtil.dhclient(wii_u_interface)
InterfaceUtil.set_metric(normal_interface, 0)
InterfaceUtil.set_metric(wii_u_interface, 1)
- self.gamepad = Gamepad()
- self.gamepad.start()
- while self.gamepad.running:
+ self.drc_sim_c = DrcSimC()
+ self.drc_sim_c.set_region(Args.args.region)
+ self.drc_sim_c.add_status_change_listener(self.drc_sim_c_status_changed)
+ self.drc_sim_c.start()
+ while self.drc_sim_c.running:
time.sleep(1)
+ def drc_sim_c_status_changed(self, status):
+ if status == DrcSimC.STOPPED:
+ self.stop()
+
@staticmethod
def check_interfaces(normal_interface, wii_u_interface):
if normal_interface == wii_u_interface:
diff --git a/src/server/ui/gui/frame/frame_log.py b/src/server/ui/gui/frame/frame_log.py
index aa2bc29..eb84105 100644
--- a/src/server/ui/gui/frame/frame_log.py
+++ b/src/server/ui/gui/frame/frame_log.py
@@ -17,7 +17,7 @@ def __init__(self, master=None, **kw):
# noinspection PyUnusedLocal
def button_clicked(self, event):
tail = ["x-terminal-emulator", "-e", "tail", "-f"]
- for file in ("drcsim", "cli", "gui", "wpa", "backend"):
+ for file in ("drcsim", "cli", "gui", "wpa", "backend", "drc_sim_c"):
tail.append(os.path.join(constants.PATH_LOG_DIR, file + ".log"))
self.deactivate()
try:
@@ -29,8 +29,7 @@ def activate(self):
pass
def deactivate(self):
- if self.log and self.log.poll() is None:
- self.log.kill()
+ pass
def kill_other_tabs(self):
return False
diff --git a/src/server/ui/gui/frame/frame_run_server.py b/src/server/ui/gui/frame/frame_run_server.py
index a4c8cc1..19dd4ae 100644
--- a/src/server/ui/gui/frame/frame_run_server.py
+++ b/src/server/ui/gui/frame/frame_run_server.py
@@ -2,14 +2,12 @@
from tkinter import messagebox
from tkinter.ttk import Label, Button, Combobox
-from src.server.control.gamepad import Gamepad
-from src.server.net import socket_handlers, sockets
-from src.server.net.wii.command import CommandHandler
-from src.server.util.wpa_supplicant import WpaSupplicant
from src.server.data import constants
from src.server.ui.gui.frame.frame_tab import FrameTab
+from src.server.util.drc_sim_c import DrcSimC
from src.server.util.interface_util import InterfaceUtil
from src.server.util.logging.logger_gui import LoggerGui
+from src.server.util.wpa_supplicant import WpaSupplicant
class FrameRunServer(FrameTab):
@@ -22,7 +20,7 @@ def __init__(self, master=None, **kw):
FrameTab.__init__(self, master, **kw)
self.wii_u_interface = None
self.normal_interface = None
- self.gamepad = None
+ self.drc_sim_c = None
self.wpa_supplicant = None
LoggerGui.extra("Initializing FrameRunServer")
# Create Widgets
@@ -67,7 +65,7 @@ def start_server(self, event=None):
if event:
LoggerGui.debug("User clicked start server button")
LoggerGui.debug("Start server called")
- if self.label_backend_status["text"] != Gamepad.STOPPED and \
+ if self.label_backend_status["text"] != DrcSimC.STOPPED and \
(self.label_wpa_status["text"] not in (WpaSupplicant.DISCONNECTED, WpaSupplicant.TERMINATED)):
messagebox.showerror("Running", "Server is already running")
return
@@ -124,11 +122,10 @@ def wpa_status_changed(self, status):
InterfaceUtil.set_metric(self.normal_interface, 0)
InterfaceUtil.set_metric(self.wii_u_interface, 1)
LoggerGui.debug("Starting backend")
- self.gamepad = Gamepad()
- self.gamepad.add_status_change_listener(self.backend_status_changed)
- self.gamepad.start()
- CommandHandler.set_region(socket_handlers.SocketHandlers.wii_handlers[sockets.Sockets.WII_CMD_S],
- self.dropdown_region.get())
+ self.drc_sim_c = DrcSimC()
+ self.drc_sim_c.add_status_change_listener(self.backend_status_changed)
+ self.drc_sim_c.set_region(self.dropdown_region.get())
+ self.drc_sim_c.start()
self.label_interface_info.config(text="Server IP: " + InterfaceUtil.get_ip(self.normal_interface)
+ "\n" + os.uname()[1])
elif status in (WpaSupplicant.DISCONNECTED, WpaSupplicant.TERMINATED):
@@ -150,7 +147,7 @@ def backend_status_changed(self, status):
"""
LoggerGui.debug("Backend status changed to %s", status)
self.label_backend_status.config(text=status)
- if status in (Gamepad.NO_PACKETS, Gamepad.CRASHED):
+ if status == DrcSimC.STOPPED:
self.stop_server()
def stop_server(self, event=None):
@@ -163,12 +160,12 @@ def stop_server(self, event=None):
LoggerGui.debug("User clicked stop server button")
LoggerGui.debug("Stop server called")
if event and (self.label_wpa_status["text"] in (WpaSupplicant.DISCONNECTED, WpaSupplicant.TERMINATED)
- and self.label_backend_status["text"] == Gamepad.STOPPED):
+ and self.label_backend_status["text"] == DrcSimC.STOPPED):
messagebox.showerror("Stop", "Server is not running.")
return
- if self.gamepad:
- self.gamepad.close()
- self.gamepad = None
+ if self.drc_sim_c:
+ self.drc_sim_c.stop()
+ self.drc_sim_c = None
if self.wpa_supplicant:
self.wpa_supplicant.stop()
self.wpa_supplicant = None
@@ -185,8 +182,8 @@ def activate(self):
self.dropdown_region["values"] = ["NONE", "NA"]
self.label_wpa_status["text"] = self.wpa_supplicant.get_status() \
if self.wpa_supplicant and self.wpa_supplicant.get_status() else WpaSupplicant.DISCONNECTED
- self.label_backend_status["text"] = self.gamepad.get_status() \
- if self.gamepad and self.gamepad.get_status() else Gamepad.STOPPED
+ self.label_backend_status["text"] = self.drc_sim_c.get_status() \
+ if self.drc_sim_c and self.drc_sim_c.get_status() else DrcSimC.STOPPED
self.button_start.config(state="normal")
self.button_stop.config(state="normal")
self.label_interface_info.config(text="")
diff --git a/src/server/util/drc_sim_c.py b/src/server/util/drc_sim_c.py
new file mode 100644
index 0000000..c362817
--- /dev/null
+++ b/src/server/util/drc_sim_c.py
@@ -0,0 +1,82 @@
+import subprocess
+from threading import Thread
+
+import time
+
+from src.server.data import constants
+from src.server.data.args import Args
+from src.server.data.config_general import ConfigGeneral
+from src.server.util.logging.logger_backend import LoggerBackend
+from src.server.util.process_util import ProcessUtil
+from src.server.util.status_sending_thread import StatusSendingThread
+
+
+class DrcSimC(StatusSendingThread):
+ UNKNOWN = "UNKNOWN"
+ STOPPED = "STOPPED"
+ RUNNING = "RUNNING"
+
+ def __init__(self):
+ """
+ Helper for interacting with drc_sim_c.
+ """
+ super().__init__()
+ self.running = False
+ self.status = self.UNKNOWN
+ self.drc_sim_c_process = None
+ self.status_check_thread = None
+ self.region = "none"
+
+ def set_region(self, region):
+ self.region = region
+
+ def start(self):
+ if Args.args.disable_server:
+ return
+ self.running = True
+ self.kill_drc_sim_c()
+ LoggerBackend.debug("Starting drc_sim_c")
+ command = ["drc_sim_c", "-region", self.region, "-video-quality", str(ConfigGeneral.video_quality),
+ "-input-delay", str(ConfigGeneral.input_delay)]
+ if not ConfigGeneral.stream_video:
+ command.append("--no-video")
+ if not ConfigGeneral.stream_audio:
+ command.append("--no-audio")
+ if Args.args.debug:
+ command.append("-d")
+ if Args.args.extra:
+ command.append("-e")
+ if Args.args.finer:
+ command.append("-f")
+ if Args.args.verbose:
+ command.append("-v")
+ self.drc_sim_c_process = subprocess.Popen(command, stdout=open(constants.PATH_LOG_DRC_SIM_C, "w"),
+ stderr=subprocess.STDOUT)
+ LoggerBackend.debug("Starting status check thread")
+ self.status_check_thread = Thread(target=self.check_status, name="drc_sim_c Status Check Thread")
+ self.status_check_thread.start()
+ self.set_status(self.RUNNING)
+
+ def check_status(self):
+ while self.running:
+ if self.drc_sim_c_process.poll():
+ self.set_status(self.STOPPED)
+ time.sleep(1)
+
+ def stop(self):
+ """
+ Stops any background thread that is running
+ :return: None
+ """
+ self.running = False
+ LoggerBackend.debug("Stopping drc_sim_c")
+ if self.drc_sim_c_process and self.drc_sim_c_process.poll() is None:
+ self.drc_sim_c_process.terminate()
+ self.kill_drc_sim_c()
+ # reset
+ self.clear_status_change_listeners()
+ LoggerBackend.debug("Stopped drc_sim_c")
+
+ @staticmethod
+ def kill_drc_sim_c():
+ ProcessUtil.call(["killall", "drc_sim_c"])
diff --git a/src/server/util/wpa_supplicant.py b/src/server/util/wpa_supplicant.py
index 372d8c1..d7cf630 100644
--- a/src/server/util/wpa_supplicant.py
+++ b/src/server/util/wpa_supplicant.py
@@ -6,7 +6,7 @@
import pexpect
from src.server.data import constants
-from src.server.data.config_server import ConfigServer
+from src.server.data.config_general import ConfigGeneral
from src.server.util.logging.logger_wpa import LoggerWpa
from src.server.util.process_util import ProcessUtil
from src.server.util.status_sending_thread import StatusSendingThread
@@ -94,20 +94,25 @@ def check_status(self):
self.time_start += 1
# scanning
elif not self.scan_contains_wii_u(scan_results) or "wpa_state=SCANNING" in wpa_status:
- LoggerWpa.finer("%d seconds until scan timeout", ConfigServer.scan_timeout - self.time_scan)
+ LoggerWpa.finer("%d seconds until scan timeout", ConfigGeneral.scan_timeout - self.time_scan)
+ # disconnect
+ if self.time_scan == -1:
+ status = self.DISCONNECTED
# timeout scan
- if self.time_scan >= ConfigServer.scan_timeout:
+ elif self.time_scan >= ConfigGeneral.scan_timeout:
status = self.NOT_FOUND
else:
status = self.SCANNING
self.time_scan += 1
elif "wpa_state=COMPLETED" in wpa_status:
status = self.CONNECTED
- self.time_scan = 0 # forces a disconnect - might need to be handled better
+ self.time_scan = -1 # forces a disconnect - might need to be handled better
elif "wpa_state=AUTHENTICATING" in wpa_status or "wpa_state=ASSOCIATING" in wpa_status:
status = self.CONNECTING
elif "wpa_state=DISCONNECTED" in wpa_status:
status = self.DISCONNECTED
+ if self.time_scan != -1:
+ status = self.FAILED_START
else:
LoggerWpa.extra("WPA status: %s", wpa_status)
status = self.UNKNOWN
@@ -150,12 +155,6 @@ def stop(self):
LoggerWpa.debug("Ignored stop request: already stopped")
return
self.running = False
- if self.status_check_thread:
- LoggerWpa.debug("Stopping wpa status check")
- try:
- self.status_check_thread.join()
- except RuntimeError as e:
- LoggerWpa.exception(e)
if self.psk_thread_cli and self.psk_thread_cli.isalive():
LoggerWpa.debug("Stopping psk pexpect spawn")
self.psk_thread_cli.sendline("quit")
diff --git a/tests/test_parse.py b/tests/test_parse.py
index e8c41be..f1dc6f8 100644
--- a/tests/test_parse.py
+++ b/tests/test_parse.py
@@ -1,15 +1,12 @@
import os
-from src.server.data.config_server import ConfigServer
-from src.server.net.wii.video import VideoHandler
-
def test_video_parse():
"""
Reads dumped video packets and sends them to the video handler
:return: None
"""
- ConfigServer.load()
+ '''ConfigServer.load()
handler = VideoHandler()
with open(os.path.join(os.path.dirname(__file__), "packets/video.bin"), "rb") as video_packets:
read = True
@@ -21,4 +18,5 @@ def test_video_parse():
return
packet += read_byte
packet = packet.replace(b"|\n", b"")
- handler.update(packet, True)
+ handler.update(packet, True)'''
+ pass