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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

#include <nabto/webrtc/device.hpp>
#include <nabto/webrtc/util/logging.hpp>
#include <optional>
#include <rtc/rtc.hpp>
#include <variant>

Expand All @@ -12,21 +13,30 @@ class RtcWebsocketWrapper
: public nabto::webrtc::SignalingWebsocket,
public std::enable_shared_from_this<RtcWebsocketWrapper> {
public:
static nabto::webrtc::SignalingWebsocketPtr create() {
return std::make_shared<RtcWebsocketWrapper>();
static nabto::webrtc::SignalingWebsocketPtr create(
std::optional<std::string> caBundle) {
return std::make_shared<RtcWebsocketWrapper>(caBundle);
}

RtcWebsocketWrapper() {}
RtcWebsocketWrapper(std::optional<std::string>& caBundle) {
if (caBundle.has_value()) {
rtc::WebSocketConfiguration conf;
conf.caCertificatePemFile = caBundle;
ws_ = std::make_shared<rtc::WebSocket>(conf);
} else {
ws_ = std::make_shared<rtc::WebSocket>();
}
}

bool send(const std::string& data) { return ws_.send(data); }
bool send(const std::string& data) { return ws_->send(data); }

void close() { return ws_.close(); }
void close() { return ws_->close(); }

void onOpen(std::function<void()> callback) { ws_.onOpen(callback); }
void onOpen(std::function<void()> callback) { ws_->onOpen(callback); }

void onMessage(std::function<void(const std::string& message)> callback) {
auto self = shared_from_this();
ws_.onMessage(
ws_->onMessage(
[self, callback](std::variant<rtc::binary, rtc::string> message) {
std::string msg;
if (std::holds_alternative<rtc::string>(message)) {
Expand All @@ -42,16 +52,16 @@ class RtcWebsocketWrapper
});
}

void onClosed(std::function<void()> callback) { ws_.onClosed(callback); }
void onClosed(std::function<void()> callback) { ws_->onClosed(callback); }

void open(const std::string& url) { ws_.open(url); }
void open(const std::string& url) { ws_->open(url); }

void onError(std::function<void(const std::string& error)> callback) {
ws_.onError(callback);
ws_->onError(callback);
}

private:
rtc::WebSocket ws_;
std::shared_ptr<rtc::WebSocket> ws_;
};

} // namespace example
Expand Down
35 changes: 32 additions & 3 deletions examples/libdatachannel/src/webrtc_device/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include <nabto/webrtc/util/message_transport.hpp>
#include <nabto/webrtc/util/std_timer.hpp>
#include <nabto/webrtc/util/token_generator.hpp>
#include <optional>
#include <webrtc_connection/webrtc_connection.hpp>

#include "h264_handler.hpp"
Expand All @@ -24,6 +25,7 @@ struct options {
std::string sharedSecret;
std::string sharedSecretId;
bool centralAuthorization;
std::optional<std::string> caBundle;
};

bool parse_options(int argc, char** argv, struct options& opts);
Expand All @@ -50,8 +52,8 @@ int main(int argc, char** argv) {
nabto::webrtc::util::NabtoTokenGenerator::create(
opts.productId, opts.deviceId, opts.privateKey);

auto http = nabto::webrtc::util::CurlHttpClient::create();
auto ws = nabto::example::RtcWebsocketWrapper::create();
auto http = nabto::webrtc::util::CurlHttpClient::create(opts.caBundle);
auto ws = nabto::example::RtcWebsocketWrapper::create(opts.caBundle);
auto tf = nabto::webrtc::util::StdTimerFactory::create();
auto trackHandler = nabto::example::H264TrackHandler::create(nullptr);

Expand Down Expand Up @@ -122,14 +124,24 @@ bool parse_options(int argc, char** argv, struct options& opts) {
"Optional. Shared secret used to sign and validate signaling messages",
cxxopts::value<std::string>())("central-authorization",
"Require central authorization")(
"h,help", "Shows this help text");
"ca-bundle",
"Optional. Path to a CA certificate file; overrides CURL_CA_BUNDLE "
"env var if set.",
cxxopts::value<std::string>())("h,help", "Shows this help text")(
"v,version", "Shows the Nabto WebRTC SDK version");
auto result = options.parse(argc, argv);

if (result.count("help")) {
std::cout << options.help({"", "Group"}) << std::endl;
return false;
}

if (result.count("version")) {
std::cout << "Nabto WebRTC SDK C++: "
<< nabto::webrtc::SignalingDevice::version() << std::endl;
return false;
}

if (result.count("deviceid") && result.count("productid")) {
opts.deviceId = result["deviceid"].as<std::string>();
opts.productId = result["productid"].as<std::string>();
Expand Down Expand Up @@ -176,6 +188,23 @@ bool parse_options(int argc, char** argv, struct options& opts) {
return false;
}

if (result.count("ca-bundle")) {
opts.caBundle = result["ca-bundle"].as<std::string>();
} else {
const char* curlCaBundle = std::getenv("CURL_CA_BUNDLE");
if (curlCaBundle != nullptr) {
opts.caBundle = std::string(curlCaBundle);
}
}
if (opts.caBundle.has_value()) {
std::ifstream f(opts.caBundle.value());
if (!f.good()) {
std::cout << "CA certificate bundle file does not exist: "
<< opts.caBundle.value() << std::endl;
return false;
}
}

} catch (const cxxopts::exceptions::exception& e) {
std::cout << "Error parsing options: " << e.what() << std::endl;
return false;
Expand Down
37 changes: 34 additions & 3 deletions examples/libdatachannel/src/webrtc_device_rtsp/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include <nabto/webrtc/util/message_transport.hpp>
#include <nabto/webrtc/util/std_timer.hpp>
#include <nabto/webrtc/util/token_generator.hpp>
#include <optional>
#include <webrtc_connection/webrtc_connection.hpp>

#include "h264_opus_rtsp_handler.hpp"
Expand All @@ -25,6 +26,7 @@ struct options {
std::string sharedSecretId;
bool centralAuthorization;
std::string rtspUrl;
std::optional<std::string> caBundle;
};

bool parse_options(int argc, char** argv, struct options& opts);
Expand All @@ -50,8 +52,10 @@ int main(int argc, char** argv) {
nabto::webrtc::util::NabtoTokenGenerator::create(
opts.productId, opts.deviceId, opts.privateKey);

auto http = nabto::webrtc::util::CurlHttpClient::create();
auto ws = nabto::example::RtcWebsocketWrapper::create();
nabto::webrtc::SignalingHttpClientPtr http =
nabto::webrtc::util::CurlHttpClient::create(opts.caBundle);
nabto::webrtc::SignalingWebsocketPtr ws =
nabto::example::RtcWebsocketWrapper::create(opts.caBundle);
auto tf = nabto::webrtc::util::StdTimerFactory::create();
auto trackHandler = nabto::example::H264TrackHandler::create(opts.rtspUrl);

Expand Down Expand Up @@ -125,14 +129,24 @@ bool parse_options(int argc, char** argv, struct options& opts) {
cxxopts::value<std::string>())("central-authorization",
"Require central authorization")(
"r,rtsp-url", "URL for the RTSP server", cxxopts::value<std::string>())(
"h,help", "Shows this help text");
"ca-bundle",
"Optional. Path to a CA certificate file; overrides CURL_CA_BUNDLE "
"env var if set.",
cxxopts::value<std::string>())("h,help", "Shows this help text")(
"v,version", "Shows the Nabto WebRTC SDK version");
auto result = options.parse(argc, argv);

if (result.count("help")) {
std::cout << options.help({"", "Group"}) << std::endl;
return false;
}

if (result.count("version")) {
std::cout << "Nabto WebRTC SDK C++: "
<< nabto::webrtc::SignalingDevice::version() << std::endl;
return false;
}

if (result.count("deviceid") && result.count("productid")) {
opts.deviceId = result["deviceid"].as<std::string>();
opts.productId = result["productid"].as<std::string>();
Expand Down Expand Up @@ -187,6 +201,23 @@ bool parse_options(int argc, char** argv, struct options& opts) {
return false;
}

if (result.count("ca-bundle")) {
opts.caBundle = result["ca-bundle"].as<std::string>();
} else {
const char* curlCaBundle = std::getenv("CURL_CA_BUNDLE");
if (curlCaBundle != nullptr) {
opts.caBundle = std::string(curlCaBundle);
}
}
if (opts.caBundle.has_value()) {
std::ifstream f(opts.caBundle.value());
if (!f.good()) {
std::cout << "CA certificate bundle file does not exist: "
<< opts.caBundle.value() << std::endl;
return false;
}
}

} catch (const cxxopts::exceptions::exception& e) {
std::cout << "Error parsing options: " << e.what() << std::endl;
return false;
Expand Down
2 changes: 1 addition & 1 deletion sdk/integration_test/test_instance.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ class TestInstance : public std::enable_shared_from_this<TestInstance> {
}

nabto::webrtc::SignalingDevicePtr createDevice() {
http_ = nabto::webrtc::util::CurlHttpClient::create();
http_ = nabto::webrtc::util::CurlHttpClient::create(std::nullopt);
ws_ = nabto::example::RtcWebsocketWrapper::create();
tf_ = nabto::webrtc::util::StdTimerFactory::create();
tokGen_ = TestTokenGen::create(accessToken_);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include <functional>
#include <memory>
#include <mutex>
#include <optional>
#include <thread>

namespace nabto {
Expand All @@ -24,13 +25,15 @@ class CurlHttpClient : public nabto::webrtc::SignalingHttpClient,
public std::enable_shared_from_this<CurlHttpClient> {
public:
/**
* Create an instance of the SignalingHttpClient.
* Create an instance of the SignalingHttpClient with a custom CA bundle.
*
* @param caBundle path to the CA bundle to use
* @return Smart pointer to the created SignalingHttpClient.
*/
static nabto::webrtc::SignalingHttpClientPtr create();
static nabto::webrtc::SignalingHttpClientPtr create(
std::optional<std::string> caBundle);

CurlHttpClient();
explicit CurlHttpClient(std::optional<std::string>& caBundle);
~CurlHttpClient() override;
CurlHttpClient(const CurlHttpClient&) = delete;
CurlHttpClient& operator=(const CurlHttpClient&) = delete;
Expand All @@ -46,6 +49,7 @@ class CurlHttpClient : public nabto::webrtc::SignalingHttpClient,
std::string writeBuffer_;
std::string authHeader_;
std::string ctHeader_;
std::optional<std::string> caBundle_;

struct curl_slist* curlReqHeaders_ = nullptr;

Expand Down
18 changes: 15 additions & 3 deletions sdk/src/signaling_util/curl_http_client/src/curl_async.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,21 @@
#include <functional>
#include <memory>
#include <mutex>
#include <optional>
#include <string>
#include <utility>

namespace nabto {
namespace webrtc {
namespace util {

nabto::webrtc::SignalingHttpClientPtr CurlHttpClient::create() {
return std::make_shared<CurlHttpClient>();
nabto::webrtc::SignalingHttpClientPtr CurlHttpClient::create(
std::optional<std::string> caBundle) {
return std::make_shared<CurlHttpClient>(caBundle);
}

CurlHttpClient::CurlHttpClient() : curl_(CurlAsync::create()) {}
CurlHttpClient::CurlHttpClient(std::optional<std::string>& caBundle)
: curl_(CurlAsync::create()), caBundle_(caBundle) {}

CurlHttpClient::~CurlHttpClient() {
if (curlReqHeaders_ != nullptr) {
Expand Down Expand Up @@ -63,6 +67,14 @@ bool CurlHttpClient::sendRequest(
return false;
}

if (caBundle_.has_value()) {
res = curl_easy_setopt(curl, CURLOPT_CAINFO, caBundle_.value().c_str());
if (res != CURLE_OK) {
NPLOGE << "Failed to set CA bundle with: " << curl_easy_strerror(res);
return false;
}
}

res = curl_easy_setopt(curl, CURLOPT_READFUNCTION, readFunc);

if (res != CURLE_OK) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,12 @@ namespace util {
class StdTimer : public nabto::webrtc::SignalingTimer,
public std::enable_shared_from_this<StdTimer> {
public:
~StdTimer() {}
~StdTimer() {
if (timer_.joinable()) {
timer_.join();
timer_ = std::thread();
}
}

void setTimeout(uint32_t timeoutMs, std::function<void()> cb) override {
auto self = shared_from_this();
Expand Down