mirror of
https://github.com/vanilla-wiiu/vanilla.git
synced 2025-01-22 16:21:48 -05:00
Merge branch 'master' into rpi
This commit is contained in:
commit
54b3f16f2b
23 changed files with 544 additions and 406 deletions
|
@ -14,7 +14,9 @@ OPTION(VANILLA_BUILD_DESKTOP "Build Qt app for Linux desktop" ON)
|
|||
OPTION(VANILLA_BUILD_RPI "Build SDL2 app for Raspberry Pi" OFF)
|
||||
|
||||
add_subdirectory(lib)
|
||||
add_subdirectory(pipe)
|
||||
if (NOT ANDROID)
|
||||
add_subdirectory(pipe)
|
||||
endif()
|
||||
if (VANILLA_BUILD_DESKTOP)
|
||||
add_subdirectory(app)
|
||||
endif()
|
||||
|
|
17
README.md
17
README.md
|
@ -22,19 +22,19 @@ Vanilla currently requires the following dependencies:
|
|||
|
||||
- Debian/Ubuntu
|
||||
```
|
||||
# apt install qt6-base-dev qt6-multimedia-dev libavcodec-dev libavutil-dev libavfilter-dev libsdl2-dev libnl-genl-3-dev isc-dhcp-client libssl-dev
|
||||
# apt install qt6-base-dev qt6-multimedia-dev libavcodec-dev libavutil-dev libavfilter-dev libsdl2-dev libnl-genl-3-dev isc-dhcp-client libssl-dev build-essential cmake
|
||||
```
|
||||
- Fedora
|
||||
```
|
||||
# dnf install qt6-qtbase-devel qt6-qtmultimedia-devel libavcodec-free-devel libavutil-free-devel libavfilter-free-devel libnl3-devel SDL2-devel openssl-devel
|
||||
# dnf install qt6-qtbase-devel qt6-qtmultimedia-devel libavcodec-free-devel libavutil-free-devel libavfilter-free-devel libnl3-devel SDL2-devel openssl-devel make automake gcc gcc-c++ kernel-devel cmake
|
||||
```
|
||||
- Arch
|
||||
```
|
||||
# pacman -S qt6 ffmpeg libnl sdl2 dhclient
|
||||
# pacman -S qt6 ffmpeg libnl sdl2 dhclient base-devel make cmake
|
||||
```
|
||||
- Alpine/postmarketOS
|
||||
```
|
||||
# apk add qt6-qtbase-dev qt6-qtmultimedia-dev ffmpeg-dev libnl3-dev sdl2-dev dhclient
|
||||
# apk add qt6-qtbase-dev qt6-qtmultimedia-dev ffmpeg-dev libnl3-dev sdl2-dev dhclient build-base cmake
|
||||
```
|
||||
|
||||
The build process is otherwise normal for a CMake program:
|
||||
|
@ -42,8 +42,13 @@ The build process is otherwise normal for a CMake program:
|
|||
```
|
||||
git clone --recursive https://github.com/vanilla-wiiu/vanilla.git
|
||||
cd vanilla
|
||||
mkdir build
|
||||
cd build
|
||||
mkdir build && cd build
|
||||
cmake ..
|
||||
cmake --build .
|
||||
```
|
||||
|
||||
Optionally, to install the program:
|
||||
|
||||
```
|
||||
sudo cmake --install .
|
||||
```
|
||||
|
|
|
@ -37,59 +37,68 @@ Backend::Backend(QObject *parent) : QObject(parent)
|
|||
|
||||
void Backend::init()
|
||||
{
|
||||
emit ready();
|
||||
initInternal();
|
||||
}
|
||||
|
||||
BackendViaLocalRoot::BackendViaLocalRoot(const QHostAddress &udpServer, QObject *parent) : Backend(parent)
|
||||
int Backend::initInternal()
|
||||
{
|
||||
m_serverAddress = udpServer;
|
||||
emit ready();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void BackendViaLocalRoot::interrupt()
|
||||
void Backend::interrupt()
|
||||
{
|
||||
vanilla_stop();
|
||||
}
|
||||
|
||||
void BackendViaLocalRoot::requestIDR()
|
||||
void Backend::requestIDR()
|
||||
{
|
||||
vanilla_request_idr();
|
||||
}
|
||||
|
||||
void BackendViaLocalRoot::connectToConsole()
|
||||
void Backend::sync(uint16_t code)
|
||||
{
|
||||
QtConcurrent::run(connectInternal, this, m_serverAddress);
|
||||
auto watcher = new QFutureWatcher<int>();
|
||||
connect(watcher, &QFutureWatcher<int>::finished, this, &Backend::syncFutureCompleted);
|
||||
watcher->setFuture(QtConcurrent::run(&Backend::syncInternal, this, code));
|
||||
}
|
||||
|
||||
int BackendViaLocalRoot::connectInternal(BackendViaLocalRoot *instance, const QHostAddress &server)
|
||||
int Backend::syncInternal(uint16_t code)
|
||||
{
|
||||
if (server.isNull()) {
|
||||
return vanilla_start(vanillaEventHandler, instance);
|
||||
} else {
|
||||
return vanilla_start_udp(vanillaEventHandler, instance, server.toIPv4Address());
|
||||
}
|
||||
return vanilla_sync(code, 0);
|
||||
}
|
||||
|
||||
void BackendViaLocalRoot::updateTouch(int x, int y)
|
||||
void Backend::connectToConsole()
|
||||
{
|
||||
QtConcurrent::run(&Backend::connectInternal, this);
|
||||
}
|
||||
|
||||
int Backend::connectInternal()
|
||||
{
|
||||
return vanilla_start(vanillaEventHandler, this);
|
||||
}
|
||||
|
||||
void Backend::updateTouch(int x, int y)
|
||||
{
|
||||
vanilla_set_touch(x, y);
|
||||
}
|
||||
|
||||
void BackendViaLocalRoot::setButton(int button, int32_t value)
|
||||
void Backend::setButton(int button, int32_t value)
|
||||
{
|
||||
vanilla_set_button(button, value);
|
||||
}
|
||||
|
||||
void BackendViaLocalRoot::setRegion(int region)
|
||||
void Backend::setRegion(int region)
|
||||
{
|
||||
vanilla_set_region(region);
|
||||
}
|
||||
|
||||
void BackendViaLocalRoot::setBatteryStatus(int status)
|
||||
void Backend::setBatteryStatus(int status)
|
||||
{
|
||||
vanilla_set_battery_status(status);
|
||||
}
|
||||
|
||||
void BackendViaLocalRoot::syncFutureCompleted()
|
||||
void Backend::syncFutureCompleted()
|
||||
{
|
||||
QFutureWatcher<int> *watcher = static_cast<QFutureWatcher<int>*>(sender());
|
||||
int r = watcher->result();
|
||||
|
@ -113,14 +122,9 @@ BackendPipe::~BackendPipe()
|
|||
quit();
|
||||
}
|
||||
|
||||
void BackendPipe::sync(uint16_t code)
|
||||
void BackendPipe::start()
|
||||
{
|
||||
m_process->start(QStringLiteral("pkexec"), {pipeProcessFilename(), m_wirelessInterface, QStringLiteral("-sync"), QString::number(code)});
|
||||
}
|
||||
|
||||
void BackendPipe::connectToConsole()
|
||||
{
|
||||
m_process->start(QStringLiteral("pkexec"), {pipeProcessFilename(), m_wirelessInterface, QStringLiteral("-connect")});
|
||||
m_process->start(QStringLiteral("pkexec"), {pipeProcessFilename(), m_wirelessInterface});
|
||||
}
|
||||
|
||||
QString BackendPipe::pipeProcessFilename()
|
||||
|
@ -133,7 +137,7 @@ void BackendPipe::receivedData()
|
|||
while (m_process->canReadLine()) {
|
||||
QByteArray a = m_process->readLine().trimmed();
|
||||
if (a == QByteArrayLiteral("READY")) {
|
||||
// Do nothing?
|
||||
emit pipeAvailable();
|
||||
} else {
|
||||
printf("%s\n", a.constData());
|
||||
}
|
||||
|
@ -149,3 +153,41 @@ void BackendPipe::quit()
|
|||
m_process = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
BackendViaInternalPipe::BackendViaInternalPipe(const QString &wirelessInterface, QObject *parent) : Backend(parent)
|
||||
{
|
||||
m_wirelessInterface = wirelessInterface;
|
||||
}
|
||||
|
||||
int BackendViaInternalPipe::initInternal()
|
||||
{
|
||||
m_pipe = new BackendPipe(m_wirelessInterface, this);
|
||||
connect(m_pipe, &BackendPipe::pipeAvailable, this, &BackendViaInternalPipe::ready);
|
||||
m_pipe->start();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int BackendViaInternalPipe::syncInternal(uint16_t code)
|
||||
{
|
||||
return vanilla_sync(code, QHostAddress(QHostAddress::LocalHost).toIPv4Address());
|
||||
}
|
||||
|
||||
int BackendViaInternalPipe::connectInternal()
|
||||
{
|
||||
return vanilla_start_udp(vanillaEventHandler, this, QHostAddress(QHostAddress::LocalHost).toIPv4Address());
|
||||
}
|
||||
|
||||
BackendViaExternalPipe::BackendViaExternalPipe(const QHostAddress &udpServer, QObject *parent) : Backend(parent)
|
||||
{
|
||||
m_serverAddress = udpServer;
|
||||
}
|
||||
|
||||
int BackendViaExternalPipe::syncInternal(uint16_t code)
|
||||
{
|
||||
return vanilla_sync(code, m_serverAddress.toIPv4Address());
|
||||
}
|
||||
|
||||
int BackendViaExternalPipe::connectInternal()
|
||||
{
|
||||
return vanilla_start_udp(vanillaEventHandler, this, m_serverAddress.toIPv4Address());
|
||||
}
|
|
@ -18,8 +18,7 @@ public:
|
|||
virtual ~BackendPipe() override;
|
||||
|
||||
public slots:
|
||||
void sync(uint16_t code);
|
||||
void connectToConsole();
|
||||
void start();
|
||||
void quit();
|
||||
|
||||
signals:
|
||||
|
@ -45,12 +44,12 @@ public:
|
|||
Backend(QObject *parent = nullptr);
|
||||
|
||||
// These are all commands that can be issued to the backend. They are re-entrant and can be called at any time.
|
||||
virtual void interrupt() = 0;
|
||||
virtual void updateTouch(int x, int y) = 0;
|
||||
virtual void setButton(int button, int32_t value) = 0;
|
||||
virtual void requestIDR() = 0;
|
||||
virtual void setRegion(int region) = 0;
|
||||
virtual void setBatteryStatus(int status) = 0;
|
||||
void interrupt();
|
||||
void updateTouch(int x, int y);
|
||||
void setButton(int button, int32_t value);
|
||||
void requestIDR();
|
||||
void setRegion(int region);
|
||||
void setBatteryStatus(int status);
|
||||
|
||||
signals:
|
||||
void videoAvailable(const QByteArray &packet);
|
||||
|
@ -64,34 +63,49 @@ signals:
|
|||
|
||||
public slots:
|
||||
// These slots must be called with Qt::QueuedConnection to start the event loops in the backend's thread
|
||||
virtual void init();
|
||||
virtual void connectToConsole() = 0;
|
||||
void init();
|
||||
void sync(uint16_t code);
|
||||
void connectToConsole();
|
||||
|
||||
};
|
||||
|
||||
class BackendViaLocalRoot : public Backend
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
BackendViaLocalRoot(const QHostAddress &serverAddress, QObject *parent = nullptr);
|
||||
|
||||
virtual void interrupt() override;
|
||||
virtual void updateTouch(int x, int y) override;
|
||||
virtual void setButton(int button, int32_t value) override;
|
||||
virtual void requestIDR() override;
|
||||
virtual void setRegion(int region) override;
|
||||
virtual void setBatteryStatus(int status) override;
|
||||
|
||||
public slots:
|
||||
virtual void connectToConsole() override;
|
||||
|
||||
private:
|
||||
static int connectInternal(BackendViaLocalRoot *instance, const QHostAddress &serverAddress);
|
||||
QHostAddress m_serverAddress;
|
||||
protected:
|
||||
virtual int initInternal();
|
||||
virtual int syncInternal(uint16_t code);
|
||||
virtual int connectInternal();
|
||||
|
||||
private slots:
|
||||
void syncFutureCompleted();
|
||||
|
||||
};
|
||||
|
||||
class BackendViaInternalPipe : public Backend
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
BackendViaInternalPipe(const QString &wirelessInterface, QObject *parent = nullptr);
|
||||
|
||||
protected:
|
||||
virtual int initInternal() override;
|
||||
virtual int syncInternal(uint16_t code) override;
|
||||
virtual int connectInternal() override;
|
||||
|
||||
private:
|
||||
QString m_wirelessInterface;
|
||||
BackendPipe *m_pipe;
|
||||
};
|
||||
|
||||
class BackendViaExternalPipe : public Backend
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
BackendViaExternalPipe(const QHostAddress &serverAddress, QObject *parent = nullptr);
|
||||
|
||||
protected:
|
||||
// virtual int initInternal() override;
|
||||
virtual int syncInternal(uint16_t code) override;
|
||||
virtual int connectInternal() override;
|
||||
|
||||
private:
|
||||
QHostAddress m_serverAddress;
|
||||
};
|
||||
|
||||
#endif // BACKEND_H
|
|
@ -21,6 +21,7 @@ GamepadHandler::GamepadHandler(QObject *parent) : QObject(parent)
|
|||
g_buttonMap[SDL_CONTROLLER_BUTTON_Y] = VANILLA_BTN_Y;
|
||||
g_buttonMap[SDL_CONTROLLER_BUTTON_BACK] = VANILLA_BTN_MINUS;
|
||||
g_buttonMap[SDL_CONTROLLER_BUTTON_GUIDE] = VANILLA_BTN_HOME;
|
||||
g_buttonMap[SDL_CONTROLLER_BUTTON_MISC1] = VANILLA_BTN_TV;
|
||||
g_buttonMap[SDL_CONTROLLER_BUTTON_START] = VANILLA_BTN_PLUS;
|
||||
g_buttonMap[SDL_CONTROLLER_BUTTON_LEFTSTICK] = VANILLA_BTN_L3;
|
||||
g_buttonMap[SDL_CONTROLLER_BUTTON_RIGHTSTICK] = VANILLA_BTN_R3;
|
||||
|
|
|
@ -30,7 +30,8 @@ InputConfigDialog::InputConfigDialog(QWidget *parent) : QDialog(parent)
|
|||
layout->addWidget(createButton(tr("D-Pad Left"), VANILLA_BTN_LEFT), 12, 0);
|
||||
layout->addWidget(createButton(tr("D-Pad Right"), VANILLA_BTN_RIGHT), 13, 0);
|
||||
|
||||
layout->addWidget(createButton(tr("Home"), VANILLA_BTN_HOME), 14, 1, 1, 3);
|
||||
layout->addWidget(createButton(tr("TV"), VANILLA_BTN_TV), 14, 1, 1, 1);
|
||||
layout->addWidget(createButton(tr("Home"), VANILLA_BTN_HOME), 14, 2);
|
||||
|
||||
layout->addWidget(createButton(tr("Right Stick Up"), VANILLA_AXIS_R_UP), 2, 4);
|
||||
layout->addWidget(createButton(tr("Right Stick Down"), VANILLA_AXIS_R_DOWN), 3, 4);
|
||||
|
|
|
@ -22,6 +22,7 @@ KeyMap::KeyMap()
|
|||
ref[Qt::Key_Return] = VANILLA_BTN_PLUS;
|
||||
ref[Qt::Key_Control] = VANILLA_BTN_MINUS;
|
||||
ref[Qt::Key_H] = VANILLA_BTN_HOME;
|
||||
ref[Qt::Key_Y] = VANILLA_BTN_TV;
|
||||
ref[Qt::Key_W] = VANILLA_AXIS_L_UP;
|
||||
ref[Qt::Key_A] = VANILLA_AXIS_L_LEFT;
|
||||
ref[Qt::Key_S] = VANILLA_AXIS_L_DOWN;
|
||||
|
|
|
@ -38,7 +38,6 @@ MainWindow::MainWindow(QWidget *parent) : QWidget(parent)
|
|||
}
|
||||
|
||||
m_backend = nullptr;
|
||||
m_pipe = nullptr;
|
||||
|
||||
qRegisterMetaType<uint16_t>("uint16_t");
|
||||
|
||||
|
@ -260,10 +259,6 @@ MainWindow::~MainWindow()
|
|||
delete t;
|
||||
}
|
||||
|
||||
if (m_pipe) {
|
||||
m_pipe->quit();
|
||||
}
|
||||
|
||||
SDL_Quit();
|
||||
|
||||
delete m_viewer;
|
||||
|
@ -356,7 +351,7 @@ void MainWindow::initBackend(T func)
|
|||
if (localWirelessIntf.isEmpty()) {
|
||||
UdpAddressDialog udpDiag(this);
|
||||
if (udpDiag.exec() == QDialog::Accepted) {
|
||||
m_backend = new BackendViaLocalRoot(udpDiag.acceptedAddress());
|
||||
m_backend = new BackendViaExternalPipe(udpDiag.acceptedAddress());
|
||||
} else {
|
||||
d->deleteLater();
|
||||
closeBackend();
|
||||
|
@ -364,10 +359,9 @@ void MainWindow::initBackend(T func)
|
|||
}
|
||||
// } else if (geteuid() == 0) {
|
||||
// If root, use lib locally
|
||||
// m_backend = new BackendViaLocalRoot(QHostAddress());
|
||||
// m_backend = new Backend(QHostAddress());
|
||||
} else {
|
||||
m_pipe = new BackendPipe(localWirelessIntf, this);
|
||||
m_backend = new BackendViaLocalRoot(QHostAddress::LocalHost);
|
||||
m_backend = new BackendViaInternalPipe(localWirelessIntf);
|
||||
}
|
||||
|
||||
connect(m_backend, &Backend::closed, d, &BackendInitDialog::deleteLater);
|
||||
|
@ -411,10 +405,6 @@ void MainWindow::setConnectedState(bool on)
|
|||
m_connectBtn->setText(on ? tr("Disconnect") : tr("Connect"));
|
||||
if (on) {
|
||||
initBackend([this]{
|
||||
if (m_pipe) {
|
||||
m_pipe->connectToConsole();
|
||||
}
|
||||
|
||||
QMetaObject::invokeMethod(m_backend, &Backend::connectToConsole, Qt::QueuedConnection);
|
||||
|
||||
updateVolumeAxis();
|
||||
|
@ -422,16 +412,8 @@ void MainWindow::setConnectedState(bool on)
|
|||
updateBatteryStatus();
|
||||
});
|
||||
} else {
|
||||
if (m_pipe) {
|
||||
m_pipe->quit();
|
||||
m_pipe->deleteLater();
|
||||
m_pipe = nullptr;
|
||||
}
|
||||
|
||||
if (m_backend) {
|
||||
m_backend->interrupt();
|
||||
m_backend->deleteLater();
|
||||
m_backend = nullptr;
|
||||
}
|
||||
|
||||
m_viewer->setImage(QImage());
|
||||
|
@ -549,6 +531,7 @@ void MainWindow::updateBatteryStatus()
|
|||
void MainWindow::closeBackend()
|
||||
{
|
||||
setConnectedState(false);
|
||||
|
||||
if (m_backend) {
|
||||
m_backend->interrupt();
|
||||
m_backend->deleteLater();
|
||||
|
|
|
@ -54,7 +54,6 @@ private:
|
|||
QSplitter *m_splitter;
|
||||
|
||||
Backend *m_backend;
|
||||
BackendPipe *m_pipe;
|
||||
|
||||
VideoDecoder *m_videoDecoder;
|
||||
GamepadHandler *m_gamepadHandler;
|
||||
|
|
|
@ -171,6 +171,7 @@ void VideoDecoder::startRecording()
|
|||
m_recordingFilename = QDir(QStandardPaths::writableLocation(QStandardPaths::TempLocation)).filePath("vanilla-recording-%0.mp4").arg(QDateTime::currentSecsSinceEpoch());
|
||||
|
||||
QByteArray filenameUtf8 = m_recordingFilename.toUtf8();
|
||||
size_t sps_pps_size;
|
||||
|
||||
int r = avformat_alloc_output_context2(&m_recordingCtx, nullptr, nullptr, filenameUtf8.constData());
|
||||
if (r < 0) {
|
||||
|
@ -192,11 +193,11 @@ void VideoDecoder::startRecording()
|
|||
m_videoStream->time_base = {1, 60};
|
||||
m_videoStream->codecpar->codec_id = AV_CODEC_ID_H264;
|
||||
|
||||
size_t sps_pps_size;
|
||||
vanilla_retrieve_sps_pps_data(nullptr, &sps_pps_size);
|
||||
sps_pps_size = sizeof(VANILLA_SPS_PARAMS) + sizeof(VANILLA_PPS_PARAMS);
|
||||
m_videoStream->codecpar->extradata_size = sps_pps_size;
|
||||
m_videoStream->codecpar->extradata = (uint8_t *) av_malloc(sps_pps_size);
|
||||
vanilla_retrieve_sps_pps_data(m_videoStream->codecpar->extradata, &sps_pps_size);
|
||||
memcpy(m_videoStream->codecpar->extradata, VANILLA_SPS_PARAMS, sizeof(VANILLA_SPS_PARAMS));
|
||||
memcpy(m_videoStream->codecpar->extradata + sizeof(VANILLA_SPS_PARAMS), VANILLA_PPS_PARAMS, sizeof(VANILLA_PPS_PARAMS));
|
||||
|
||||
m_audioStream = avformat_new_stream(m_recordingCtx, nullptr);
|
||||
if (!m_audioStream) {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
add_library(vanilla SHARED
|
||||
add_library(vanilla STATIC
|
||||
gamepad/audio.c
|
||||
gamepad/command.c
|
||||
gamepad/gamepad.c
|
||||
|
@ -13,8 +13,10 @@ target_include_directories(vanilla PRIVATE
|
|||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
)
|
||||
|
||||
target_link_libraries(vanilla PRIVATE
|
||||
if (NOT ANDROID)
|
||||
target_link_libraries(vanilla PRIVATE
|
||||
pthread
|
||||
)
|
||||
)
|
||||
endif()
|
||||
|
||||
install(TARGETS vanilla)
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
#include "input.h"
|
||||
#include "video.h"
|
||||
|
||||
#include "../pipe/linux/def.h"
|
||||
#include "../pipe/def.h"
|
||||
#include "status.h"
|
||||
#include "util.h"
|
||||
|
||||
|
@ -52,7 +52,7 @@ void send_to_console(int fd, const void *data, size_t data_size, int port)
|
|||
|
||||
ssize_t sent = sendto(fd, data, data_size, 0, (const struct sockaddr *) &address, sizeof(address));
|
||||
if (sent == -1) {
|
||||
print_info("Failed to send to Wii U socket: fd - %d; port - %d", fd, port);
|
||||
print_info("Failed to send to Wii U socket: fd - %d; port - %d", fd, port - 100);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -97,17 +97,89 @@ int send_pipe_cc(int skt, uint32_t cc, int wait_for_reply)
|
|||
do {
|
||||
sendto(skt, &send_cc, sizeof(send_cc), 0, (struct sockaddr *) &addr, sizeof(addr));
|
||||
|
||||
if (wait_for_reply) {
|
||||
if (!wait_for_reply) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
read_size = recv(skt, &recv_cc, sizeof(recv_cc), 0);
|
||||
if (read_size == sizeof(recv_cc) && ntohl(recv_cc) == VANILLA_PIPE_CC_BIND_ACK) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
sleep(1);
|
||||
} while (!is_interrupted());
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int connect_to_backend(int *socket, uint32_t cc)
|
||||
{
|
||||
// Try to bind with backend
|
||||
int pipe_cc_skt;
|
||||
if (!create_socket(&pipe_cc_skt, VANILLA_PIPE_CMD_CLIENT_PORT)) {
|
||||
return VANILLA_ERROR;
|
||||
}
|
||||
|
||||
struct timeval tv = {0};
|
||||
tv.tv_sec = 2;
|
||||
setsockopt(pipe_cc_skt, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
|
||||
|
||||
if (!send_pipe_cc(pipe_cc_skt, cc, 1)) {
|
||||
print_info("FAILED TO BIND TO PIPE");
|
||||
close(pipe_cc_skt);
|
||||
return VANILLA_ERROR;
|
||||
}
|
||||
|
||||
*socket = pipe_cc_skt;
|
||||
|
||||
return VANILLA_SUCCESS;
|
||||
}
|
||||
|
||||
int sync_internal(uint16_t code, uint32_t server_address)
|
||||
{
|
||||
clear_interrupt();
|
||||
|
||||
if (server_address == 0) {
|
||||
SERVER_ADDRESS = inet_addr("192.168.1.10");
|
||||
} else {
|
||||
SERVER_ADDRESS = htonl(server_address);
|
||||
}
|
||||
|
||||
int skt = 0;
|
||||
int ret = VANILLA_ERROR;
|
||||
if (server_address != 0) {
|
||||
ret = connect_to_backend(&skt, VANILLA_PIPE_SYNC_CODE(code));
|
||||
if (ret != VANILLA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
|
||||
// Wait for sync result from pipe
|
||||
uint32_t recv_cc;
|
||||
while (1) {
|
||||
ssize_t read_size = recv(skt, &recv_cc, sizeof(recv_cc), 0);
|
||||
if (read_size == sizeof(recv_cc)) {
|
||||
recv_cc = ntohl(recv_cc);
|
||||
if (recv_cc >> 8 == VANILLA_PIPE_CC_SYNC_STATUS >> 8) {
|
||||
ret = recv_cc & 0xFF;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (is_interrupted()) {
|
||||
send_pipe_cc(skt, VANILLA_PIPE_CC_UNBIND, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
exit_pipe:
|
||||
if (skt)
|
||||
close(skt);
|
||||
|
||||
exit:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int connect_as_gamepad_internal(vanilla_event_handler_t event_handler, void *context, uint32_t server_address)
|
||||
{
|
||||
clear_interrupt();
|
||||
|
@ -135,18 +207,11 @@ int connect_as_gamepad_internal(vanilla_event_handler_t event_handler, void *con
|
|||
|
||||
int ret = VANILLA_ERROR;
|
||||
|
||||
// Try to bind with backend
|
||||
int pipe_cc_skt;
|
||||
int pipe_cc_skt = 0;
|
||||
if (server_address != 0) {
|
||||
if (!create_socket(&pipe_cc_skt, VANILLA_PIPE_CMD_CLIENT_PORT)) goto exit;
|
||||
|
||||
struct timeval tv = {0};
|
||||
tv.tv_sec = 2;
|
||||
setsockopt(pipe_cc_skt, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
|
||||
|
||||
if (!send_pipe_cc(pipe_cc_skt, VANILLA_PIPE_CC_BIND, 1)) {
|
||||
print_info("FAILED TO BIND TO PIPE");
|
||||
goto exit_pipe;
|
||||
ret = connect_to_backend(&pipe_cc_skt, VANILLA_PIPE_CC_CONNECT);
|
||||
if (ret != VANILLA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -202,6 +267,7 @@ exit_vid:
|
|||
close(info.socket_vid);
|
||||
|
||||
exit_pipe:
|
||||
if (pipe_cc_skt)
|
||||
close(pipe_cc_skt);
|
||||
|
||||
exit:
|
||||
|
|
|
@ -25,6 +25,7 @@ struct gamepad_thread_context
|
|||
int socket_cmd;
|
||||
};
|
||||
|
||||
int sync_internal(uint16_t code, uint32_t server_address);
|
||||
int connect_as_gamepad_internal(vanilla_event_handler_t event_handler, void *context, uint32_t server_address);
|
||||
unsigned int reverse_bits(unsigned int b, int bit_count);
|
||||
void send_to_console(int fd, const void *data, size_t data_size, int port);
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include <unistd.h>
|
||||
|
||||
#include "gamepad.h"
|
||||
#include "status.h"
|
||||
#include "vanilla.h"
|
||||
#include "util.h"
|
||||
|
||||
|
@ -211,6 +212,7 @@ void send_input(int socket_hid)
|
|||
|
||||
if (current_buttons[VANILLA_BTN_L3]) button_mask |= 0x80;
|
||||
if (current_buttons[VANILLA_BTN_R3]) button_mask |= 0x40;
|
||||
if (current_buttons[VANILLA_BTN_TV]) button_mask |= 0x20;
|
||||
|
||||
ip.extra_buttons = button_mask;
|
||||
|
||||
|
|
|
@ -146,8 +146,10 @@ void handle_video_packet(vanilla_event_handler_t event_handler, void *context, u
|
|||
frame_decode_num++;
|
||||
|
||||
if (is_idr) {
|
||||
memcpy(nals_current, sps_pps_params, sizeof(sps_pps_params));
|
||||
nals_current += sizeof(sps_pps_params);
|
||||
memcpy(nals_current, VANILLA_SPS_PARAMS, sizeof(VANILLA_SPS_PARAMS));
|
||||
nals_current += sizeof(VANILLA_SPS_PARAMS);
|
||||
memcpy(nals_current, VANILLA_PPS_PARAMS, sizeof(VANILLA_PPS_PARAMS));
|
||||
nals_current += sizeof(VANILLA_PPS_PARAMS);
|
||||
}
|
||||
|
||||
// begin slice nalu
|
||||
|
|
|
@ -6,11 +6,4 @@
|
|||
void *listen_video(void *x);
|
||||
void request_idr();
|
||||
|
||||
static const uint8_t sps_pps_params[] = {
|
||||
// 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
|
||||
};
|
||||
|
||||
#endif // GAMEPAD_VIDEO_H
|
|
@ -103,14 +103,6 @@ void vanilla_request_idr()
|
|||
request_idr();
|
||||
}
|
||||
|
||||
void vanilla_retrieve_sps_pps_data(void *data, size_t *size)
|
||||
{
|
||||
if (data != NULL) {
|
||||
memcpy(data, sps_pps_params, MIN(*size, sizeof(sps_pps_params)));
|
||||
}
|
||||
*size = sizeof(sps_pps_params);
|
||||
}
|
||||
|
||||
void vanilla_set_region(int region)
|
||||
{
|
||||
set_region(region);
|
||||
|
@ -120,3 +112,8 @@ void vanilla_set_battery_status(int battery_status)
|
|||
{
|
||||
set_battery_status(battery_status);
|
||||
}
|
||||
|
||||
int vanilla_sync(uint16_t code, uint32_t server_address)
|
||||
{
|
||||
return sync_internal(code, server_address);
|
||||
}
|
|
@ -29,6 +29,7 @@ enum VanillaGamepadButtons
|
|||
VANILLA_BTN_MINUS,
|
||||
VANILLA_BTN_PLUS,
|
||||
VANILLA_BTN_HOME,
|
||||
VANILLA_BTN_TV,
|
||||
VANILLA_BTN_L3,
|
||||
VANILLA_BTN_R3,
|
||||
VANILLA_BTN_LEFT,
|
||||
|
@ -85,6 +86,14 @@ enum VanillaBatteryStatus {
|
|||
VANILLA_BATTERY_STATUS_FULL = 6
|
||||
};
|
||||
|
||||
static const uint8_t VANILLA_SPS_PARAMS[] = {
|
||||
0x00, 0x00, 0x00, 0x01, 0x67, 0x64, 0x00, 0x20, 0xac, 0x2b, 0x40, 0x6c, 0x1e, 0xf3, 0x68,
|
||||
};
|
||||
|
||||
static const uint8_t VANILLA_PPS_PARAMS[] = {
|
||||
0x00, 0x00, 0x00, 0x01, 0x68, 0xee, 0x06, 0x0c, 0xe8
|
||||
};
|
||||
|
||||
/**
|
||||
* Event handler used by caller to receive events
|
||||
*/
|
||||
|
@ -96,6 +105,8 @@ typedef void (*vanilla_event_handler_t)(void *context, int event_type, const cha
|
|||
int vanilla_start(vanilla_event_handler_t event_handler, void *context);
|
||||
int vanilla_start_udp(vanilla_event_handler_t event_handler, void *context, uint32_t server_address);
|
||||
|
||||
int vanilla_sync(uint16_t code, uint32_t server_address);
|
||||
|
||||
/**
|
||||
* Attempt to stop the current action
|
||||
*
|
||||
|
@ -142,14 +153,6 @@ void vanilla_install_logger(void (*logger)(const char *, va_list args));
|
|||
*/
|
||||
void vanilla_request_idr();
|
||||
|
||||
/**
|
||||
* Retrieve SPS/PPS data for H.264 encoding
|
||||
*
|
||||
* If `data` is null, `*size` will be set to the number of bytes required.
|
||||
* If `data` is not null, bytes will be copied up to `*size` or the total number of bytes.
|
||||
*/
|
||||
void vanilla_retrieve_sps_pps_data(void *data, size_t *size);
|
||||
|
||||
/**
|
||||
* Sets the region Vanilla should present itself to the console
|
||||
*
|
||||
|
|
5
pipe/README.md
Normal file
5
pipe/README.md
Normal file
|
@ -0,0 +1,5 @@
|
|||
# `vanilla-pipe`
|
||||
|
||||
No, this is not something you smoke, `vanilla-pipe` is a program on various platforms that facilitates a connection between the Wii U and another device. Since the Wii U connection is slightly nonstandard, not all devices can connect to it on their own. Hence, `vanilla-pipe`, which allows a connection on one device that forwards all communication to another.
|
||||
|
||||
`vanilla-pipe` is also used locally to allow the connection to happen with root permissions (which the nonstandard connection requires) while the frontend can remain a user program (with regular access to the user's X/Wayland/PulseAudio sessions).
|
|
@ -1,12 +1,15 @@
|
|||
#ifndef VANILLA_PIPE_DEF_H
|
||||
#define VANILLA_PIPE_DEF_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define VANILLA_PIPE_CMD_SERVER_PORT 51000
|
||||
#define VANILLA_PIPE_CMD_CLIENT_PORT 51001
|
||||
#define VANILLA_PIPE_CC_BIND 0x56414249
|
||||
#define VANILLA_PIPE_CC_SYNC 0x56530000
|
||||
#define VANILLA_PIPE_CC_CONNECT 0x56414249
|
||||
#define VANILLA_PIPE_CC_BIND_ACK 0x56414245
|
||||
#define VANILLA_PIPE_CC_SYNC_STATUS 0x53595300
|
||||
#define VANILLA_PIPE_CC_BUSY 0x56414255
|
||||
#define VANILLA_PIPE_CC_UNBIND 0x5641554E
|
||||
|
||||
#define VANILLA_PIPE_SYNC_CODE(x) (VANILLA_PIPE_CC_SYNC | (x & 0xFFFF))
|
||||
|
||||
#endif // VANILLA_PIPE_DEF_H
|
|
@ -7,61 +7,36 @@
|
|||
|
||||
int main(int argc, const char **argv)
|
||||
{
|
||||
if (argc < 3) {
|
||||
goto show_help;
|
||||
}
|
||||
|
||||
const char *wireless_interface = argv[1];
|
||||
const char *mode = argv[2];
|
||||
|
||||
if (!strcmp("-sync", mode)) {
|
||||
if (argc < 4) {
|
||||
pprint("ERROR: -sync requires sync code\n\n");
|
||||
goto show_help;
|
||||
}
|
||||
|
||||
int code = atoi(argv[3]);
|
||||
if (code == 0) {
|
||||
pprint("ERROR: Invalid sync code\n\n");
|
||||
goto show_help;
|
||||
}
|
||||
|
||||
vanilla_sync_with_console(wireless_interface, code);
|
||||
} else if (!strcmp("-connect", mode)) {
|
||||
vanilla_connect_to_console(wireless_interface);
|
||||
} else if (!strcmp("-is_synced", mode)) {
|
||||
if (vanilla_has_config()) {
|
||||
pprint("YES\n");
|
||||
} else {
|
||||
pprint("NO\n");
|
||||
}
|
||||
} else {
|
||||
pprint("ERROR: Invalid mode\n\n");
|
||||
goto show_help;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
show_help:
|
||||
if (argc < 2) {
|
||||
pprint("vanilla-pipe - brokers a connection between Vanilla and the Wii U\n");
|
||||
pprint("--------------------------------------------------------------------------------\n");
|
||||
pprint("\n");
|
||||
pprint("Usage: %s <wireless-interface> <mode> [args]\n", argv[0]);
|
||||
pprint("Usage: %s <wireless-interface>\n", argv[0]);
|
||||
pprint("\n");
|
||||
pprint("Modes: \n");
|
||||
pprint(" -sync <code> Sync/authenticate with the Wii U.\n");
|
||||
pprint(" -connect Connect to the Wii U (requires syncing prior).\n");
|
||||
pprint(" -is_synced Returns 1 if gamepad has been synced or 0 if it hasn't yet.\n");
|
||||
pprint("Connecting to the Wii U as a gamepad requires some modifications to the 802.11n\n");
|
||||
pprint("protocol, and not all platforms allow such modifications to be made.\n");
|
||||
pprint("Additionally, such modifications usually require root level access, and it can\n");
|
||||
pprint("be undesirable for various reasons to run a GUI application as root.\n");
|
||||
pprint("\n");
|
||||
pprint("Sync code is a 4-digit PIN based on the card suits shown on the console.\n\n");
|
||||
pprint(" To calculate the code, use the following:\n");
|
||||
pprint("This necessitated the creation of `vanilla-pipe`, a thin program that can\n");
|
||||
pprint("handle connecting to the Wii U in an environment that supports it (e.g. as root,\n");
|
||||
pprint("and in a Linux VM, or a separate Linux PC) while forwarding all data to the\n");
|
||||
pprint("user's desired frontend. `libvanilla` has full support for integrating with\n");
|
||||
pprint("`vanilla-pipe`, so as long as the frontend uses `libvanilla`, it can be used.\n");
|
||||
pprint("Additionally, since `vanilla-pipe` is fairly simple, it can be ported to\n");
|
||||
pprint("embedded devices such as MCUs or SBCs, providing more versatility in hardware\n");
|
||||
pprint("configurations.\n");
|
||||
pprint("\n");
|
||||
pprint(" ♠ (spade) = 0\n");
|
||||
pprint(" ♥ (heart) = 1\n");
|
||||
pprint(" ♦ (diamond) = 2\n");
|
||||
pprint(" ♣ (clover) = 3\n");
|
||||
pprint("\n");
|
||||
pprint(" Example: ♣♠♥♦ (clover, spade, heart, diamond) would equal 3012\n");
|
||||
pprint("`vanilla-pipe` cannot be controlled directly, it can only be controlled via UDP\n");
|
||||
pprint("sockets by a compatible frontend.\n");
|
||||
pprint("\n");
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
const char *wireless_interface = argv[1];
|
||||
|
||||
vanilla_listen(wireless_interface);
|
||||
|
||||
return 0;
|
||||
}
|
462
pipe/linux/wpa.c
462
pipe/linux/wpa.c
|
@ -17,7 +17,7 @@
|
|||
#include <unistd.h>
|
||||
#include <wpa_ctrl.h>
|
||||
|
||||
#include "def.h"
|
||||
#include "../def.h"
|
||||
#include "ports.h"
|
||||
#include "status.h"
|
||||
#include "util.h"
|
||||
|
@ -27,7 +27,13 @@
|
|||
const char *wpa_ctrl_interface = "/var/run/wpa_supplicant_drc";
|
||||
|
||||
pthread_mutex_t running_mutex;
|
||||
pthread_mutex_t main_loop_mutex;
|
||||
pthread_mutex_t action_mutex;
|
||||
pthread_mutex_t sync_mutex;
|
||||
int running = 0;
|
||||
int main_loop = 0;
|
||||
int sync_result_ready = 0;
|
||||
uint8_t sync_result = 0;
|
||||
|
||||
typedef struct {
|
||||
int from_socket;
|
||||
|
@ -38,8 +44,16 @@ typedef struct {
|
|||
} relay_ports;
|
||||
|
||||
struct in_addr client_address = {0};
|
||||
pthread_mutex_t client_address_mutex;
|
||||
pthread_cond_t client_address_waitcond;
|
||||
|
||||
struct sync_args {
|
||||
const char *wireless_interface;
|
||||
const char *wireless_config;
|
||||
uint16_t code;
|
||||
void *(*start_routine)(void *);
|
||||
struct wpa_ctrl *ctrl;
|
||||
};
|
||||
|
||||
#define THREADRESULT(x) ((void *) (uintptr_t) (x))
|
||||
|
||||
void lpprint(const char *fmt, va_list args)
|
||||
{
|
||||
|
@ -67,12 +81,10 @@ void print_info(const char *errstr, ...)
|
|||
|
||||
int is_interrupted()
|
||||
{
|
||||
return !running;
|
||||
}
|
||||
|
||||
void clear_interrupt()
|
||||
{
|
||||
running = 1;
|
||||
pthread_mutex_lock(&running_mutex);
|
||||
int r = !running;
|
||||
pthread_mutex_unlock(&running_mutex);
|
||||
return r;
|
||||
}
|
||||
|
||||
void wpa_msg(char *msg, size_t len)
|
||||
|
@ -282,15 +294,20 @@ give_up:
|
|||
void quit_loop()
|
||||
{
|
||||
pthread_mutex_lock(&running_mutex);
|
||||
pthread_mutex_lock(&client_address_mutex);
|
||||
pthread_mutex_lock(&main_loop_mutex);
|
||||
running = 0;
|
||||
pthread_cond_broadcast(&client_address_waitcond);
|
||||
pthread_mutex_unlock(&client_address_mutex);
|
||||
main_loop = 0;
|
||||
pthread_mutex_unlock(&main_loop_mutex);
|
||||
pthread_mutex_unlock(&running_mutex);
|
||||
}
|
||||
|
||||
void sigint_handler(int signum)
|
||||
{
|
||||
if (signum == SIGINT) {
|
||||
pprint("RECEIVED INTERRUPT SIGNAL\n");
|
||||
} else if (signum == SIGTERM) {
|
||||
pprint("RECEIVED TERMINATE SIGNAL\n");
|
||||
}
|
||||
quit_loop();
|
||||
signal(signum, SIG_DFL);
|
||||
}
|
||||
|
@ -315,38 +332,31 @@ void *read_stdin(void *)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
int wpa_setup_environment(const char *wireless_interface, const char *wireless_conf_file, ready_callback_t callback, void *callback_data)
|
||||
void *wpa_setup_environment(void *data)
|
||||
{
|
||||
int ret = VANILLA_ERROR;
|
||||
void *ret = THREADRESULT(VANILLA_ERROR);
|
||||
|
||||
clear_interrupt();
|
||||
|
||||
signal(SIGINT, sigint_handler);
|
||||
signal(SIGTERM, sigint_handler);
|
||||
//install_interrupt_handler();
|
||||
|
||||
pthread_t stdin_thread;
|
||||
pthread_create(&stdin_thread, NULL, read_stdin, NULL);
|
||||
struct sync_args *args = (struct sync_args *) data;
|
||||
|
||||
// Check status of interface with NetworkManager
|
||||
int is_managed = 0;
|
||||
if (is_networkmanager_managing_device(wireless_interface, &is_managed) != VANILLA_SUCCESS) {
|
||||
if (is_networkmanager_managing_device(args->wireless_interface, &is_managed) != VANILLA_SUCCESS) {
|
||||
print_info("FAILED TO DETERMINE MANAGED STATE OF WIRELESS INTERFACE");
|
||||
//goto die;
|
||||
}
|
||||
|
||||
// If NetworkManager is managing this device, temporarily stop it from doing so
|
||||
if (is_managed) {
|
||||
if (disable_networkmanager_on_device(wireless_interface) != VANILLA_SUCCESS) {
|
||||
if (disable_networkmanager_on_device(args->wireless_interface) != VANILLA_SUCCESS) {
|
||||
print_info("FAILED TO SET %s TO UNMANAGED, RESULTS MAY BE UNPREDICTABLE");
|
||||
} else {
|
||||
print_info("TEMPORARILY SET %s TO UNMANAGED", wireless_interface);
|
||||
print_info("TEMPORARILY SET %s TO UNMANAGED", args->wireless_interface);
|
||||
}
|
||||
}
|
||||
|
||||
// Start modified WPA supplicant
|
||||
pid_t pid;
|
||||
int err = start_wpa_supplicant(wireless_interface, wireless_conf_file, &pid);
|
||||
int err = start_wpa_supplicant(args->wireless_interface, args->wireless_config, &pid);
|
||||
if (err != VANILLA_SUCCESS || is_interrupted()) {
|
||||
print_info("FAILED TO START WPA SUPPLICANT");
|
||||
goto die_and_reenable_managed;
|
||||
|
@ -355,7 +365,7 @@ int wpa_setup_environment(const char *wireless_interface, const char *wireless_c
|
|||
// Get control interface
|
||||
const size_t buf_len = 1048576;
|
||||
char *buf = malloc(buf_len);
|
||||
snprintf(buf, buf_len, "%s/%s", wpa_ctrl_interface, wireless_interface);
|
||||
snprintf(buf, buf_len, "%s/%s", wpa_ctrl_interface, args->wireless_interface);
|
||||
struct wpa_ctrl *ctrl;
|
||||
while (!(ctrl = wpa_ctrl_open(buf))) {
|
||||
if (is_interrupted()) goto die_and_kill;
|
||||
|
@ -368,7 +378,8 @@ int wpa_setup_environment(const char *wireless_interface, const char *wireless_c
|
|||
goto die_and_close;
|
||||
}
|
||||
|
||||
ret = callback(ctrl, callback_data);
|
||||
args->ctrl = ctrl;
|
||||
ret = args->start_routine(args);
|
||||
|
||||
die_and_detach:
|
||||
wpa_ctrl_detach(ctrl);
|
||||
|
@ -383,19 +394,11 @@ die_and_kill:
|
|||
|
||||
die_and_reenable_managed:
|
||||
if (is_managed) {
|
||||
print_info("SETTING %s BACK TO MANAGED", wireless_interface);
|
||||
enable_networkmanager_on_device(wireless_interface);
|
||||
print_info("SETTING %s BACK TO MANAGED", args->wireless_interface);
|
||||
enable_networkmanager_on_device(args->wireless_interface);
|
||||
}
|
||||
|
||||
die:
|
||||
// Interrupt our stdin thread
|
||||
signal(SIGINT, SIG_DFL);
|
||||
signal(SIGTERM, SIG_DFL);
|
||||
pthread_kill(stdin_thread, SIGINT);
|
||||
|
||||
// Remove our custom sigint signal handler
|
||||
//uninstall_interrupt_handler();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -512,12 +515,12 @@ int enable_networkmanager_on_device(const char *wireless_interface)
|
|||
return set_networkmanager_on_device(wireless_interface, 1);
|
||||
}
|
||||
|
||||
void* do_relay(void *data)
|
||||
void *do_relay(void *data)
|
||||
{
|
||||
relay_ports *ports = (relay_ports *) data;
|
||||
char buf[2048];
|
||||
ssize_t read_size;
|
||||
while (running && client_address.s_addr != 0) {
|
||||
while (!is_interrupted() && client_address.s_addr != 0) {
|
||||
read_size = recv(ports->from_socket, buf, sizeof(buf), 0);
|
||||
if (read_size <= 0) {
|
||||
continue;
|
||||
|
@ -574,7 +577,7 @@ int open_socket(in_port_t port)
|
|||
|
||||
void *open_relay(void *data)
|
||||
{
|
||||
in_port_t port = (in_port_t) data;
|
||||
in_port_t port = (in_port_t) (uintptr_t) data;
|
||||
int ret = -1;
|
||||
|
||||
// Open an incoming port from the console
|
||||
|
@ -590,23 +593,10 @@ void *open_relay(void *data)
|
|||
}
|
||||
|
||||
// print_info("ENTERING MAIN LOOP");
|
||||
pthread_mutex_lock(&running_mutex);
|
||||
while (running) {
|
||||
pthread_mutex_unlock(&running_mutex);
|
||||
|
||||
// print_info("CHECKING CLIENT ADDRESS STATUS");
|
||||
pthread_mutex_lock(&client_address_mutex);
|
||||
struct in_addr addr = {0};
|
||||
while (client_address.s_addr == 0 && running) {
|
||||
pthread_cond_wait(&client_address_waitcond, &client_address_mutex);
|
||||
}
|
||||
// print_info("READ CLIENT ADDRESS");
|
||||
addr = client_address;
|
||||
pthread_mutex_unlock(&client_address_mutex);
|
||||
|
||||
if (addr.s_addr != 0) {
|
||||
while (!is_interrupted()) {
|
||||
if (client_address.s_addr != 0) {
|
||||
print_info("STARTED RELAYS");
|
||||
relay_ports console_to_frontend = create_ports(from_console, port, from_frontend, addr.s_addr, port + 200);
|
||||
relay_ports console_to_frontend = create_ports(from_console, port, from_frontend, client_address.s_addr, port + 200);
|
||||
relay_ports frontend_to_console = create_ports(from_frontend, port + 100, from_console, inet_addr("192.168.1.10"), port - 100);
|
||||
|
||||
pthread_t a_thread, b_thread;
|
||||
|
@ -620,9 +610,7 @@ void *open_relay(void *data)
|
|||
}
|
||||
|
||||
// print_info("RELAY EXITED");
|
||||
pthread_mutex_lock(&running_mutex);
|
||||
}
|
||||
pthread_mutex_unlock(&running_mutex);
|
||||
|
||||
ret = 0;
|
||||
|
||||
|
@ -633,20 +621,18 @@ close_console_connection:
|
|||
close(from_console);
|
||||
|
||||
close:
|
||||
return (void *) ret;
|
||||
return THREADRESULT(ret);
|
||||
}
|
||||
|
||||
void create_all_relays()
|
||||
{
|
||||
pthread_t vid_thread, aud_thread, msg_thread, cmd_thread, hid_thread;
|
||||
|
||||
pthread_create(&vid_thread, NULL, open_relay, (void *) PORT_VID);
|
||||
pthread_create(&aud_thread, NULL, open_relay, (void *) PORT_AUD);
|
||||
pthread_create(&msg_thread, NULL, open_relay, (void *) PORT_MSG);
|
||||
pthread_create(&cmd_thread, NULL, open_relay, (void *) PORT_CMD);
|
||||
pthread_create(&hid_thread, NULL, open_relay, (void *) PORT_HID);
|
||||
|
||||
pprint("READY\n");
|
||||
pthread_create(&vid_thread, NULL, open_relay, THREADRESULT(PORT_VID));
|
||||
pthread_create(&aud_thread, NULL, open_relay, THREADRESULT(PORT_AUD));
|
||||
pthread_create(&msg_thread, NULL, open_relay, THREADRESULT(PORT_MSG));
|
||||
pthread_create(&cmd_thread, NULL, open_relay, THREADRESULT(PORT_CMD));
|
||||
pthread_create(&hid_thread, NULL, open_relay, THREADRESULT(PORT_HID));
|
||||
|
||||
pthread_join(vid_thread, NULL);
|
||||
pthread_join(aud_thread, NULL);
|
||||
|
@ -676,120 +662,30 @@ int call_ip(const char **argv)
|
|||
return VANILLA_SUCCESS;
|
||||
}
|
||||
|
||||
void *read_client_control(void *data)
|
||||
void *thread_handler(void *data)
|
||||
{
|
||||
int skt = open_socket(VANILLA_PIPE_CMD_SERVER_PORT);
|
||||
uint32_t control_code;
|
||||
struct sync_args *args = (struct sync_args *) data;
|
||||
|
||||
struct sockaddr_in addr = {0};
|
||||
socklen_t addr_size = sizeof(addr);
|
||||
pthread_mutex_lock(&running_mutex);
|
||||
running = 1;
|
||||
pthread_mutex_unlock(&running_mutex);
|
||||
|
||||
while (running) {
|
||||
ssize_t r = recvfrom(skt, &control_code, sizeof(control_code), 0, (struct sockaddr *) &addr, &addr_size);
|
||||
if (r <= 0) {
|
||||
continue;
|
||||
}
|
||||
void *ret = args->start_routine(data);
|
||||
|
||||
control_code = ntohl(control_code);
|
||||
switch (control_code) {
|
||||
case VANILLA_PIPE_CC_BIND:
|
||||
print_info("RECEIVED BIND SIGNAL");
|
||||
pthread_mutex_lock(&client_address_mutex);
|
||||
client_address = addr.sin_addr;
|
||||
pthread_cond_broadcast(&client_address_waitcond);
|
||||
pthread_mutex_unlock(&client_address_mutex);
|
||||
free(args);
|
||||
|
||||
control_code = htonl(VANILLA_PIPE_CC_BIND_ACK);
|
||||
sendto(skt, &control_code, sizeof(control_code), 0, (struct sockaddr *) &addr, sizeof(addr));
|
||||
break;
|
||||
case VANILLA_PIPE_CC_UNBIND:
|
||||
print_info("RECEIVED UNBIND SIGNAL");
|
||||
pthread_mutex_lock(&client_address_mutex);
|
||||
client_address.s_addr = 0;
|
||||
pthread_cond_broadcast(&client_address_waitcond);
|
||||
pthread_mutex_unlock(&client_address_mutex);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
pthread_mutex_lock(&running_mutex);
|
||||
running = 0;
|
||||
pthread_mutex_unlock(&running_mutex);
|
||||
|
||||
// Locked by calling thread
|
||||
pthread_mutex_unlock(&action_mutex);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int do_connect(struct wpa_ctrl *ctrl, const char *wireless_interface)
|
||||
{
|
||||
while (1) {
|
||||
while (!wpa_ctrl_pending(ctrl)) {
|
||||
sleep(2);
|
||||
print_info("WAITING FOR CONNECTION");
|
||||
|
||||
if (is_interrupted()) return VANILLA_ERROR;
|
||||
}
|
||||
|
||||
char buf[1024];
|
||||
size_t actual_buf_len = sizeof(buf);
|
||||
wpa_ctrl_recv(ctrl, buf, &actual_buf_len);
|
||||
print_info("CONN RECV: %.*s", actual_buf_len, buf);
|
||||
|
||||
if (memcmp(buf, "<3>CTRL-EVENT-CONNECTED", 23) == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (is_interrupted()) return VANILLA_ERROR;
|
||||
}
|
||||
|
||||
print_info("CONNECTED TO CONSOLE");
|
||||
|
||||
// Use DHCP on interface
|
||||
pid_t dhclient_pid;
|
||||
int r = call_dhcp(wireless_interface, &dhclient_pid);
|
||||
if (r != VANILLA_SUCCESS) {
|
||||
print_info("FAILED TO RUN DHCP ON %s", wireless_interface);
|
||||
return r;
|
||||
} else {
|
||||
print_info("DHCP ESTABLISHED");
|
||||
}
|
||||
|
||||
call_ip((const char *[]){"ip", "route", "del", "default", "via", "192.168.1.1", "dev", wireless_interface, NULL});
|
||||
call_ip((const char *[]){"ip", "route", "del", "192.168.1.0/24", "dev", wireless_interface, NULL});
|
||||
call_ip((const char *[]){"route", "add", "-host", "192.168.1.10", "dev", wireless_interface, NULL});
|
||||
|
||||
pthread_mutex_init(&running_mutex, NULL);
|
||||
pthread_mutex_init(&client_address_mutex, NULL);
|
||||
pthread_cond_init(&client_address_waitcond, NULL);
|
||||
|
||||
pthread_t client_control_thread;
|
||||
pthread_create(&client_control_thread, NULL, read_client_control, NULL);
|
||||
|
||||
create_all_relays();
|
||||
|
||||
pthread_join(client_control_thread, NULL);
|
||||
|
||||
pthread_cond_destroy(&client_address_waitcond);
|
||||
pthread_mutex_destroy(&client_address_mutex);
|
||||
pthread_mutex_destroy(&running_mutex);
|
||||
|
||||
int kill_ret = kill(dhclient_pid, SIGTERM);
|
||||
print_info("KILLING DHCLIENT %i", dhclient_pid);
|
||||
}
|
||||
|
||||
size_t read_line_from_fd(int pipe, char *output, size_t max_output_size)
|
||||
{
|
||||
size_t i = 0;
|
||||
while (i < max_output_size && read(pipe, output, 1) > 0) {
|
||||
int newline = (*output == '\n');
|
||||
output++;
|
||||
i++;
|
||||
if (newline) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
*output = 0;
|
||||
return i;
|
||||
}
|
||||
|
||||
size_t read_line_from_file(FILE *file, char *output, size_t max_output_size)
|
||||
{
|
||||
return read_line_from_fd(fileno(file), output, max_output_size);
|
||||
}
|
||||
char wireless_authenticate_config_filename[1024] = {0};
|
||||
char wireless_connect_config_filename[1024] = {0};
|
||||
|
||||
size_t get_home_directory(char *buf, size_t buf_size)
|
||||
{
|
||||
|
@ -816,9 +712,6 @@ size_t get_max_path_length()
|
|||
return pathconf(".", _PC_PATH_MAX);
|
||||
}
|
||||
|
||||
char wireless_authenticate_config_filename[1024] = {0};
|
||||
char wireless_connect_config_filename[1024] = {0};
|
||||
|
||||
const char *get_wireless_connect_config_filename()
|
||||
{
|
||||
if (wireless_connect_config_filename[0] == 0) {
|
||||
|
@ -837,13 +730,25 @@ const char *get_wireless_authenticate_config_filename()
|
|||
return wireless_authenticate_config_filename;
|
||||
}
|
||||
|
||||
struct sync_args {
|
||||
uint16_t code;
|
||||
};
|
||||
size_t read_line_from_fd(int pipe, char *output, size_t max_output_size)
|
||||
{
|
||||
size_t i = 0;
|
||||
while (i < max_output_size && read(pipe, output, 1) > 0) {
|
||||
int newline = (*output == '\n');
|
||||
output++;
|
||||
i++;
|
||||
if (newline) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
*output = 0;
|
||||
return i;
|
||||
}
|
||||
|
||||
struct connect_args {
|
||||
const char *wireless_interface;
|
||||
};
|
||||
size_t read_line_from_file(FILE *file, char *output, size_t max_output_size)
|
||||
{
|
||||
return read_line_from_fd(fileno(file), output, max_output_size);
|
||||
}
|
||||
|
||||
int create_connect_config(const char *input_config, const char *bssid)
|
||||
{
|
||||
|
@ -880,8 +785,10 @@ int create_connect_config(const char *input_config, const char *bssid)
|
|||
return VANILLA_SUCCESS;
|
||||
}
|
||||
|
||||
int sync_with_console_internal(struct wpa_ctrl *ctrl, uint16_t code)
|
||||
void *sync_with_console_internal(void *data)
|
||||
{
|
||||
struct sync_args *args = (struct sync_args *) data;
|
||||
|
||||
char buf[16384];
|
||||
const size_t buf_len = sizeof(buf);
|
||||
|
||||
|
@ -898,7 +805,7 @@ int sync_with_console_internal(struct wpa_ctrl *ctrl, uint16_t code)
|
|||
|
||||
// print_info("SCANNING");
|
||||
actual_buf_len = buf_len;
|
||||
wpa_ctrl_command(ctrl, "SCAN", buf, &actual_buf_len);
|
||||
wpa_ctrl_command(args->ctrl, "SCAN", buf, &actual_buf_len);
|
||||
|
||||
if (!memcmp(buf, "FAIL-BUSY", 9)) {
|
||||
//print_info("DEVICE BUSY, RETRYING");
|
||||
|
@ -913,7 +820,7 @@ int sync_with_console_internal(struct wpa_ctrl *ctrl, uint16_t code)
|
|||
|
||||
//print_info("WAITING FOR SCAN RESULTS");
|
||||
actual_buf_len = buf_len;
|
||||
wpa_ctrl_command(ctrl, "SCAN_RESULTS", buf, &actual_buf_len);
|
||||
wpa_ctrl_command(args->ctrl, "SCAN_RESULTS", buf, &actual_buf_len);
|
||||
print_info("RECEIVED SCAN RESULTS");
|
||||
|
||||
const char *line = strtok(buf, "\n");
|
||||
|
@ -928,17 +835,17 @@ int sync_with_console_internal(struct wpa_ctrl *ctrl, uint16_t code)
|
|||
bssid[17] = '\0';
|
||||
|
||||
char wps_buf[100];
|
||||
snprintf(wps_buf, sizeof(wps_buf), "WPS_PIN %.*s %04d5678", 17, bssid, code);
|
||||
snprintf(wps_buf, sizeof(wps_buf), "WPS_PIN %.*s %04d5678", 17, bssid, args->code);
|
||||
|
||||
size_t actual_buf_len = buf_len;
|
||||
wpa_ctrl_command(ctrl, wps_buf, buf, &actual_buf_len);
|
||||
wpa_ctrl_command(args->ctrl, wps_buf, buf, &actual_buf_len);
|
||||
|
||||
static const int max_wait = 20;
|
||||
int wait_count = 0;
|
||||
int cred_received = 0;
|
||||
|
||||
while (!is_interrupted()) {
|
||||
while (wait_count < max_wait && !wpa_ctrl_pending(ctrl)) {
|
||||
while (wait_count < max_wait && !wpa_ctrl_pending(args->ctrl)) {
|
||||
if (is_interrupted()) goto exit_loop;
|
||||
sleep(1);
|
||||
wait_count++;
|
||||
|
@ -950,7 +857,7 @@ int sync_with_console_internal(struct wpa_ctrl *ctrl, uint16_t code)
|
|||
}
|
||||
|
||||
actual_buf_len = buf_len;
|
||||
wpa_ctrl_recv(ctrl, buf, &actual_buf_len);
|
||||
wpa_ctrl_recv(args->ctrl, buf, &actual_buf_len);
|
||||
print_info("CRED RECV: %.*s", buf_len, buf);
|
||||
|
||||
if (!memcmp("<3>WPS-CRED-RECEIVED", buf, 20)) {
|
||||
|
@ -964,7 +871,7 @@ int sync_with_console_internal(struct wpa_ctrl *ctrl, uint16_t code)
|
|||
// Tell wpa_supplicant to save config
|
||||
actual_buf_len = buf_len;
|
||||
print_info("SAVING CONFIG", actual_buf_len, buf);
|
||||
wpa_ctrl_command(ctrl, "SAVE_CONFIG", buf, &actual_buf_len);
|
||||
wpa_ctrl_command(args->ctrl, "SAVE_CONFIG", buf, &actual_buf_len);
|
||||
|
||||
// Create connect config which needs a couple more parameters
|
||||
create_connect_config(get_wireless_authenticate_config_filename(), bssid);
|
||||
|
@ -977,23 +884,61 @@ int sync_with_console_internal(struct wpa_ctrl *ctrl, uint16_t code)
|
|||
} while (!found_console);
|
||||
|
||||
exit_loop:
|
||||
return found_console ? VANILLA_SUCCESS : VANILLA_ERROR;
|
||||
return THREADRESULT(found_console ? VANILLA_SUCCESS : VANILLA_ERROR);
|
||||
}
|
||||
|
||||
int thunk_to_sync(struct wpa_ctrl *ctrl, void *data)
|
||||
void *do_connect(void *data)
|
||||
{
|
||||
struct sync_args *args = (struct sync_args *) data;
|
||||
return sync_with_console_internal(ctrl, args->code);
|
||||
|
||||
while (1) {
|
||||
while (!wpa_ctrl_pending(args->ctrl)) {
|
||||
sleep(2);
|
||||
print_info("WAITING FOR CONNECTION");
|
||||
|
||||
if (is_interrupted()) return THREADRESULT(VANILLA_ERROR);
|
||||
}
|
||||
|
||||
char buf[1024];
|
||||
size_t actual_buf_len = sizeof(buf);
|
||||
wpa_ctrl_recv(args->ctrl, buf, &actual_buf_len);
|
||||
print_info("CONN RECV: %.*s", actual_buf_len, buf);
|
||||
|
||||
if (memcmp(buf, "<3>CTRL-EVENT-CONNECTED", 23) == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (is_interrupted()) return THREADRESULT(VANILLA_ERROR);
|
||||
}
|
||||
|
||||
print_info("CONNECTED TO CONSOLE");
|
||||
|
||||
// Use DHCP on interface
|
||||
pid_t dhclient_pid;
|
||||
int r = call_dhcp(args->wireless_interface, &dhclient_pid);
|
||||
if (r != VANILLA_SUCCESS) {
|
||||
print_info("FAILED TO RUN DHCP ON %s", args->wireless_interface);
|
||||
return THREADRESULT(r);
|
||||
} else {
|
||||
print_info("DHCP ESTABLISHED");
|
||||
}
|
||||
|
||||
call_ip((const char *[]){"ip", "route", "del", "default", "via", "192.168.1.1", "dev", args->wireless_interface, NULL});
|
||||
call_ip((const char *[]){"ip", "route", "del", "192.168.1.0/24", "dev", args->wireless_interface, NULL});
|
||||
call_ip((const char *[]){"route", "add", "-host", "192.168.1.10", "dev", args->wireless_interface, NULL});
|
||||
|
||||
create_all_relays();
|
||||
|
||||
int kill_ret = kill(dhclient_pid, SIGTERM);
|
||||
print_info("KILLING DHCLIENT %i", dhclient_pid);
|
||||
|
||||
return THREADRESULT(VANILLA_SUCCESS);
|
||||
}
|
||||
|
||||
int thunk_to_connect(struct wpa_ctrl *ctrl, void *data)
|
||||
void *vanilla_sync_with_console(void *data)
|
||||
{
|
||||
struct connect_args *args = (struct connect_args *) data;
|
||||
return do_connect(ctrl, args->wireless_interface);
|
||||
}
|
||||
struct sync_args *args = (struct sync_args *) data;
|
||||
|
||||
int vanilla_sync_with_console(const char *wireless_interface, uint16_t code)
|
||||
{
|
||||
const char *wireless_conf_file;
|
||||
|
||||
FILE *config;
|
||||
|
@ -1001,24 +946,125 @@ int vanilla_sync_with_console(const char *wireless_interface, uint16_t code)
|
|||
config = fopen(wireless_conf_file, "w");
|
||||
if (!config) {
|
||||
print_info("FAILED TO WRITE TEMP CONFIG: %s", wireless_conf_file);
|
||||
return VANILLA_ERROR;
|
||||
return THREADRESULT(VANILLA_ERROR);
|
||||
}
|
||||
|
||||
fprintf(config, "ctrl_interface=%s\nupdate_config=1\n", wpa_ctrl_interface);
|
||||
fclose(config);
|
||||
|
||||
struct sync_args args;
|
||||
args.code = code;
|
||||
args->start_routine = sync_with_console_internal;
|
||||
args->wireless_config = wireless_conf_file;
|
||||
|
||||
return wpa_setup_environment(wireless_interface, wireless_conf_file, thunk_to_sync, &args);
|
||||
void *ret = wpa_setup_environment(args);
|
||||
|
||||
pthread_mutex_lock(&sync_mutex);
|
||||
sync_result_ready = 1;
|
||||
sync_result = (uint8_t) (uintptr_t) ret;
|
||||
pthread_mutex_unlock(&sync_mutex);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int vanilla_connect_to_console(const char *wireless_interface)
|
||||
void *vanilla_connect_to_console(void *data)
|
||||
{
|
||||
struct connect_args args;
|
||||
args.wireless_interface = wireless_interface;
|
||||
struct sync_args *args = (struct sync_args *) data;
|
||||
args->start_routine = do_connect;
|
||||
args->wireless_config = get_wireless_connect_config_filename();
|
||||
return wpa_setup_environment(args);
|
||||
}
|
||||
|
||||
return wpa_setup_environment(wireless_interface, get_wireless_connect_config_filename(), thunk_to_connect, &args);
|
||||
void vanilla_listen(const char *wireless_interface)
|
||||
{
|
||||
int skt = open_socket(VANILLA_PIPE_CMD_SERVER_PORT);
|
||||
uint32_t control_code;
|
||||
|
||||
struct sockaddr_in addr = {0};
|
||||
socklen_t addr_size = sizeof(addr);
|
||||
|
||||
pthread_mutex_init(&running_mutex, NULL);
|
||||
pthread_mutex_init(&action_mutex, NULL);
|
||||
pthread_mutex_init(&main_loop_mutex, NULL);
|
||||
pthread_mutex_init(&sync_mutex, NULL);
|
||||
|
||||
signal(SIGINT, sigint_handler);
|
||||
signal(SIGTERM, sigint_handler);
|
||||
|
||||
pthread_t stdin_thread;
|
||||
pthread_create(&stdin_thread, NULL, read_stdin, NULL);
|
||||
|
||||
main_loop = 1;
|
||||
|
||||
pthread_mutex_lock(&main_loop_mutex);
|
||||
|
||||
pprint("READY\n");
|
||||
|
||||
while (main_loop) {
|
||||
pthread_mutex_unlock(&main_loop_mutex);
|
||||
|
||||
// If we got a sync result
|
||||
pthread_mutex_lock(&sync_mutex);
|
||||
if (sync_result_ready) {
|
||||
control_code = htonl(VANILLA_PIPE_CC_SYNC_STATUS | (sync_result & 0xFF));
|
||||
sendto(skt, &control_code, sizeof(control_code), 0, (struct sockaddr *) &addr, sizeof(addr));
|
||||
sync_result_ready = 0;
|
||||
}
|
||||
pthread_mutex_unlock(&sync_mutex);
|
||||
|
||||
ssize_t r = recvfrom(skt, &control_code, sizeof(control_code), 0, (struct sockaddr *) &addr, &addr_size);
|
||||
if (r <= 0) {
|
||||
goto repeat_loop;
|
||||
}
|
||||
|
||||
control_code = ntohl(control_code);
|
||||
|
||||
if ((control_code >> 16) == (VANILLA_PIPE_CC_SYNC >> 16) || control_code == VANILLA_PIPE_CC_CONNECT) {
|
||||
print_info("RECEIVED SYNC/CONNECT SIGNAL");
|
||||
|
||||
if (pthread_mutex_trylock(&action_mutex) == 0) {
|
||||
struct sync_args *args = malloc(sizeof(struct sync_args));
|
||||
args->wireless_interface = wireless_interface;
|
||||
args->code = control_code & 0xFFFF;
|
||||
args->start_routine = (control_code == VANILLA_PIPE_CC_CONNECT) ? vanilla_connect_to_console : vanilla_sync_with_console;
|
||||
|
||||
client_address = addr.sin_addr;
|
||||
|
||||
// Acknowledge
|
||||
control_code = htonl(VANILLA_PIPE_CC_BIND_ACK);
|
||||
sendto(skt, &control_code, sizeof(control_code), 0, (struct sockaddr *) &addr, sizeof(addr));
|
||||
|
||||
pthread_t thread;
|
||||
int thread_ret;
|
||||
if (pthread_create(&thread, NULL, thread_handler, args) != 0) {
|
||||
print_info("FAILED TO CREATE THREAD");
|
||||
free(args);
|
||||
}
|
||||
} else {
|
||||
// Busy
|
||||
control_code = htonl(VANILLA_PIPE_CC_BUSY);
|
||||
sendto(skt, &control_code, sizeof(control_code), 0, (struct sockaddr *) &addr, sizeof(addr));
|
||||
}
|
||||
} else if (control_code == VANILLA_PIPE_CC_UNBIND) {
|
||||
print_info("RECEIVED UNBIND SIGNAL");
|
||||
pthread_mutex_lock(&running_mutex);
|
||||
running = 0;
|
||||
pthread_mutex_unlock(&running_mutex);
|
||||
}
|
||||
|
||||
repeat_loop:
|
||||
pthread_mutex_lock(&main_loop_mutex);
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&main_loop_mutex);
|
||||
|
||||
// Interrupt our stdin thread
|
||||
signal(SIGINT, SIG_DFL);
|
||||
signal(SIGTERM, SIG_DFL);
|
||||
pthread_kill(stdin_thread, SIGINT);
|
||||
|
||||
pthread_mutex_destroy(&sync_mutex);
|
||||
pthread_mutex_destroy(&main_loop_mutex);
|
||||
pthread_mutex_destroy(&action_mutex);
|
||||
pthread_mutex_destroy(&running_mutex);
|
||||
}
|
||||
|
||||
int vanilla_has_config()
|
||||
|
|
|
@ -8,10 +8,6 @@
|
|||
struct wpa_ctrl;
|
||||
extern const char *wpa_ctrl_interface;
|
||||
|
||||
typedef int (*ready_callback_t)(struct wpa_ctrl *, void *);
|
||||
|
||||
int wpa_setup_environment(const char *wireless_interface, const char *wireless_conf_file, ready_callback_t callback, void *callback_data);
|
||||
|
||||
void wpa_ctrl_command(struct wpa_ctrl *ctrl, const char *cmd, char *buf, size_t *buf_len);
|
||||
int start_wpa_supplicant(const char *wireless_interface, const char *config_file, pid_t *pid);
|
||||
|
||||
|
@ -21,10 +17,8 @@ int is_networkmanager_managing_device(const char *wireless_interface, int *is_ma
|
|||
int disable_networkmanager_on_device(const char *wireless_interface);
|
||||
int enable_networkmanager_on_device(const char *wireless_interface);
|
||||
|
||||
int vanilla_sync_with_console(const char *wireless_interface, uint16_t code);
|
||||
int vanilla_connect_to_console(const char *wireless_interface);
|
||||
int vanilla_has_config();
|
||||
|
||||
void pprint(const char *fmt, ...);
|
||||
|
||||
void vanilla_listen(const char *wireless_interface);
|
||||
|
||||
#endif // VANILLA_WPA_H
|
||||
|
|
Loading…
Reference in a new issue