forked from wtsnz/obs-ios-camera-source
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request wtsnz#60 from wtsnz/feature/refactor-portal
Refactor portal lib
- Loading branch information
Showing
26 changed files
with
1,780 additions
and
1,088 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,6 @@ | ||
/* | ||
portal | ||
Copyright (C) 2018 Will Townsend <[email protected]> | ||
Copyright (C) 2018 Will Townsend <[email protected]> | ||
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 | ||
|
@@ -17,90 +17,139 @@ | |
*/ | ||
|
||
#include "Channel.hpp" | ||
#include <iostream> | ||
|
||
namespace portal | ||
namespace portal { | ||
|
||
Channel::Channel(int port_, int conn_) | ||
{ | ||
port = port_; | ||
conn = conn_; | ||
|
||
Channel::Channel(int port_, int conn_) | ||
{ | ||
port = port_; | ||
conn = conn_; | ||
setState(State::Disconnected); | ||
} | ||
|
||
protocol = std::make_unique<SimpleDataPacketProtocol>(); | ||
Channel::~Channel() | ||
{ | ||
running = false; | ||
WaitForInternalThreadToExit(); | ||
portal_log("%s: Deallocating\n", __func__); | ||
} | ||
|
||
running = StartInternalThread(); | ||
} | ||
bool Channel::start() | ||
{ | ||
if (getState() == State::Connected) { | ||
return false; | ||
} | ||
|
||
Channel::~Channel() | ||
{ | ||
running = false; | ||
WaitForInternalThreadToExit(); | ||
portal_log("%s: %d: Deallocating\n", __func__, conn); | ||
} | ||
running = StartInternalThread(); | ||
|
||
void Channel::close() | ||
{ | ||
running = false; | ||
WaitForInternalThreadToExit(); | ||
usbmuxd_disconnect(conn); | ||
} | ||
if (running == true) { | ||
setState(State::Connecting); | ||
} | ||
|
||
/** Returns true if the thread was successfully started, false if there was an error starting the thread */ | ||
bool Channel::StartInternalThread() | ||
{ | ||
_thread = std::thread(InternalThreadEntryFunc, this); | ||
return true; | ||
} | ||
return running; | ||
} | ||
|
||
/** Will not return until the internal thread has exited. */ | ||
void Channel::WaitForInternalThreadToExit() | ||
{ | ||
if (_thread.joinable()) | ||
{ | ||
_thread.join(); | ||
} | ||
} | ||
bool Channel::close() | ||
{ | ||
running = false; | ||
|
||
void Channel::StopInternalThread() | ||
{ | ||
running = false; | ||
} | ||
//// Wait for exit if close() wasn't called on the internal thread | ||
if (std::this_thread::get_id() != _thread.get_id()) { | ||
WaitForInternalThreadToExit(); | ||
} | ||
|
||
void Channel::InternalThreadEntry() | ||
{ | ||
while (running) | ||
{ | ||
auto ret = usbmuxd_disconnect(conn); | ||
|
||
return ret; | ||
} | ||
|
||
const uint32_t numberOfBytesToAskFor = 65536; // (1 << 16); // This is the value in DarkLighting | ||
uint32_t numberOfBytesReceived = 0; | ||
bool Channel::send(std::vector<char> data) | ||
{ | ||
if (getState() != State::Connected) { | ||
return false; | ||
} | ||
|
||
char buffer[numberOfBytesToAskFor]; | ||
uint32_t sentBytes = 0; | ||
|
||
int ret = usbmuxd_recv_timeout(conn, (char *)&buffer, numberOfBytesToAskFor, &numberOfBytesReceived, 100); | ||
usbmuxd_send(conn, &data[0], data.size(), &sentBytes); | ||
} | ||
|
||
if (ret == 0) | ||
{ | ||
if (numberOfBytesReceived > 0) | ||
{ | ||
if (running) { | ||
protocol->processData((char *)buffer, numberOfBytesReceived); | ||
} | ||
} | ||
} | ||
else | ||
{ | ||
portal_log("%d: There was an error receiving data\n", conn); | ||
running = false; | ||
} | ||
} | ||
} | ||
void Channel::setState(State state) | ||
{ | ||
if (state == getState()) { | ||
return; | ||
} | ||
|
||
void Channel::simpleDataPacketProtocolDelegateDidProcessPacket(std::vector<char> packet, int type, int tag) | ||
{ | ||
std::shared_ptr<ChannelDelegate> strongDelegate = delegate.lock(); | ||
if (strongDelegate) { | ||
strongDelegate->channelDidReceivePacket(packet, type, tag); | ||
} | ||
//std::cout << "Channel:setState: " << state << std::endl; | ||
_state = state; | ||
|
||
if (auto delegate = this->delegate.lock()) { | ||
delegate->channelDidChangeState(state); | ||
} | ||
} | ||
|
||
/** Returns true if the thread was successfully started, false if there was an error starting the thread */ | ||
bool Channel::StartInternalThread() | ||
{ | ||
_thread = std::thread(InternalThreadEntryFunc, this); | ||
return true; | ||
} | ||
|
||
/** Will not return until the internal thread has exited. */ | ||
void Channel::WaitForInternalThreadToExit() | ||
{ | ||
running = false; | ||
std::unique_lock<std::mutex> lock(worker_mutex); | ||
if (_thread.joinable()) { | ||
_thread.join(); | ||
} | ||
lock.unlock(); | ||
} | ||
|
||
void Channel::StopInternalThread() | ||
{ | ||
running = false; | ||
} | ||
|
||
// TODO: https://stackoverflow.com/questions/58477291/function-exceeds-stack-size-consider-moving-some-data-to-heap-c6262 | ||
void Channel::InternalThreadEntry() | ||
{ | ||
while (running) { | ||
std::unique_lock<std::mutex> lock(worker_mutex); | ||
|
||
const uint32_t numberOfBytesToAskFor = 1 << 18; // 262,144 | ||
uint32_t numberOfBytesReceived = 0; | ||
auto vector = std::vector<char>(numberOfBytesToAskFor); | ||
|
||
int ret = usbmuxd_recv_timeout(conn, vector.data(), | ||
numberOfBytesToAskFor, | ||
&numberOfBytesReceived, 10); | ||
|
||
if (ret == 0) { | ||
if (getState() == State::Connecting) { | ||
setState(State::Connected); | ||
} | ||
|
||
if (numberOfBytesReceived > 0) { | ||
vector.resize(numberOfBytesReceived); | ||
|
||
if (auto spt = delegate.lock()) { | ||
spt->channelDidReceiveData( | ||
vector); | ||
} | ||
} | ||
lock.unlock(); | ||
} else { | ||
// Unlock now as the `close()` function also requires | ||
// a lock | ||
lock.unlock(); | ||
portal_log("There was an error receiving data"); | ||
close(); | ||
setState(State::Errored); | ||
} | ||
} | ||
} | ||
|
||
} // namespace portal |
Oops, something went wrong.