Minor changes to code indentation
This commit is contained in:
parent
7f2bd7f4f0
commit
e7cfaa1d99
121
daemon/rtsp_client.cpp
Executable file → Normal file
121
daemon/rtsp_client.cpp
Executable file → Normal file
@ -21,13 +21,13 @@
|
|||||||
|
|
||||||
#include <boost/algorithm/string.hpp>
|
#include <boost/algorithm/string.hpp>
|
||||||
#include <boost/asio/ip/tcp.hpp>
|
#include <boost/asio/ip/tcp.hpp>
|
||||||
|
#include <chrono>
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <istream>
|
#include <istream>
|
||||||
|
#include <map>
|
||||||
#include <ostream>
|
#include <ostream>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <chrono>
|
|
||||||
#include <map>
|
|
||||||
|
|
||||||
#include "log.hpp"
|
#include "log.hpp"
|
||||||
#include "utils.hpp"
|
#include "utils.hpp"
|
||||||
@ -37,7 +37,6 @@ using namespace boost::asio;
|
|||||||
using namespace boost::asio::ip;
|
using namespace boost::asio::ip;
|
||||||
using namespace boost::algorithm;
|
using namespace boost::algorithm;
|
||||||
|
|
||||||
|
|
||||||
struct RtspResponse {
|
struct RtspResponse {
|
||||||
int32_t cseq{-1};
|
int32_t cseq{-1};
|
||||||
std::string content_type;
|
std::string content_type;
|
||||||
@ -88,7 +87,7 @@ RtspResponse read_response(tcp::iostream& s, uint16_t max_length) {
|
|||||||
<< "cannot perform number conversion";
|
<< "cannot perform number conversion";
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_LOG_TRIVIAL(debug) << "rtsp_client:: reading body length "
|
BOOST_LOG_TRIVIAL(debug) << "rtsp_client:: reading body length "
|
||||||
<< res.content_length;
|
<< res.content_length;
|
||||||
// read up to max_length
|
// read up to max_length
|
||||||
if (res.content_length > 0 && res.content_length < max_length) {
|
if (res.content_length > 0 && res.content_length < max_length) {
|
||||||
@ -101,14 +100,13 @@ RtspResponse read_response(tcp::iostream& s, uint16_t max_length) {
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<bool, RtspSource> RtspClient::process(
|
std::pair<bool, RtspSource> RtspClient::process(RtspClient::Observer callback,
|
||||||
RtspClient::Observer callback,
|
const std::string& name,
|
||||||
const std::string& name,
|
const std::string& domain,
|
||||||
const std::string& domain,
|
const std::string& path,
|
||||||
const std::string& path,
|
const std::string& address,
|
||||||
const std::string& address,
|
const std::string& port,
|
||||||
const std::string& port,
|
bool wait_for_updates) {
|
||||||
bool wait_for_updates) {
|
|
||||||
RtspSource rtsp_source;
|
RtspSource rtsp_source;
|
||||||
ip::tcp::iostream s;
|
ip::tcp::iostream s;
|
||||||
try {
|
try {
|
||||||
@ -160,88 +158,89 @@ std::pair<bool, RtspSource> RtspClient::process(
|
|||||||
auto res = read_response(s, max_body_length);
|
auto res = read_response(s, max_body_length);
|
||||||
if (is_describe && res.cseq != cseq) {
|
if (is_describe && res.cseq != cseq) {
|
||||||
BOOST_LOG_TRIVIAL(error)
|
BOOST_LOG_TRIVIAL(error)
|
||||||
<< "rtsp_client:: invalid response sequence " << res.cseq
|
<< "rtsp_client:: invalid response sequence " << res.cseq
|
||||||
<< " from rtsp://" << address << ":" << port << path;
|
<< " from rtsp://" << address << ":" << port << path;
|
||||||
return {false, rtsp_source};
|
return {false, rtsp_source};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!res.content_type.empty() &&
|
if (!res.content_type.empty() &&
|
||||||
res.content_type.rfind("application/sdp", 0) == std::string::npos) {
|
res.content_type.rfind("application/sdp", 0) == std::string::npos) {
|
||||||
BOOST_LOG_TRIVIAL(error) << "rtsp_client:: unsupported content-type "
|
BOOST_LOG_TRIVIAL(error) << "rtsp_client:: unsupported content-type "
|
||||||
<< res.content_type << " from "
|
<< res.content_type << " from "
|
||||||
<< "rtsp://" << address << ":" << port << path;
|
<< "rtsp://" << address << ":" << port << path;
|
||||||
if (is_describe) {
|
if (is_describe) {
|
||||||
return {false, rtsp_source};
|
return {false, rtsp_source};
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
ss << "rtsp:" << std::hex
|
ss << "rtsp:" << std::hex
|
||||||
<< crc16(reinterpret_cast<const uint8_t*>(res.body.c_str()),
|
<< crc16(reinterpret_cast<const uint8_t*>(res.body.c_str()),
|
||||||
res.body.length());
|
res.body.length());
|
||||||
/*<< std::hex << ip::address_v4::from_string(address.c_str()).to_ulong();*/
|
/*<< std::hex <<
|
||||||
|
* ip::address_v4::from_string(address.c_str()).to_ulong();*/
|
||||||
rtsp_source.id = ss.str();
|
rtsp_source.id = ss.str();
|
||||||
rtsp_source.source = "mDNS";
|
rtsp_source.source = "mDNS";
|
||||||
rtsp_source.address = address;
|
rtsp_source.address = address;
|
||||||
rtsp_source.sdp = std::move(res.body);
|
rtsp_source.sdp = std::move(res.body);
|
||||||
BOOST_LOG_TRIVIAL(info) << "rtsp_client:: completed "
|
BOOST_LOG_TRIVIAL(info) << "rtsp_client:: completed "
|
||||||
<< "rtsp://" << address << ":" << port << path;
|
<< "rtsp://" << address << ":" << port << path;
|
||||||
|
|
||||||
if (is_announce || is_describe) {
|
if (is_announce || is_describe) {
|
||||||
if (is_announce && announced_name.empty()) {
|
if (is_announce && announced_name.empty()) {
|
||||||
/* if no name from URL we try from SDP file */
|
/* if no name from URL we try from SDP file */
|
||||||
announced_name = sdp_get_subject(rtsp_source.sdp);
|
announced_name = sdp_get_subject(rtsp_source.sdp);
|
||||||
}
|
}
|
||||||
callback(announced_name.empty() ? name : announced_name, domain,
|
callback(announced_name.empty() ? name : announced_name, domain,
|
||||||
rtsp_source);
|
rtsp_source);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_announce) {
|
if (is_announce) {
|
||||||
s << "RTSP/1.0 200 OK\r\n";
|
s << "RTSP/1.0 200 OK\r\n";
|
||||||
s << "CSeq: " << res.cseq << "\r\n";
|
s << "CSeq: " << res.cseq << "\r\n";
|
||||||
s << "\r\n";
|
s << "\r\n";
|
||||||
} else if (!is_describe) {
|
} else if (!is_describe) {
|
||||||
s << "RTSP/1.0 405 Method Not Allowed\r\n";
|
s << "RTSP/1.0 405 Method Not Allowed\r\n";
|
||||||
s << "CSeq: " << res.cseq << "\r\n";
|
s << "CSeq: " << res.cseq << "\r\n";
|
||||||
s << "\r\n";
|
s << "\r\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wait_for_updates) {
|
if (wait_for_updates) {
|
||||||
g_mutex.lock();
|
g_mutex.lock();
|
||||||
g_active_clients[{name, domain}] = &s;
|
g_active_clients[{name, domain}] = &s;
|
||||||
g_mutex.unlock();
|
g_mutex.unlock();
|
||||||
|
|
||||||
/* we start waiting for updates */
|
/* we start waiting for updates */
|
||||||
do {
|
do {
|
||||||
std::getline(s, request);
|
std::getline(s, request);
|
||||||
} while (request.empty() && !s.error());
|
} while (request.empty() && !s.error());
|
||||||
if (s.error()) {
|
if (s.error()) {
|
||||||
BOOST_LOG_TRIVIAL(info) << "rtsp_client:: end: "
|
BOOST_LOG_TRIVIAL(info)
|
||||||
<< s.error().message();
|
<< "rtsp_client:: end: " << s.error().message();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
BOOST_LOG_TRIVIAL(info) << "rtsp_client:: received " << request;
|
BOOST_LOG_TRIVIAL(info) << "rtsp_client:: received " << request;
|
||||||
boost::trim(request);
|
boost::trim(request);
|
||||||
is_describe = is_announce = false;
|
is_describe = is_announce = false;
|
||||||
announced_name = "";
|
announced_name = "";
|
||||||
std::vector<std::string> fields;
|
std::vector<std::string> fields;
|
||||||
split(fields, request, boost::is_any_of(" "));
|
split(fields, request, boost::is_any_of(" "));
|
||||||
if (fields.size() >= 2 && fields[0] == "ANNOUNCE") {
|
if (fields.size() >= 2 && fields[0] == "ANNOUNCE") {
|
||||||
auto const res = parse_url(fields[1]);
|
auto const res = parse_url(fields[1]);
|
||||||
if (std::get<0>(res)) {
|
if (std::get<0>(res)) {
|
||||||
/* if we find a valid announced source name we use it
|
/* if we find a valid announced source name we use it
|
||||||
* otherwise we try from SDP file or we use the mDNS name */
|
* otherwise we try from SDP file or we use the mDNS name */
|
||||||
auto path = std::get<4>(res);
|
auto path = std::get<4>(res);
|
||||||
if (path.rfind("/by-name/") != std::string::npos) {
|
if (path.rfind("/by-name/") != std::string::npos) {
|
||||||
announced_name = path.substr(9);
|
announced_name = path.substr(9);
|
||||||
BOOST_LOG_TRIVIAL(debug) << "rtsp_client:: found announced name "
|
BOOST_LOG_TRIVIAL(debug)
|
||||||
<< announced_name;
|
<< "rtsp_client:: found announced name " << announced_name;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
is_announce = true;
|
is_announce = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
} while (wait_for_updates);
|
||||||
} while (wait_for_updates);
|
|
||||||
} catch (std::exception& e) {
|
} catch (std::exception& e) {
|
||||||
BOOST_LOG_TRIVIAL(warning)
|
BOOST_LOG_TRIVIAL(warning)
|
||||||
<< "rtsp_client:: error with "
|
<< "rtsp_client:: error with "
|
||||||
@ -259,7 +258,6 @@ std::pair<bool, RtspSource> RtspClient::process(
|
|||||||
return {true, rtsp_source};
|
return {true, rtsp_source};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void RtspClient::stop(const std::string& name, const std::string& domain) {
|
void RtspClient::stop(const std::string& name, const std::string& domain) {
|
||||||
std::lock_guard<std::mutex> lock(g_mutex);
|
std::lock_guard<std::mutex> lock(g_mutex);
|
||||||
auto it = g_active_clients.find({name, domain});
|
auto it = g_active_clients.find({name, domain});
|
||||||
@ -279,9 +277,8 @@ void RtspClient::stop_all() {
|
|||||||
std::lock_guard<std::mutex> lock(g_mutex);
|
std::lock_guard<std::mutex> lock(g_mutex);
|
||||||
auto it = g_active_clients.begin();
|
auto it = g_active_clients.begin();
|
||||||
while (it != g_active_clients.end()) {
|
while (it != g_active_clients.end()) {
|
||||||
BOOST_LOG_TRIVIAL(info)
|
BOOST_LOG_TRIVIAL(info) << "rtsp_client:: stopping client "
|
||||||
<< "rtsp_client:: stopping client "
|
<< it->first.first << " " << it->first.second;
|
||||||
<< it->first.first << " " << it->first.second;
|
|
||||||
#if BOOST_VERSION < 106600
|
#if BOOST_VERSION < 106600
|
||||||
it->second->close();
|
it->second->close();
|
||||||
#else
|
#else
|
||||||
@ -291,10 +288,8 @@ void RtspClient::stop_all() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<bool, RtspSource> RtspClient::describe(
|
std::pair<bool, RtspSource> RtspClient::describe(const std::string& path,
|
||||||
const std::string& path,
|
const std::string& address,
|
||||||
const std::string& address,
|
const std::string& port) {
|
||||||
const std::string& port) {
|
|
||||||
return RtspClient::process({}, {}, {}, path, address, port, false);
|
return RtspClient::process({}, {}, {}, path, address, port, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,8 +20,8 @@
|
|||||||
#ifndef _RTSP_CLIENT_HPP_
|
#ifndef _RTSP_CLIENT_HPP_
|
||||||
#define _RTSP_CLIENT_HPP_
|
#define _RTSP_CLIENT_HPP_
|
||||||
|
|
||||||
#include <mutex>
|
|
||||||
#include <boost/asio/ip/tcp.hpp>
|
#include <boost/asio/ip/tcp.hpp>
|
||||||
|
#include <mutex>
|
||||||
|
|
||||||
struct RtspSource {
|
struct RtspSource {
|
||||||
std::string id;
|
std::string id;
|
||||||
@ -36,33 +36,32 @@ class RtspClient {
|
|||||||
constexpr static uint16_t client_timeout = 10; // sec
|
constexpr static uint16_t client_timeout = 10; // sec
|
||||||
constexpr static const char dft_port[] = "554";
|
constexpr static const char dft_port[] = "554";
|
||||||
|
|
||||||
using Observer = std::function<void(
|
using Observer = std::function<void(const std::string& name,
|
||||||
const std::string& name,
|
const std::string& domain,
|
||||||
const std::string& domain,
|
const RtspSource& source)>;
|
||||||
const RtspSource& source)>;
|
|
||||||
|
|
||||||
static std::pair<bool, RtspSource> process(
|
static std::pair<bool, RtspSource> process(Observer callback,
|
||||||
Observer callback,
|
const std::string& name,
|
||||||
const std::string& name,
|
const std::string& domain,
|
||||||
const std::string& domain,
|
const std::string& path,
|
||||||
const std::string& path,
|
const std::string& address,
|
||||||
const std::string& address,
|
const std::string& port = dft_port,
|
||||||
const std::string& port = dft_port,
|
bool wait_for_updates = true);
|
||||||
bool wait_for_updates = true);
|
|
||||||
|
|
||||||
static void stop(const std::string& name, const std::string& domain);
|
static void stop(const std::string& name, const std::string& domain);
|
||||||
static void stop_all();
|
static void stop_all();
|
||||||
|
|
||||||
static std::pair<bool, RtspSource> describe(
|
static std::pair<bool, RtspSource> describe(
|
||||||
const std::string& path,
|
const std::string& path,
|
||||||
const std::string& address,
|
const std::string& address,
|
||||||
const std::string& port = dft_port);
|
const std::string& port = dft_port);
|
||||||
|
|
||||||
inline static std::atomic<uint16_t> g_seq_number{0};
|
inline static std::atomic<uint16_t> g_seq_number{0};
|
||||||
inline static std::map<std::pair<std::string /*name*/, std::string /*domain*/>,
|
inline static std::map<
|
||||||
boost::asio::ip::tcp::iostream* /*stream*/> g_active_clients;
|
std::pair<std::string /*name*/, std::string /*domain*/>,
|
||||||
|
boost::asio::ip::tcp::iostream* /*stream*/>
|
||||||
|
g_active_clients;
|
||||||
inline static std::mutex g_mutex;
|
inline static std::mutex g_mutex;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
x
Reference in New Issue
Block a user