diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index c806e9ab2..f5f6005d2 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -128,8 +128,7 @@ jobs:
- name: Run SRS regression-test
run: |
docker run --rm srs:test bash -c './objs/srs -c conf/regression-test.conf && sleep 10 && \
- cd 3rdparty/srs-bench && (./objs/srs_test -test.v || (cat ../../objs/srs.log && exit 1)) && \
- ./objs/srs_gb28181_test -test.v'
+ cd 3rdparty/srs-bench && (./objs/srs_test -test.v || (cat ../../objs/srs.log && exit 1))'
runs-on: ubuntu-22.04
coverage:
diff --git a/trunk/conf/full.conf b/trunk/conf/full.conf
index 0f3d3551f..a3e5f27b3 100644
--- a/trunk/conf/full.conf
+++ b/trunk/conf/full.conf
@@ -1648,32 +1648,6 @@ stream_caster {
# For gb28181 converter, listen at TCP port. for example, 9000.
# @remark We always enable bundle for media streams at this port.
listen 9000;
- # SIP server for GB28181. Please note that this is only a demonstrated SIP server, please never use it in your
- # online production environment. Instead please use [jsip](https://github.com/usnistgov/jsip) and there is a demo
- # [srs-sip](https://github.com/ossrs/srs-sip) also base on it, for more information please see project
- # [GB: External SIP](https://ossrs.io/lts/en-us/docs/v7/doc/gb28181#external-sip).
- sip {
- # Whether enable embedded SIP server. Please disable it if you want to use your own SIP server, see
- # [GB: External SIP](https://ossrs.io/lts/en-us/docs/v7/doc/gb28181#external-sip).
- # Default: on
- enabled on;
- # The SIP listen port, for TCP protocol.
- # Default: 5060
- listen 5060;
- # The SIP or media transport timeout in seconds.
- # Default: 60
- timeout 60;
- # When media disconnect, the wait time in seconds to re-invite device to publish. During this wait time, device
- # might send bye or unregister message(expire is 0), so that we will cancel the re-invite.
- # Default: 5
- reinvite 5;
- # The exposed candidate IPs, response in SDP connection line. It can be:
- # * Retrieve server IP automatically, from all network interfaces.
- # $CANDIDATE Read the IP from ENV variable, use * if not set.
- # x.x.x.x A specified IP address or DNS name, use * if 0.0.0.0.
- # Default: *
- candidate *;
- }
}
#
diff --git a/trunk/conf/gb28181-without-sip.conf b/trunk/conf/gb28181-without-sip.conf
deleted file mode 100644
index 31ab65f83..000000000
--- a/trunk/conf/gb28181-without-sip.conf
+++ /dev/null
@@ -1,57 +0,0 @@
-
-max_connections 1000;
-daemon off;
-srs_log_tank console;
-
-# RTMP server configuration
-rtmp {
- listen 1935;
-}
-
-stream_caster {
- enabled on;
- caster gb28181;
- output rtmp://127.0.0.1/live/[stream];
- listen 9000;
- sip {
- enabled off;
- }
-}
-
-http_server {
- enabled on;
- listen 8080;
- dir ./objs/nginx/html;
-}
-
-http_api {
- enabled on;
- listen 1985;
-}
-stats {
- network 0;
-}
-rtc_server {
- enabled on;
- listen 8000; # UDP port
- # @see https://ossrs.io/lts/en-us/docs/v7/doc/webrtc#config-candidate
- candidate $CANDIDATE;
-}
-
-vhost __defaultVhost__ {
- rtc {
- enabled on;
- # @see https://ossrs.io/lts/en-us/docs/v7/doc/webrtc#rtmp-to-rtc
- rtmp_to_rtc on;
- # @see https://ossrs.io/lts/en-us/docs/v7/doc/webrtc#rtc-to-rtmp
- rtc_to_rtmp on;
- }
- http_remux {
- enabled on;
- mount [vhost]/[app]/[stream].flv;
- }
- hls {
- enabled on;
- }
-}
-
diff --git a/trunk/conf/gb28181.conf b/trunk/conf/gb28181.conf
index 020872d6f..2b35d3cc0 100644
--- a/trunk/conf/gb28181.conf
+++ b/trunk/conf/gb28181.conf
@@ -13,12 +13,6 @@ stream_caster {
caster gb28181;
output rtmp://127.0.0.1/live/[stream];
listen 9000;
- sip {
- enabled on;
- listen 5060;
- # @see https://ossrs.io/lts/en-us/docs/v7/doc/gb28181#config-candidate
- candidate $CANDIDATE;
- }
}
http_server {
diff --git a/trunk/conf/push.gb28181.conf b/trunk/conf/push.gb28181.conf
index 3b4157141..796eb1796 100644
--- a/trunk/conf/push.gb28181.conf
+++ b/trunk/conf/push.gb28181.conf
@@ -17,8 +17,7 @@ stream_caster {
# @see https://ossrs.io/lts/en-us/docs/v7/doc/gb28181#config-candidate
host $CANDIDATE;
sip {
- enabled on;
- listen 5060;
+ enabled off;
}
}
diff --git a/trunk/doc/CHANGELOG.md b/trunk/doc/CHANGELOG.md
index f0d1e5324..5cee3e22c 100644
--- a/trunk/doc/CHANGELOG.md
+++ b/trunk/doc/CHANGELOG.md
@@ -7,6 +7,7 @@ The changelog for SRS.
## SRS 7.0 Changelog
+* v7.0, 2025-09-02, Merge [#4466](https://github.com/ossrs/srs/pull/4466): AI: GB28181: Remove embedded SIP server and enforce external SIP usage. v7.0.75 (#4466)
* v7.0, 2025-09-01, Merge [#4465](https://github.com/ossrs/srs/pull/4465): AI: Replace SrsSharedPtrMessage with SrsMediaPacket for unified media packet handling. v7.0.74 (#4465)
* v7.0, 2025-09-01, Merge [#4464](https://github.com/ossrs/srs/pull/4464): AI: Use shared ptr in RTMP message. v7.0.73 (#4464)
* v7.0, 2025-09-01, Merge [#4463](https://github.com/ossrs/srs/pull/4463): AI: Use SrsHttpUri for URL parsing and add legacy RTMP URL conversion. v7.0.72 (#4463)
diff --git a/trunk/src/app/srs_app_config.cpp b/trunk/src/app/srs_app_config.cpp
index 0d35176f9..07abb27ae 100644
--- a/trunk/src/app/srs_app_config.cpp
+++ b/trunk/src/app/srs_app_config.cpp
@@ -3188,121 +3188,6 @@ int SrsConfig::get_stream_caster_listen(SrsConfDirective *conf)
return ::atoi(conf->arg0().c_str());
}
-bool SrsConfig::get_stream_caster_sip_enable(SrsConfDirective *conf)
-{
- static bool DEFAULT = true;
-
- if (!conf) {
- return DEFAULT;
- }
-
- conf = conf->get("sip");
- if (!conf) {
- return DEFAULT;
- }
-
- conf = conf->get("enabled");
- if (!conf || conf->arg0().empty()) {
- return DEFAULT;
- }
-
- return SRS_CONF_PREFER_TRUE(conf->arg0());
-}
-
-int SrsConfig::get_stream_caster_sip_listen(SrsConfDirective *conf)
-{
- static int DEFAULT = 5060;
-
- if (!conf) {
- return DEFAULT;
- }
-
- conf = conf->get("sip");
- if (!conf) {
- return DEFAULT;
- }
-
- conf = conf->get("listen");
- if (!conf || conf->arg0().empty()) {
- return DEFAULT;
- }
-
- return ::atoi(conf->arg0().c_str());
-}
-
-srs_utime_t SrsConfig::get_stream_caster_sip_timeout(SrsConfDirective *conf)
-{
- static srs_utime_t DEFAULT = 60 * SRS_UTIME_SECONDS;
-
- if (!conf) {
- return DEFAULT;
- }
-
- conf = conf->get("sip");
- if (!conf) {
- return DEFAULT;
- }
-
- conf = conf->get("timeout");
- if (!conf || conf->arg0().empty()) {
- return DEFAULT;
- }
-
- return ::atof(conf->arg0().c_str()) * SRS_UTIME_SECONDS;
-}
-
-srs_utime_t SrsConfig::get_stream_caster_sip_reinvite(SrsConfDirective *conf)
-{
- static srs_utime_t DEFAULT = 5 * SRS_UTIME_SECONDS;
-
- if (!conf) {
- return DEFAULT;
- }
-
- conf = conf->get("sip");
- if (!conf) {
- return DEFAULT;
- }
-
- conf = conf->get("reinvite");
- if (!conf || conf->arg0().empty()) {
- return DEFAULT;
- }
-
- return ::atof(conf->arg0().c_str()) * SRS_UTIME_SECONDS;
-}
-
-std::string SrsConfig::get_stream_caster_sip_candidate(SrsConfDirective *conf)
-{
- static string DEFAULT = "*";
-
- if (!conf) {
- return DEFAULT;
- }
-
- conf = conf->get("sip");
- if (!conf) {
- return DEFAULT;
- }
-
- conf = conf->get("candidate");
- if (!conf || conf->arg0().empty()) {
- return DEFAULT;
- }
-
- string eip = srs_getenv(conf->arg0());
- if (!eip.empty()) {
- return eip;
- }
-
- // If configed as ENV, but no ENV set, use default value.
- if (srs_strings_starts_with(conf->arg0(), "$")) {
- return DEFAULT;
- }
-
- return conf->arg0();
-}
-
bool SrsConfig::get_rtsp_server_enabled()
{
SrsConfDirective *conf = root->get("rtsp_server");
diff --git a/trunk/src/app/srs_app_config.hpp b/trunk/src/app/srs_app_config.hpp
index 9d2fc0e17..bf1130fef 100644
--- a/trunk/src/app/srs_app_config.hpp
+++ b/trunk/src/app/srs_app_config.hpp
@@ -484,16 +484,6 @@ public:
virtual std::string get_stream_caster_output(SrsConfDirective *conf);
// Get the listen port of stream caster.
virtual int get_stream_caster_listen(SrsConfDirective *conf);
- // Get the sip.enabled configuration.
- virtual bool get_stream_caster_sip_enable(SrsConfDirective *conf);
- // Get the sip.listen port configuration.
- virtual int get_stream_caster_sip_listen(SrsConfDirective *conf);
- // Get the sip.timeout configuration.
- virtual srs_utime_t get_stream_caster_sip_timeout(SrsConfDirective *conf);
- // Get the sip.reinvite configuration.
- virtual srs_utime_t get_stream_caster_sip_reinvite(SrsConfDirective *conf);
- // Get the candidate for SDP.
- virtual std::string get_stream_caster_sip_candidate(SrsConfDirective *conf);
// rtsp section
public:
virtual bool get_rtsp_server_enabled();
diff --git a/trunk/src/app/srs_app_gb28181.cpp b/trunk/src/app/srs_app_gb28181.cpp
index dda5bed40..46896e239 100644
--- a/trunk/src/app/srs_app_gb28181.cpp
+++ b/trunk/src/app/srs_app_gb28181.cpp
@@ -29,9 +29,6 @@
#include
using namespace std;
-// See https://www.ietf.org/rfc/rfc3261.html#section-8.1.1.7
-#define SRS_GB_BRANCH_MAGIC "z9hG4bK"
-#define SRS_GB_SIP_PORT 5060
#define SRS_GB_MAX_RECOVER 16
#define SRS_GB_MAX_TIMEOUT 3
#define SRS_GB_LARGE_PACKET 1500
@@ -58,34 +55,7 @@ std::string srs_gb_state(SrsGbSessionState ostate, SrsGbSessionState state)
return srs_fmt_sprintf("%s->%s", srs_gb_session_state(ostate).c_str(), srs_gb_session_state(state).c_str());
}
-std::string srs_gb_sip_state(SrsGbSipState state)
-{
- switch (state) {
- case SrsGbSipStateInit:
- return "Init";
- case SrsGbSipStateRegistered:
- return "Registered";
- case SrsGbSipStateInviting:
- return "Inviting";
- case SrsGbSipStateTrying:
- return "Trying";
- case SrsGbSipStateStable:
- return "Stable";
- case SrsGbSipStateReinviting:
- return "Re-inviting";
- case SrsGbSipStateBye:
- return "Bye";
- default:
- return "Invalid";
- }
-}
-
-std::string srs_sip_state(SrsGbSipState ostate, SrsGbSipState state)
-{
- return srs_fmt_sprintf("%s->%s", srs_gb_sip_state(ostate).c_str(), srs_gb_sip_state(state).c_str());
-}
-
-SrsGbSession::SrsGbSession() : sip_(new SrsGbSipTcpConn()), media_(new SrsGbMediaTcpConn())
+SrsGbSession::SrsGbSession() : media_(new SrsGbMediaTcpConn())
{
wrapper_ = NULL;
owner_coroutine_ = NULL;
@@ -95,10 +65,8 @@ SrsGbSession::SrsGbSession() : sip_(new SrsGbSipTcpConn()), media_(new SrsGbMedi
state_ = SrsGbSessionStateInit;
connecting_starttime_ = 0;
- connecting_timeout_ = 0;
nn_timeout_ = 0;
reinviting_starttime_ = 0;
- reinvite_wait_ = 0;
ppp_ = new SrsAlonePithyPrint();
startime_ = srs_time_now_realtime();
@@ -128,18 +96,10 @@ SrsGbSession::~SrsGbSession()
void SrsGbSession::setup(SrsConfDirective *conf)
{
- pip_ = candidate_ = _srs_config->get_stream_caster_sip_candidate(conf);
- if (candidate_ == "*") {
- pip_ = srs_get_public_internet_address(true);
- }
-
std::string output = _srs_config->get_stream_caster_output(conf);
muxer_->setup(output);
- connecting_timeout_ = _srs_config->get_stream_caster_sip_timeout(conf);
- reinvite_wait_ = _srs_config->get_stream_caster_sip_reinvite(conf);
- srs_trace("Session: Start timeout=%dms, reinvite=%dms, candidate=%s, pip=%s, output=%s", srsu2msi(connecting_timeout_),
- srsu2msi(reinvite_wait_), candidate_.c_str(), pip_.c_str(), output.c_str());
+ srs_trace("Session: Start output=%s", output.c_str());
}
void SrsGbSession::setup_owner(SrsSharedResource *wrapper, ISrsInterruptable *owner_coroutine, ISrsContextIdSetter *owner_cid)
@@ -212,18 +172,6 @@ void SrsGbSession::on_ps_pack(SrsPackContext *ctx, SrsPsPacket *ps, const std::v
}
}
-void SrsGbSession::on_sip_transport(SrsSharedResource sip)
-{
- sip_ = sip;
- // Change id of SIP and all its child coroutines.
- sip_->set_cid(cid_);
-}
-
-SrsSharedResource SrsGbSession::sip_transport()
-{
- return sip_;
-}
-
void SrsGbSession::on_media_transport(SrsSharedResource media)
{
media_ = media;
@@ -232,11 +180,6 @@ void SrsGbSession::on_media_transport(SrsSharedResource media
media_->set_cid(cid_);
}
-std::string SrsGbSession::pip()
-{
- return pip_;
-}
-
srs_error_t SrsGbSession::cycle()
{
srs_error_t err = srs_success;
@@ -244,14 +187,13 @@ srs_error_t SrsGbSession::cycle()
// Update all context id to cid of session.
_srs_context->set_id(cid_);
owner_cid_->set_cid(cid_);
- sip_->set_cid(cid_);
+
media_->set_cid(cid_);
// Drive the session cycle.
err = do_cycle();
- // Interrupt the SIP and media transport when session terminated.
- sip_->interrupt();
+ // Interrupt the media transport when session terminated.
media_->interrupt();
// success.
@@ -295,12 +237,7 @@ srs_error_t SrsGbSession::do_cycle()
// Drive the state in a fixed interval.
srs_usleep(SRS_GB_SESSION_DRIVE_INTERVAL);
- // Client send bye, we should dispose the session.
- if (sip_->is_bye()) {
- return err;
- }
-
- // Regular state, driven by state of SIP and transport.
+ // Regular state, driven by state of transport.
if ((err = drive_state()) != srs_success) {
return srs_error_wrap(err, "drive");
}
@@ -323,68 +260,24 @@ srs_error_t SrsGbSession::drive_state()
{
srs_error_t err = srs_success;
-#define SRS_GB_CHANGE_STATE_TO(state) \
- { \
- SrsGbSessionState ostate = set_state(state); \
- srs_trace("Session: Change device=%s, state=%s", sip_->device_id().c_str(), \
- srs_gb_state(ostate, state_).c_str()); \
+#define SRS_GB_CHANGE_STATE_TO(state) \
+ { \
+ SrsGbSessionState ostate = set_state(state); \
+ srs_trace("Session: Change device=%s, state=%s", device_id_.c_str(), \
+ srs_gb_state(ostate, state_).c_str()); \
}
if (state_ == SrsGbSessionStateInit) {
- // Set to connecting, whatever media is connected or not, because the connecting state will handle it if media
- // is connected, so we don't need to handle it here.
- if (sip_->is_registered()) {
- SRS_GB_CHANGE_STATE_TO(SrsGbSessionStateConnecting);
- connecting_starttime_ = srs_time_now_realtime();
- }
-
- // Invite if media is not connected.
- if (sip_->is_registered() && !media_->is_connected()) {
- uint32_t ssrc = 0;
- if ((err = sip_->invite_request(&ssrc)) != srs_success) {
- return srs_error_wrap(err, "invite");
- }
-
- // Now, we're able to query session by ssrc, for media packets.
- _srs_gb_manager->add_with_fast_id(ssrc, wrapper_);
- }
- }
-
- if (state_ == SrsGbSessionStateConnecting) {
- if (srs_time_now_realtime() - connecting_starttime_ >= connecting_timeout_) {
- if ((nn_timeout_++) > SRS_GB_MAX_TIMEOUT) {
- return srs_error_new(ERROR_GB_TIMEOUT, "timeout");
- }
-
- srs_trace("Session: Connecting timeout, nn=%d, state=%s, sip=%s, media=%d", nn_timeout_, srs_gb_session_state(state_).c_str(),
- srs_gb_sip_state(sip_->state()).c_str(), media_->is_connected());
- sip_->reset_to_register();
- SRS_GB_CHANGE_STATE_TO(SrsGbSessionStateInit);
- }
-
- if (sip_->is_stable() && media_->is_connected()) {
+ // With external SIP server, we assume media connection is handled externally
+ if (media_->is_connected()) {
SRS_GB_CHANGE_STATE_TO(SrsGbSessionStateEstablished);
}
}
if (state_ == SrsGbSessionStateEstablished) {
- if (sip_->is_bye()) {
- srs_trace("Session: Dispose for client bye");
- return err;
- }
-
- // When media disconnected, we wait for a while then reinvite.
+ // Simple state management - just check if media is still connected
if (!media_->is_connected()) {
- if (!reinviting_starttime_) {
- reinviting_starttime_ = srs_time_now_realtime();
- }
- if (srs_time_now_cached() - reinviting_starttime_ > reinvite_wait_) {
- reinviting_starttime_ = 0;
- srs_trace("Session: Re-invite for disconnect, state=%s, sip=%s, media=%d", srs_gb_session_state(state_).c_str(),
- srs_gb_sip_state(sip_->state()).c_str(), media_->is_connected());
- sip_->reset_to_register();
- SRS_GB_CHANGE_STATE_TO(SrsGbSessionStateInit);
- }
+ SRS_GB_CHANGE_STATE_TO(SrsGbSessionStateInit);
}
}
@@ -411,14 +304,12 @@ std::string SrsGbSession::desc()
SrsGbListener::SrsGbListener()
{
conf_ = NULL;
- sip_listener_ = new SrsTcpListener(this);
media_listener_ = new SrsTcpListener(this);
}
SrsGbListener::~SrsGbListener()
{
srs_freep(conf_);
- srs_freep(sip_listener_);
srs_freep(media_listener_);
}
@@ -435,14 +326,6 @@ srs_error_t SrsGbListener::initialize(SrsConfDirective *conf)
media_listener_->set_endpoint(ip, port)->set_label("GB-TCP");
}
- bool sip_enabled = _srs_config->get_stream_caster_sip_enable(conf);
- if (!sip_enabled) {
- srs_warn("GB SIP is disabled.");
- } else {
- int port = _srs_config->get_stream_caster_sip_listen(conf);
- sip_listener_->set_endpoint(ip, port)->set_label("SIP-TCP");
- }
-
return err;
}
@@ -454,10 +337,6 @@ srs_error_t SrsGbListener::listen()
return srs_error_wrap(err, "listen");
}
- if ((err = sip_listener_->listen()) != srs_success) {
- return srs_error_wrap(err, "listen");
- }
-
if ((err = listen_api()) != srs_success) {
return srs_error_wrap(err, "listen api");
}
@@ -486,21 +365,7 @@ srs_error_t SrsGbListener::on_tcp_client(ISrsListener *listener, srs_netfd_t stf
srs_error_t err = srs_success;
// Handle TCP connections.
- if (listener == sip_listener_) {
- SrsGbSipTcpConn *raw_conn = new SrsGbSipTcpConn();
- raw_conn->setup(conf_, sip_listener_, media_listener_, stfd);
-
- SrsSharedResource *conn = new SrsSharedResource(raw_conn);
- _srs_gb_manager->add(conn, NULL);
-
- SrsExecutorCoroutine *executor = new SrsExecutorCoroutine(_srs_gb_manager, conn, raw_conn, raw_conn);
- raw_conn->setup_owner(conn, executor, executor);
-
- if ((err = executor->start()) != srs_success) {
- srs_freep(executor);
- return srs_error_wrap(err, "gb sip");
- }
- } else if (listener == media_listener_) {
+ if (listener == media_listener_) {
SrsGbMediaTcpConn *raw_conn = new SrsGbMediaTcpConn();
raw_conn->setup(stfd);
@@ -522,760 +387,6 @@ srs_error_t SrsGbListener::on_tcp_client(ISrsListener *listener, srs_netfd_t stf
return err;
}
-SrsGbSipTcpConn::SrsGbSipTcpConn()
-{
- wrapper_ = NULL;
- owner_coroutine_ = NULL;
- owner_cid_ = NULL;
- cid_ = _srs_context->get_id();
-
- session_ = NULL;
- state_ = SrsGbSipStateInit;
- register_ = new SrsSipMessage();
- invite_ok_ = new SrsSipMessage();
- ssrc_v_ = 0;
-
- conf_ = NULL;
- sip_listener_ = NULL;
- media_listener_ = NULL;
- conn_ = NULL;
- receiver_ = NULL;
- sender_ = NULL;
-}
-
-SrsGbSipTcpConn::~SrsGbSipTcpConn()
-{
- srs_freep(receiver_);
- srs_freep(sender_);
- srs_freep(conn_);
- srs_freep(register_);
- srs_freep(invite_ok_);
- srs_freep(conf_);
-}
-
-void SrsGbSipTcpConn::setup(SrsConfDirective *conf, SrsTcpListener *sip, SrsTcpListener *media, srs_netfd_t stfd)
-{
- srs_freep(conf_);
- conf_ = conf->copy();
-
- sip_listener_ = sip;
- media_listener_ = media;
- conn_ = new SrsTcpConnection(stfd);
- receiver_ = new SrsGbSipTcpReceiver(this, conn_);
- sender_ = new SrsGbSipTcpSender(conn_);
-}
-
-void SrsGbSipTcpConn::setup_owner(SrsSharedResource *wrapper, ISrsInterruptable *owner_coroutine, ISrsContextIdSetter *owner_cid)
-{
- wrapper_ = wrapper;
- owner_coroutine_ = owner_coroutine;
- owner_cid_ = owner_cid;
-}
-
-void SrsGbSipTcpConn::on_executor_done(ISrsInterruptable *executor)
-{
- owner_coroutine_ = NULL;
-}
-
-std::string SrsGbSipTcpConn::device_id()
-{
- return register_->device_id();
-}
-
-void SrsGbSipTcpConn::set_device_id(const std::string &id)
-{
- register_->from_address_user_ = id;
-}
-
-void SrsGbSipTcpConn::set_cid(const SrsContextId &cid)
-{
- if (owner_cid_)
- owner_cid_->set_cid(cid);
- if (receiver_)
- receiver_->set_cid(cid);
- if (sender_)
- sender_->set_cid(cid);
- cid_ = cid;
-}
-
-void SrsGbSipTcpConn::query_ports(int *sip, int *media)
-{
- if (sip)
- *sip = sip_listener_->port();
- if (media)
- *media = media_listener_->port();
-}
-
-srs_error_t SrsGbSipTcpConn::on_sip_message(SrsSipMessage *msg)
-{
- srs_error_t err = srs_success;
-
- // Finger out the GB session to handle SIP messages.
- if (!session_ && (err = bind_session(msg, &session_)) != srs_success) {
- return srs_error_wrap(err, "bind session");
- }
-
- // Ignore if session not found.
- if (!session_) {
- srs_warn("SIP: No session, drop message type=%d, id=%s, body=%s", msg->type_,
- msg->device_id().c_str(), msg->body_escaped_.c_str());
- return err;
- }
-
- // For state to use device id from register message.
- if (msg->is_register()) {
- srs_freep(register_);
- register_ = msg->copy(); // Cache the register request message.
- }
-
- // Drive state machine of SIP connection.
- drive_state(msg);
-
- // Notify session about the SIP message.
- if (msg->is_register()) {
- register_response(msg); // Response for REGISTER.
- } else if (msg->is_message()) {
- // Response for MESSAGE, the heartbeat message.
- // Set 403 to require client register, see https://www.ietf.org/rfc/rfc3261.html#section-21.4
- // Please note that it does not work for GB device, which just ignore 4xx packets like no response.
- message_response(msg, (state_ == SrsGbSipStateInit ? HTTP_STATUS_FORBIDDEN : HTTP_STATUS_OK));
- } else if (msg->is_invite_ok()) {
- srs_freep(invite_ok_);
- invite_ok_ = msg->copy(); // Cache the invite ok message.
- invite_ack(msg); // Response for INVITE OK.
- } else if (msg->is_bye()) {
- bye_response(msg); // Response for Bye OK.
- } else if (msg->is_trying() || msg->is_bye_ok()) {
- // Ignore SIP message 100(Trying).
- // Ignore BYE ok.
- } else {
- srs_warn("SIP: Ignore message type=%d, status=%d, method=%d, body=%s", msg->type_,
- msg->status_, msg->method_, msg->body_escaped_.c_str());
- }
-
- return err;
-}
-
-void SrsGbSipTcpConn::enqueue_sip_message(SrsSipMessage *msg)
-{
- // Drive state machine when enqueue message.
- drive_state(msg);
-
- // TODO: Support SIP transaction and wait for response for request?
- sender_->enqueue(msg);
-}
-
-void SrsGbSipTcpConn::drive_state(SrsSipMessage *msg)
-{
- srs_error_t err = srs_success;
-
-#define SRS_GB_SIP_CHANGE_STATE_TO(state) \
- { \
- SrsGbSipState ostate = set_state(state); \
- srs_trace("SIP: Change device=%s, state=%s", register_->device_id().c_str(), \
- srs_sip_state(ostate, state_).c_str()); \
- }
-
- // const char* mt = msg->type_ == HTTP_REQUEST ? "REQUEST" : "RESPONSE";
- // const char* mm = msg->type_ == HTTP_REQUEST ? http_method_str(msg->method_) : "Response";
- // int ms = msg->type_ == HTTP_REQUEST ? 200 : msg->status_;
- // srs_trace("SIP: Got message type=%s, method=%s, status=%d, expire=%d", mt, mm, ms, msg->expires_);
-
- if (state_ == SrsGbSipStateInit) {
- // The register message, we will invite it automatically.
- if (msg->is_register() && msg->expires_ > 0)
- SRS_GB_SIP_CHANGE_STATE_TO(SrsGbSipStateRegistered);
- // Client bye or unregister, we should destroy the session because it might never publish again.
- if (msg->is_register() && msg->expires_ == 0)
- SRS_GB_SIP_CHANGE_STATE_TO(SrsGbSipStateBye);
- // When got heartbeat message, we restore to stable state.
- if (msg->is_message())
- SRS_GB_SIP_CHANGE_STATE_TO(SrsGbSipStateStable);
- }
-
- if (state_ == SrsGbSipStateRegistered) {
- if (msg->is_invite())
- SRS_GB_SIP_CHANGE_STATE_TO(SrsGbSipStateInviting);
- }
-
- if (state_ == SrsGbSipStateInviting) {
- if (msg->is_trying())
- SRS_GB_SIP_CHANGE_STATE_TO(SrsGbSipStateTrying);
- if (msg->is_invite_ok())
- SRS_GB_SIP_CHANGE_STATE_TO(SrsGbSipStateStable);
-
- // If device got invite request and disconnect, it might register again, we should re-invite.
- if (msg->is_register()) {
- srs_warn("SIP: Re-invite for got REGISTER in state=%s", srs_gb_sip_state(state_).c_str());
- if ((err = invite_request(NULL)) != srs_success) {
- // TODO: FIXME: Should fail the SIP session.
- srs_freep(err);
- }
- }
- }
-
- if (state_ == SrsGbSipStateTrying) {
- if (msg->is_invite_ok())
- SRS_GB_SIP_CHANGE_STATE_TO(SrsGbSipStateStable);
- }
-
- if (state_ == SrsGbSipStateStable) {
- // Client bye or unregister, we should destroy the session because it might never publish again.
- if (msg->is_register() && msg->expires_ == 0)
- SRS_GB_SIP_CHANGE_STATE_TO(SrsGbSipStateBye);
- if (msg->is_bye())
- SRS_GB_SIP_CHANGE_STATE_TO(SrsGbSipStateBye);
- }
-
- if (state_ == SrsGbSipStateReinviting) {
- if (msg->is_bye_ok())
- SRS_GB_SIP_CHANGE_STATE_TO(SrsGbSipStateInviting);
- }
-}
-
-void SrsGbSipTcpConn::register_response(SrsSipMessage *msg)
-{
- SrsSipMessage *res = new SrsSipMessage();
-
- res->type_ = HTTP_RESPONSE;
- res->status_ = HTTP_STATUS_OK;
- res->via_ = msg->via_;
- res->from_ = msg->from_;
- res->to_ = msg->to_;
- res->cseq_ = msg->cseq_;
- res->call_id_ = msg->call_id_;
- res->contact_ = msg->contact_;
- res->expires_ = msg->expires_;
-
- enqueue_sip_message(res);
-}
-
-void SrsGbSipTcpConn::message_response(SrsSipMessage *msg, http_status status)
-{
- SrsSipMessage *res = new SrsSipMessage();
-
- res->type_ = HTTP_RESPONSE;
- res->status_ = status;
- res->via_ = msg->via_;
- res->from_ = msg->from_;
- res->to_ = msg->to_;
- res->cseq_ = msg->cseq_;
- res->call_id_ = msg->call_id_;
-
- enqueue_sip_message(res);
-}
-
-void SrsGbSipTcpConn::invite_ack(SrsSipMessage *msg)
-{
- string pip = session_->pip(); // Parse from CANDIDATE
- int sip_port;
- query_ports(&sip_port, NULL);
- string gb_device_id = srs_fmt_sprintf("sip:%s@%s", msg->to_address_user_.c_str(), msg->to_address_host_.c_str());
- string branch = srs_rand_gen_str(6);
-
- SrsSipMessage *req = new SrsSipMessage();
- req->type_ = HTTP_REQUEST;
- req->method_ = HTTP_ACK;
- req->request_uri_ = gb_device_id;
- req->via_ = srs_fmt_sprintf("SIP/2.0/TCP %s:%d;rport;branch=%s%s", pip.c_str(), sip_port, SRS_GB_BRANCH_MAGIC, branch.c_str());
- req->from_ = msg->from_;
- req->to_ = msg->to_;
- req->cseq_ = srs_fmt_sprintf("%d ACK", msg->cseq_number_);
- req->call_id_ = msg->call_id_;
- req->max_forwards_ = 70;
-
- enqueue_sip_message(req);
-}
-
-void SrsGbSipTcpConn::bye_response(SrsSipMessage *msg)
-{
- SrsSipMessage *res = new SrsSipMessage();
-
- res->type_ = HTTP_RESPONSE;
- res->status_ = HTTP_STATUS_OK;
- res->via_ = msg->via_;
- res->from_ = msg->from_;
- res->to_ = msg->to_;
- res->cseq_ = msg->cseq_;
- res->call_id_ = msg->call_id_;
-
- enqueue_sip_message(res);
-}
-
-srs_error_t SrsGbSipTcpConn::invite_request(uint32_t *pssrc)
-{
- srs_error_t err = srs_success;
-
- srs_assert(register_);
-
- if (true) {
- // Generate SSRC, detect conflict.
- string ssrc = ssrc_str_;
- for (int i = 0; ssrc.empty() && i < 16; i++) {
- int flag = 0; // 0 is realtime.
- string ssrc_str = srs_fmt_sprintf("%d%s%04d", flag, register_->ssrc_domain_id().c_str(), srs_rand_integer() % 10000);
- uint32_t ssrc_v = (uint32_t)::atol(ssrc_str.c_str());
- if (!_srs_gb_manager->find_by_fast_id(ssrc_v)) {
- ssrc = ssrc_str;
- break;
- }
- }
- if (ssrc.empty()) {
- return srs_error_new(ERROR_GB_SSRC_GENERATE, "Generate SSRC failed");
- }
-
- // Update and cache the SSRC for re-invite.
- ssrc_str_ = ssrc;
- ssrc_v_ = (uint32_t)::atol(ssrc_str_.c_str());
- if (pssrc)
- *pssrc = ssrc_v_;
- }
-
- string pip = session_->pip(); // Parse from CANDIDATE
- int sip_port, media_port;
- query_ports(&sip_port, &media_port);
- string srs_device_id = srs_fmt_sprintf("sip:%s@%s", register_->request_uri_user_.c_str(), register_->request_uri_host_.c_str());
- string gb_device_id = srs_fmt_sprintf("sip:%s@%s", register_->from_address_user_.c_str(), register_->from_address_host_.c_str());
- string subject = srs_fmt_sprintf("%s:%s,%s:0", register_->from_address_user_.c_str(), ssrc_str_.c_str(), register_->request_uri_user_.c_str());
- string branch = srs_rand_gen_str(6);
- string tag = srs_rand_gen_str(8);
- string call_id = srs_rand_gen_str(16);
- int cseq = (int)(srs_rand_integer() % 1000); // TODO: FIXME: Increase.
-
- SrsSdp local_sdp;
- local_sdp.version_ = "0";
- local_sdp.username_ = register_->contact_user_;
- local_sdp.session_id_ = "0";
- local_sdp.session_version_ = "0";
- local_sdp.nettype_ = "IN";
- local_sdp.addrtype_ = "IP4";
- local_sdp.unicast_address_ = pip; // Parse from CANDIDATE
- local_sdp.session_name_ = "Play";
- local_sdp.start_time_ = 0;
- local_sdp.end_time_ = 0;
- local_sdp.ice_lite_ = ""; // Disable this line.
- local_sdp.connection_ = srs_fmt_sprintf("c=IN IP4 %s", pip.c_str()); // Session level connection.
-
- local_sdp.media_descs_.push_back(SrsMediaDesc("video"));
- SrsMediaDesc &media = local_sdp.media_descs_.at(0);
- media.port_ = media_port; // Read from config.
- media.protos_ = "TCP/RTP/AVP";
- media.connection_ = ""; // Disable media level connection.
- media.recvonly_ = true;
-
- media.payload_types_.push_back(SrsMediaPayloadType(96));
- SrsMediaPayloadType &ps = media.payload_types_.at(0);
- ps.encoding_name_ = "PS";
- ps.clock_rate_ = 90000;
-
- media.ssrc_infos_.push_back(SrsSSRCInfo());
- SrsSSRCInfo &ssrc_info = media.ssrc_infos_.at(0);
- ssrc_info.cname_ = ssrc_str_;
- ssrc_info.ssrc_ = ssrc_v_;
- ssrc_info.label_ = "gb28181";
-
- ostringstream ss;
- if ((err = local_sdp.encode(ss)) != srs_success) {
- return srs_error_wrap(err, "encode sdp");
- }
-
- SrsSipMessage *req = new SrsSipMessage();
- req->type_ = HTTP_REQUEST;
- req->method_ = HTTP_INVITE;
- req->request_uri_ = gb_device_id;
- req->via_ = srs_fmt_sprintf("SIP/2.0/TCP %s:%d;rport;branch=%s%s", pip.c_str(), sip_port, SRS_GB_BRANCH_MAGIC, branch.c_str());
- req->from_ = srs_fmt_sprintf("<%s>;tag=SRS%s", srs_device_id.c_str(), tag.c_str());
- req->to_ = srs_fmt_sprintf("<%s>", gb_device_id.c_str());
- req->cseq_ = srs_fmt_sprintf("%d INVITE", cseq);
- req->call_id_ = call_id;
- req->content_type_ = "Application/SDP";
- req->contact_ = srs_fmt_sprintf("<%s>", srs_device_id.c_str());
- req->max_forwards_ = 70;
- req->subject_ = subject;
- req->set_body(ss.str());
-
- enqueue_sip_message(req);
- srs_trace("SIP: INVITE device=%s, branch=%s, tag=%s, call=%s, ssrc=%s, sdp is %s", gb_device_id.c_str(), branch.c_str(),
- tag.c_str(), call_id.c_str(), ssrc_str_.c_str(), req->body_escaped_.c_str());
-
- return err;
-}
-
-void SrsGbSipTcpConn::interrupt()
-{
- receiver_->interrupt();
- sender_->interrupt();
- if (owner_coroutine_)
- owner_coroutine_->interrupt();
-}
-
-SrsGbSipState SrsGbSipTcpConn::state()
-{
- return state_;
-}
-
-void SrsGbSipTcpConn::reset_to_register()
-{
- state_ = SrsGbSipStateRegistered;
-}
-
-bool SrsGbSipTcpConn::is_registered()
-{
- return state_ >= SrsGbSipStateRegistered && state_ <= SrsGbSipStateStable;
-}
-
-bool SrsGbSipTcpConn::is_stable()
-{
- return state_ == SrsGbSipStateStable;
-}
-
-bool SrsGbSipTcpConn::is_bye()
-{
- return state_ == SrsGbSipStateBye;
-}
-
-SrsGbSipState SrsGbSipTcpConn::set_state(SrsGbSipState v)
-{
- SrsGbSipState state = state_;
- state_ = v;
- return state;
-}
-
-const SrsContextId &SrsGbSipTcpConn::get_id()
-{
- return cid_;
-}
-
-std::string SrsGbSipTcpConn::desc()
-{
- return "GB-SIP-TCP";
-}
-
-srs_error_t SrsGbSipTcpConn::cycle()
-{
- srs_error_t err = srs_success;
-
- if ((err = receiver_->start()) != srs_success) {
- return srs_error_wrap(err, "receiver");
- }
-
- if ((err = sender_->start()) != srs_success) {
- return srs_error_wrap(err, "sender");
- }
-
- // Wait for the SIP connection to be terminated.
- err = do_cycle();
-
- // Interrupt the receiver and sender coroutine.
- receiver_->interrupt();
- sender_->interrupt();
-
- // success.
- if (err == srs_success) {
- srs_trace("client finished.");
- return err;
- }
-
- // It maybe success with message.
- if (srs_error_code(err) == ERROR_SUCCESS) {
- srs_trace("client finished%s.", srs_error_summary(err).c_str());
- srs_freep(err);
- return err;
- }
-
- // client close peer.
- // TODO: FIXME: Only reset the error when client closed it.
- if (srs_is_client_gracefully_close(err)) {
- srs_warn("client disconnect peer. ret=%d", srs_error_code(err));
- } else if (srs_is_server_gracefully_close(err)) {
- srs_warn("server disconnect. ret=%d", srs_error_code(err));
- } else {
- srs_error("serve error %s", srs_error_desc(err).c_str());
- }
-
- srs_freep(err);
- return srs_success;
-}
-
-srs_error_t SrsGbSipTcpConn::do_cycle()
-{
- srs_error_t err = srs_success;
-
- while (true) {
- if (!owner_coroutine_)
- return err;
- if ((err = owner_coroutine_->pull()) != srs_success) {
- return srs_error_wrap(err, "pull");
- }
-
- srs_usleep(SRS_UTIME_NO_TIMEOUT);
- }
-
- return err;
-}
-
-srs_error_t SrsGbSipTcpConn::bind_session(SrsSipMessage *msg, SrsGbSession **psession)
-{
- srs_error_t err = srs_success;
-
- string device = msg->device_id();
- if (device.empty())
- return err;
-
- // Only create session for REGISTER request.
- if (msg->type_ != HTTP_REQUEST || msg->method_ != HTTP_REGISTER)
- return err;
-
- // Find exists session for register, might be created by another object and still alive.
- SrsSharedResource *session = dynamic_cast *>(_srs_gb_manager->find_by_id(device));
- SrsGbSession *raw_session = session ? (*session).get() : NULL;
- if (!session) {
- // Create new GB session.
- raw_session = new SrsGbSession();
- raw_session->setup(conf_);
-
- session = new SrsSharedResource(raw_session);
- _srs_gb_manager->add_with_id(device, session);
-
- SrsExecutorCoroutine *executor = new SrsExecutorCoroutine(_srs_gb_manager, session, raw_session, raw_session);
- raw_session->setup_owner(session, executor, executor);
-
- if ((err = executor->start()) != srs_success) {
- srs_freep(executor);
- return srs_error_wrap(err, "gb session");
- }
- }
-
- // Try to load state from previous SIP connection.
- SrsSharedResource pre = raw_session->sip_transport();
- if (pre.get() && pre.get() != this) {
- state_ = pre->state_;
- ssrc_str_ = pre->ssrc_str_;
- ssrc_v_ = pre->ssrc_v_;
- srs_freep(register_);
- register_ = pre->register_->copy();
- srs_freep(invite_ok_);
- invite_ok_ = pre->invite_ok_->copy();
- }
-
- // Notice session to use current SIP connection.
- raw_session->on_sip_transport(*wrapper_);
- *psession = raw_session;
-
- return err;
-}
-
-SrsGbSipTcpReceiver::SrsGbSipTcpReceiver(SrsGbSipTcpConn *sip, SrsTcpConnection *conn)
-{
- sip_ = sip;
- conn_ = conn;
- trd_ = new SrsSTCoroutine("sip-receiver", this);
-}
-
-SrsGbSipTcpReceiver::~SrsGbSipTcpReceiver()
-{
- srs_freep(trd_);
-}
-
-void SrsGbSipTcpReceiver::interrupt()
-{
- trd_->interrupt();
-}
-
-void SrsGbSipTcpReceiver::set_cid(const SrsContextId &cid)
-{
- trd_->set_cid(cid);
-}
-
-srs_error_t SrsGbSipTcpReceiver::start()
-{
- srs_error_t err = srs_success;
-
- if ((err = trd_->start()) != srs_success) {
- return srs_error_wrap(err, "coroutine");
- }
-
- return err;
-}
-
-srs_error_t SrsGbSipTcpReceiver::cycle()
-{
- srs_error_t err = do_cycle();
-
- // TODO: FIXME: Notify SIP transport to cleanup.
- if (err != srs_success) {
- srs_error("SIP: Receive err %s", srs_error_desc(err).c_str());
- }
-
- return err;
-}
-
-srs_error_t SrsGbSipTcpReceiver::do_cycle()
-{
- srs_error_t err = srs_success;
-
- SrsUniquePtr parser(new SrsHttpParser());
-
- // We might get SIP request or response message.
- if ((err = parser->initialize(HTTP_BOTH)) != srs_success) {
- return srs_error_wrap(err, "init parser");
- }
-
- while (true) {
- if ((err = trd_->pull()) != srs_success) {
- return srs_error_wrap(err, "pull");
- }
-
- // Use HTTP parser to parse SIP messages.
- ISrsHttpMessage *hmsg_raw = NULL;
- if ((err = parser->parse_message(conn_, &hmsg_raw)) != srs_success) {
- return srs_error_wrap(err, "parse message");
- }
- SrsUniquePtr hmsg(hmsg_raw);
-
- SrsSipMessage smsg;
- if ((err = smsg.parse(hmsg.get())) != srs_success) {
- srs_warn("SIP: Drop msg type=%d, method=%d, err is %s", hmsg->message_type(), hmsg->method(), srs_error_summary(err).c_str());
- srs_freep(err);
- continue;
- }
-
- if ((err = sip_->on_sip_message(&smsg)) != srs_success) {
- srs_warn("SIP: Ignore on msg err %s", srs_error_desc(err).c_str());
- srs_freep(err);
- continue;
- }
- }
-
- return err;
-}
-
-SrsGbSipTcpSender::SrsGbSipTcpSender(SrsTcpConnection *conn)
-{
- conn_ = conn;
- wait_ = srs_cond_new();
- trd_ = new SrsSTCoroutine("sip-sender", this);
-}
-
-SrsGbSipTcpSender::~SrsGbSipTcpSender()
-{
- srs_freep(trd_);
- srs_cond_destroy(wait_);
-
- for (vector::iterator it = msgs_.begin(); it != msgs_.end(); ++it) {
- SrsSipMessage *msg = *it;
- srs_freep(msg);
- }
-}
-
-void SrsGbSipTcpSender::enqueue(SrsSipMessage *msg)
-{
- msgs_.push_back(msg);
- srs_cond_signal(wait_);
-}
-
-void SrsGbSipTcpSender::interrupt()
-{
- trd_->interrupt();
-}
-
-void SrsGbSipTcpSender::set_cid(const SrsContextId &cid)
-{
- trd_->set_cid(cid);
-}
-
-srs_error_t SrsGbSipTcpSender::start()
-{
- srs_error_t err = srs_success;
-
- if ((err = trd_->start()) != srs_success) {
- return srs_error_wrap(err, "coroutine");
- }
-
- return err;
-}
-
-srs_error_t SrsGbSipTcpSender::cycle()
-{
- srs_error_t err = do_cycle();
-
- // TODO: FIXME: Notify SIP transport to cleanup.
- if (err != srs_success) {
- srs_error("SIP: Send err %s", srs_error_desc(err).c_str());
- }
-
- return err;
-}
-
-srs_error_t SrsGbSipTcpSender::do_cycle()
-{
- srs_error_t err = srs_success;
-
- while (true) {
- if (msgs_.empty()) {
- srs_cond_wait(wait_);
- }
-
- if ((err = trd_->pull()) != srs_success) {
- return srs_error_wrap(err, "pull");
- }
-
- SrsUniquePtr msg(msgs_.front());
- msgs_.erase(msgs_.begin());
-
- if (msg->type_ == HTTP_RESPONSE) {
- SrsSipResponseWriter res(conn_);
- res.header()->set("Via", msg->via_);
- res.header()->set("From", msg->from_);
- res.header()->set("To", msg->to_);
- res.header()->set("CSeq", msg->cseq_);
- res.header()->set("Call-ID", msg->call_id_);
- res.header()->set("User-Agent", RTMP_SIG_SRS_SERVER);
- if (!msg->contact_.empty())
- res.header()->set("Contact", msg->contact_);
- if (msg->expires_ != UINT32_MAX)
- res.header()->set("Expires", srs_strconv_format_int(msg->expires_));
-
- res.header()->set_content_length(msg->body_.length());
- res.write_header(msg->status_);
- if (!msg->body_.empty())
- res.write((char *)msg->body_.c_str(), msg->body_.length());
- if ((err = res.final_request()) != srs_success) {
- return srs_error_wrap(err, "response");
- }
- } else if (msg->type_ == HTTP_REQUEST) {
- SrsSipRequestWriter req(conn_);
- req.header()->set("Via", msg->via_);
- req.header()->set("From", msg->from_);
- req.header()->set("To", msg->to_);
- req.header()->set("CSeq", msg->cseq_);
- req.header()->set("Call-ID", msg->call_id_);
- req.header()->set("User-Agent", RTMP_SIG_SRS_SERVER);
- if (!msg->contact_.empty())
- req.header()->set("Contact", msg->contact_);
- if (!msg->subject_.empty())
- req.header()->set("Subject", msg->subject_);
- if (msg->max_forwards_)
- req.header()->set("Max-Forwards", srs_strconv_format_int(msg->max_forwards_));
-
- if (!msg->content_type_.empty())
- req.header()->set_content_type(msg->content_type_);
- req.header()->set_content_length(msg->body_.length());
- req.write_header(http_method_str(msg->method_), msg->request_uri_);
- if (!msg->body_.empty())
- req.write((char *)msg->body_.c_str(), msg->body_.length());
- if ((err = req.final_request()) != srs_success) {
- return srs_error_wrap(err, "request");
- }
- } else {
- srs_warn("SIP: Sender drop message type=%d, method=%s, body=%dB", msg->type_,
- http_method_str(msg->method_), msg->body_.length());
- }
- }
-
- return err;
-}
-
ISrsPsPackHandler::ISrsPsPackHandler()
{
}
@@ -2156,7 +1267,7 @@ srs_error_t SrsGbMuxer::connect()
// Cleanup the data before connect again.
close();
- string url = srs_strings_replace(output_, "[stream]", session_->sip_transport()->device_id());
+ string url = srs_strings_replace(output_, "[stream]", session_->device_id_);
srs_trace("Muxer: Convert GB to RTMP %s", url.c_str());
srs_utime_t cto = SRS_CONSTS_RTMP_TIMEOUT;
@@ -2189,318 +1300,6 @@ void SrsGbMuxer::close()
h264_pps_ = "";
}
-SrsSipResponseWriter::SrsSipResponseWriter(ISrsProtocolReadWriter *io) : SrsHttpResponseWriter(io)
-{
-}
-
-SrsSipResponseWriter::~SrsSipResponseWriter()
-{
-}
-
-srs_error_t SrsSipResponseWriter::build_first_line(std::stringstream &ss, char *data, int size)
-{
- // Write status line for response.
- ss << "SIP/2.0 " << status << " " << srs_generate_http_status_text(status) << SRS_HTTP_CRLF;
- return srs_success;
-}
-
-SrsSipRequestWriter::SrsSipRequestWriter(ISrsProtocolReadWriter *io) : SrsHttpRequestWriter(io)
-{
-}
-
-SrsSipRequestWriter::~SrsSipRequestWriter()
-{
-}
-
-srs_error_t SrsSipRequestWriter::build_first_line(std::stringstream &ss, char *data, int size)
-{
- // Write status line for response.
- ss << method_ << " " << path_ << " SIP/2.0" << SRS_HTTP_CRLF;
- return srs_success;
-}
-
-SrsSipMessage::SrsSipMessage()
-{
- method_ = HTTP_GET;
- cseq_number_ = 0;
- expires_ = UINT32_MAX; // Never use 0 because it means unregister.
- max_forwards_ = 0;
- via_send_by_port_ = SRS_GB_SIP_PORT;
- contact_host_port_ = SRS_GB_SIP_PORT;
-}
-
-SrsSipMessage::~SrsSipMessage()
-{
-}
-
-SrsSipMessage *SrsSipMessage::copy()
-{
- SrsSipMessage *cp = new SrsSipMessage();
- *cp = *this;
- return cp;
-}
-
-const std::string &SrsSipMessage::device_id()
-{
- // If request is sent by device, then the "from" address must be the ID of device. While we use id to identify the
- // requests of device, so we can use the "from" address.
- return from_address_user_;
-}
-
-std::string SrsSipMessage::ssrc_domain_id()
-{
- // The request uri user is GB domain, the 4-8 is used as domain id for SSRC, so the length must be 8+ bytes,
- // see https://openstd.samr.gov.cn/bzgk/gb/newGbInfo?hcno=469659DC56B9B8187671FF08748CEC89
- return (request_uri_user_.length() < 8) ? "00000" : request_uri_user_.substr(3, 5);
-}
-
-SrsSipMessage *SrsSipMessage::set_body(std::string v)
-{
- body_ = v;
- body_escaped_ = v;
- body_escaped_ = srs_strings_replace(body_escaped_, "\r", "\\r");
- body_escaped_ = srs_strings_replace(body_escaped_, "\n", "\\n");
- return this;
-}
-
-srs_error_t SrsSipMessage::parse(ISrsHttpMessage *m)
-{
- srs_error_t err = srs_success;
-
- // Parse body if exists any. Note that we must read body even the message is invalid, because we might need to parse
- // the next message when skip current invalid message.
- string v;
- ISrsHttpResponseReader *br = m->body_reader();
- if (!br->eof() && (err = srs_io_readall(br, v)) != srs_success) {
- return srs_error_wrap(err, "read body");
- }
-
- set_body(v);
-
- // Parse the first line.
- type_ = (http_parser_type)m->message_type();
- if (type_ == HTTP_REQUEST) {
- // Parse request line.
- method_ = (http_method)m->method();
- request_uri_ = srs_strings_trim_start(m->path(), "/");
- srs_sip_parse_address(request_uri_, request_uri_user_, request_uri_host_);
- } else if (type_ == HTTP_RESPONSE) {
- // Parse status line for response.
- status_ = (http_status)m->status_code();
- } else {
- return srs_error_new(ERROR_GB_SIP_HEADER, "Invalid message type=%d", type_);
- }
-
- // Check fields for SIP request.
- if (type_ == HTTP_REQUEST) {
- if (method_ < HTTP_REGISTER || method_ > HTTP_BYE) {
- return srs_error_new(ERROR_GB_SIP_MESSAGE, "Invalid method=%d(%s) of message", method_, http_method_str(method_));
- }
- if (request_uri_.empty())
- return srs_error_new(ERROR_GB_SIP_MESSAGE, "No Request-URI in message");
- }
-
- // Get fields of SIP.
- via_ = m->header()->get("Via");
- from_ = m->header()->get("From");
- to_ = m->header()->get("To");
- call_id_ = m->header()->get("Call-ID");
- cseq_ = m->header()->get("CSeq");
- contact_ = m->header()->get("Contact");
- subject_ = m->header()->get("Subject");
- content_type_ = m->header()->content_type();
-
- string expires = m->header()->get("Expires");
- if (!expires.empty()) {
- expires_ = (uint32_t)::atol(expires.c_str());
- // See https://www.ietf.org/rfc/rfc3261.html#section-20.19
- if (!expires_ && expires != "0") {
- return srs_error_new(ERROR_GB_SIP_HEADER, "Invalid Expires=%s in header", expires.c_str());
- }
- }
-
- string max_forwards = m->header()->get("Max-Forwards");
- if (!max_forwards.empty() && max_forwards != "0") {
- max_forwards_ = (uint32_t)::atol(max_forwards.c_str());
- // See https://www.ietf.org/rfc/rfc3261.html#section-20.22
- if (!max_forwards_) {
- return srs_error_new(ERROR_GB_SIP_HEADER, "Invalid Max-Forwards=%s in header", max_forwards.c_str());
- }
- }
-
- if (via_.empty())
- return srs_error_new(ERROR_GB_SIP_HEADER, "No Via in header");
- if (from_.empty())
- return srs_error_new(ERROR_GB_SIP_HEADER, "No From in header");
- if (to_.empty())
- return srs_error_new(ERROR_GB_SIP_HEADER, "No To in header");
- if (call_id_.empty())
- return srs_error_new(ERROR_GB_SIP_HEADER, "No Call-ID in header");
- if (cseq_.empty())
- return srs_error_new(ERROR_GB_SIP_HEADER, "No CSeq in header");
-
- // Parse more information from fields.
- if ((err = parse_via(via_)) != srs_success) {
- return srs_error_wrap(err, "parse via=%s", via_.c_str());
- }
- if ((err = parse_from(from_)) != srs_success) {
- return srs_error_wrap(err, "parse from=%s", from_.c_str());
- }
- if ((err = parse_to(to_)) != srs_success) {
- return srs_error_wrap(err, "parse to=%s", to_.c_str());
- }
- if ((err = parse_cseq(cseq_)) != srs_success) {
- return srs_error_wrap(err, "parse cseq=%s", cseq_.c_str());
- }
- if ((err = parse_contact(contact_)) != srs_success) {
- return srs_error_wrap(err, "parse contact=%s", contact_.c_str());
- }
-
- srs_sip_parse_address(from_address_, from_address_user_, from_address_host_);
- srs_sip_parse_address(to_address_, to_address_user_, to_address_host_);
-
- // Except REGISTER, the initial Request-URI of the message SHOULD be set to the value of the URI in the To field.
- // See https://www.ietf.org/rfc/rfc3261.html#section-8.1.1.1
- if (type_ == HTTP_REQUEST && method_ != HTTP_REGISTER && to_address_user_ != request_uri_user_) {
- return srs_error_new(ERROR_GB_SIP_HEADER, "User of Request-URI=%s not in To=%s", request_uri_.c_str(), to_.c_str());
- }
-
- return err;
-}
-
-srs_error_t SrsSipMessage::parse_via(const std::string &via)
-{
- srs_error_t err = srs_success;
-
- if (!srs_strings_starts_with(via, "SIP/2.0/")) {
- return srs_error_new(ERROR_GB_SIP_HEADER, "Via protocol invalid");
- }
-
- if (srs_strings_starts_with(via, "SIP/2.0/TCP")) {
- via_transport_ = "TCP";
- } else if (srs_strings_starts_with(via, "SIP/2.0/UDP")) {
- via_transport_ = "UDP";
- } else {
- return srs_error_new(ERROR_GB_SIP_HEADER, "Via transport invalid");
- }
-
- vector vs = srs_strings_split(via, " ");
- if (vs.size() <= 1)
- return srs_error_new(ERROR_GB_SIP_HEADER, "Via no send-by");
-
- vector params = srs_strings_split(vs[1], ";");
- if (params.size() <= 1)
- return srs_error_new(ERROR_GB_SIP_HEADER, "Via no params");
-
- via_send_by_ = params[0];
- srs_net_split_hostport(via_send_by_, via_send_by_address_, via_send_by_port_);
-
- for (int i = 1; i < (int)params.size(); i++) {
- string param = params[i];
- if (srs_strings_starts_with(param, "rport")) {
- via_rport_ = param;
- } else if (srs_strings_starts_with(param, "branch")) {
- via_branch_ = param;
- }
- }
-
- // Before a request is sent, the client transport MUST insert a value of the "sent-by" field into the Via header
- // field. See https://www.ietf.org/rfc/rfc3261.html#section-18.1.1
- if (via_send_by_.empty())
- return srs_error_new(ERROR_GB_SIP_HEADER, "Via no sent-by");
- // The Via header field value MUST contain a branch parameter.
- // See https://www.ietf.org/rfc/rfc3261.html#section-8.1.1.7
- if (via_branch_.empty())
- return srs_error_new(ERROR_GB_SIP_HEADER, "Via no branch");
- // The branch ID inserted by an element compliant with this specification MUST always begin with the characters
- // "z9hG4bK". See https://www.ietf.org/rfc/rfc3261.html#section-8.1.1.7
- if (!srs_strings_starts_with(via_branch_, string("branch=") + SRS_GB_BRANCH_MAGIC)) {
- return srs_error_new(ERROR_GB_SIP_HEADER, "Invalid branch=%s", via_branch_.c_str());
- }
-
- return err;
-}
-
-srs_error_t SrsSipMessage::parse_from(const std::string &from)
-{
- srs_error_t err = srs_success;
-
- vector params = srs_strings_split(from, ";");
- if (params.size() < 2)
- return srs_error_new(ERROR_GB_SIP_HEADER, "From no params");
-
- from_address_ = params[0];
- for (int i = 1; i < (int)params.size(); i++) {
- string param = params[i];
- if (srs_strings_starts_with(param, "tag")) {
- from_tag_ = param;
- }
- }
-
- // The From field MUST contain a new "tag" parameter, chosen by the UAC.
- // See https://www.ietf.org/rfc/rfc3261.html#section-8.1.1.3
- if (from_tag_.empty())
- return srs_error_new(ERROR_GB_SIP_HEADER, "From no tag");
-
- return err;
-}
-
-srs_error_t SrsSipMessage::parse_to(const std::string &to)
-{
- srs_error_t err = srs_success;
-
- vector params = srs_strings_split(to, ";");
- if (params.size() < 1)
- return srs_error_new(ERROR_GB_SIP_HEADER, "To is empty");
-
- to_address_ = params[0];
- for (int i = 1; i < (int)params.size(); i++) {
- string param = params[i];
- if (srs_strings_starts_with(param, "tag")) {
- to_tag_ = param;
- }
- }
-
- return err;
-}
-
-srs_error_t SrsSipMessage::parse_cseq(const std::string &cseq)
-{
- srs_error_t err = srs_success;
-
- vector params = srs_strings_split(cseq, " ");
- if (params.size() < 2)
- return srs_error_new(ERROR_GB_SIP_HEADER, "CSeq is empty");
-
- string sno = params[0];
- if (sno != "0") {
- cseq_number_ = (uint32_t)::atol(sno.c_str());
-
- // The sequence number MUST be expressible as a 32-bit unsigned integer.
- // See https://www.ietf.org/rfc/rfc3261.html#section-20.16
- if (!cseq_number_)
- return srs_error_new(ERROR_GB_SIP_HEADER, "CSeq number is invalid");
- }
-
- cseq_method_ = params[1];
- // The method part of CSeq is case-sensitive. See https://www.ietf.org/rfc/rfc3261.html#section-20.16
- if (type_ == HTTP_REQUEST && string(http_method_str(method_)) != cseq_method_) {
- return srs_error_new(ERROR_GB_SIP_HEADER, "CSeq method=%s is invalid, expect=%d(%s)", cseq_method_.c_str(), method_, http_method_str(method_));
- }
-
- return err;
-}
-
-srs_error_t SrsSipMessage::parse_contact(const std::string &contact)
-{
- srs_error_t err = srs_success;
-
- srs_sip_parse_address(contact, contact_user_, contact_host_);
- srs_net_split_hostport(contact_host_, contact_host_address_, contact_host_port_);
-
- return err;
-}
-
SrsPackContext::SrsPackContext(ISrsPsPackHandler *handler)
{
static uint32_t gid = 0;
@@ -2748,29 +1547,6 @@ bool srs_skip_util_pack(SrsBuffer *stream)
return false;
}
-void srs_sip_parse_address(const std::string &address, std::string &user, std::string &host)
-{
- string v = address;
-
- size_t pos;
-
- if ((pos = v.find("<")) != string::npos) {
- v = v.substr(pos + 1);
- }
- if ((pos = v.find(">")) != string::npos) {
- v = v.substr(0, pos);
- }
- if ((pos = v.find("sip:")) != string::npos) {
- v = v.substr(4);
- }
-
- user = v;
- if ((pos = v.find("@")) != string::npos) {
- user = v.substr(0, pos);
- host = v.substr(pos + 1);
- }
-}
-
SrsGoApiGbPublish::SrsGoApiGbPublish(SrsConfDirective *conf)
{
conf_ = conf->copy();
@@ -2873,7 +1649,7 @@ srs_error_t SrsGoApiGbPublish::bind_session(std::string id, uint64_t ssrc)
SrsExecutorCoroutine *executor = new SrsExecutorCoroutine(_srs_gb_manager, session, raw_session, raw_session);
raw_session->setup_owner(session, executor, executor);
- raw_session->sip_transport()->set_device_id(id);
+ raw_session->device_id_ = id;
if ((err = executor->start()) != srs_success) {
srs_freep(executor);
diff --git a/trunk/src/app/srs_app_gb28181.hpp b/trunk/src/app/srs_app_gb28181.hpp
index 77e3d9bf0..c73504a9a 100644
--- a/trunk/src/app/srs_app_gb28181.hpp
+++ b/trunk/src/app/srs_app_gb28181.hpp
@@ -25,12 +25,11 @@ class SrsTcpConnection;
class SrsCoroutine;
class SrsPackContext;
class SrsBuffer;
-class SrsSipMessage;
+
class SrsGbSession;
-class SrsGbSipTcpConn;
+
class SrsGbMediaTcpConn;
-class SrsGbSipTcpReceiver;
-class SrsGbSipTcpSender;
+
class SrsAlonePithyPrint;
class SrsGbMuxer;
class SrsSimpleRtmpClient;
@@ -58,34 +57,6 @@ enum SrsGbSessionState {
};
std::string srs_gb_session_state(SrsGbSessionState state);
-// The state machine for GB SIP connection.
-// init:
-// to registered: Got REGISTER SIP message.
-// to stable: Got MESSAGE SIP message, when SIP TCP connection re-connect.
-// registered:
-// to inviting: Sent INVITE SIP message.
-// inviting:
-// to trying: Got TRYING SIP message.
-// to stable: Got INVITE 200 OK and sent INVITE OK response.
-// trying:
-// to stable: Got INVITE 200 OK and sent INVITE OK response.
-// stable:
-// to re-inviting: Sent bye to device before re-inviting.
-// to bye: Got bye SIP message from device.
-// re-inviting:
-// to inviting: Got bye OK response from deivce.
-// Please see SrsGbSipTcpConn::drive_state for detail.
-enum SrsGbSipState {
- SrsGbSipStateInit = 0,
- SrsGbSipStateRegistered,
- SrsGbSipStateInviting,
- SrsGbSipStateTrying,
- SrsGbSipStateReinviting,
- SrsGbSipStateStable,
- SrsGbSipStateBye,
-};
-std::string srs_gb_sip_state(SrsGbSipState state);
-
// For external SIP server mode, where SRS acts only as a media relay server
// 1. SIP server POST request via HTTP API with stream ID and SSRC
// 2. SRS create session using ID and SSRC, return a port for receiving media streams (indicated in conf).
@@ -118,9 +89,9 @@ private:
};
// The main logic object for GB, the session.
-// Each session contains a SIP object and a media object, that are managed by session. This means session always
-// lives longer than SIP and media, and session will dispose SIP and media when session disposed. In another word,
-// SIP and media objects use directly pointer to session, while session use shared ptr.
+// Each session contains a media object, that are managed by session. This means session always
+// lives longer than media, and session will dispose media when session disposed. In another word,
+// media objects use directly pointer to session, while session use shared ptr.
class SrsGbSession : public ISrsResource, public ISrsCoroutineHandler, public ISrsExecutorHandler
{
private:
@@ -135,23 +106,15 @@ private:
private:
SrsGbSessionState state_;
- SrsSharedResource sip_;
+
SrsSharedResource media_;
SrsGbMuxer *muxer_;
private:
- // The candidate for SDP in configuration.
- std::string candidate_;
- // The public IP for SDP, generated by SRS.
- std::string pip_;
- // When wait for SIP and media connecting, timeout if exceed.
+ // When wait for media connecting, timeout if exceed.
srs_utime_t connecting_starttime_;
- // The max timeout for connecting.
- srs_utime_t connecting_timeout_;
// The time we enter reinviting state.
srs_utime_t reinviting_starttime_;
- // The wait time for re-invite.
- srs_utime_t reinvite_wait_;
// The number of timeout, dispose session if exceed.
uint32_t nn_timeout_;
@@ -173,6 +136,11 @@ private:
uint64_t media_msgs_dropped_;
uint64_t media_reserved_;
+public:
+ // The device ID generated and set by external SIP server, using SRS HTTP API. This
+ // device ID is used to generate the RTMP stream name.
+ std::string device_id_;
+
public:
SrsGbSession();
virtual ~SrsGbSession();
@@ -189,13 +157,10 @@ public:
public:
// When got a pack of messages.
void on_ps_pack(SrsPackContext *ctx, SrsPsPacket *ps, const std::vector &msgs);
- // When got available SIP transport.
- void on_sip_transport(SrsSharedResource sip);
- SrsSharedResource sip_transport();
+
// When got available media transport.
void on_media_transport(SrsSharedResource media);
- // Get the candidate for SDP generation, the public IP address for device to connect to.
- std::string pip();
+
// Interface ISrsCoroutineHandler
public:
virtual srs_error_t cycle();
@@ -212,13 +177,12 @@ public:
virtual std::string desc();
};
-// The SIP and Media listener for GB.
+// The Media listener for GB.
class SrsGbListener : public ISrsListener, public ISrsTcpHandler
{
private:
SrsConfDirective *conf_;
SrsTcpListener *media_listener_;
- SrsTcpListener *sip_listener_;
public:
SrsGbListener();
@@ -236,174 +200,6 @@ private:
srs_error_t listen_api();
};
-// A GB28181 TCP SIP connection.
-class SrsGbSipTcpConn : public ISrsResource, public ISrsCoroutineHandler, public ISrsExecutorHandler
-{
-private:
- SrsGbSipState state_;
- // The owner session object, note that we use the raw pointer and should never free it.
- SrsGbSession *session_;
- SrsSipMessage *register_;
- SrsSipMessage *invite_ok_;
-
-private:
- std::string ssrc_str_;
- uint32_t ssrc_v_;
-
-private:
- SrsConfDirective *conf_;
- SrsTcpListener *sip_listener_;
- SrsTcpListener *media_listener_;
-
-private:
- // The shared resource which own this object, we should never free it because it's managed by shared ptr.
- SrsSharedResource *wrapper_;
- // The owner coroutine, allow user to interrupt the loop.
- ISrsInterruptable *owner_coroutine_;
- ISrsContextIdSetter *owner_cid_;
- SrsContextId cid_;
-
-private:
- SrsTcpConnection *conn_;
- SrsGbSipTcpReceiver *receiver_;
- SrsGbSipTcpSender *sender_;
-
-public:
- SrsGbSipTcpConn();
- virtual ~SrsGbSipTcpConn();
-
-public:
- // Setup object, to keep empty constructor.
- void setup(SrsConfDirective *conf, SrsTcpListener *sip, SrsTcpListener *media, srs_netfd_t stfd);
- // Setup the owner, the wrapper is the shared ptr, the interruptable object is the coroutine, and the cid is the context id.
- void setup_owner(SrsSharedResource *wrapper, ISrsInterruptable *owner_coroutine, ISrsContextIdSetter *owner_cid);
- // Interface ISrsExecutorHandler
-public:
- virtual void on_executor_done(ISrsInterruptable *executor);
-
-public:
- // Get the SIP device id.
- std::string device_id();
- // For use with external SIP signaling server ONLY
- // When using an external SIP signaling server, device id are not available, so manual configuration is required
- // This id will be used as the stream name in the RTMP protocol
- void set_device_id(const std::string &id);
- // Set the cid of all coroutines.
- virtual void set_cid(const SrsContextId &cid);
-
-private:
- // Get the sip and media listen port.
- void query_ports(int *sip, int *media);
-
-public:
- // When got a SIP message.
- srs_error_t on_sip_message(SrsSipMessage *msg);
- // Enqueue a SIP message to send, which might be a request or response.
- void enqueue_sip_message(SrsSipMessage *msg);
-
-private:
- void drive_state(SrsSipMessage *msg);
- void register_response(SrsSipMessage *msg);
- void message_response(SrsSipMessage *msg, http_status status);
- void invite_ack(SrsSipMessage *msg);
- void bye_response(SrsSipMessage *msg);
-
-public:
- srs_error_t invite_request(uint32_t *pssrc);
-
-public:
- // Interrupt transport by session.
- void interrupt();
- // Get the SIP state.
- SrsGbSipState state();
- // Reset the SIP state to registered, for re-inviting.
- void reset_to_register();
- // Whether SIP state is registered or more.
- bool is_registered();
- // Whether SIP state is stable state, established.
- bool is_stable();
- // Whether SIP is bye bye.
- bool is_bye();
-
-private:
- SrsGbSipState set_state(SrsGbSipState v);
- // Interface ISrsResource
-public:
- virtual const SrsContextId &get_id();
- virtual std::string desc();
- // Interface ISrsCoroutineHandler
-public:
- virtual srs_error_t cycle();
-
-private:
- srs_error_t do_cycle();
-
-private:
- // Create session if no one, or bind to an existed session.
- srs_error_t bind_session(SrsSipMessage *msg, SrsGbSession **psession);
-};
-
-// Start a coroutine to receive SIP messages.
-class SrsGbSipTcpReceiver : public ISrsStartable, public ISrsCoroutineHandler
-{
-private:
- SrsCoroutine *trd_;
- SrsTcpConnection *conn_;
- SrsGbSipTcpConn *sip_;
-
-public:
- SrsGbSipTcpReceiver(SrsGbSipTcpConn *sip, SrsTcpConnection *conn);
- virtual ~SrsGbSipTcpReceiver();
-
-public:
- // Interrupt the receiver coroutine.
- void interrupt();
- // Set the cid of all coroutines.
- virtual void set_cid(const SrsContextId &cid);
- // Interface ISrsStartable
-public:
- virtual srs_error_t start();
- // Interface ISrsCoroutineHandler
-public:
- virtual srs_error_t cycle();
-
-private:
- srs_error_t do_cycle();
-};
-
-// Start a coroutine to send out SIP messages.
-class SrsGbSipTcpSender : public ISrsStartable, public ISrsCoroutineHandler
-{
-private:
- SrsCoroutine *trd_;
- SrsTcpConnection *conn_;
-
-private:
- std::vector msgs_;
- srs_cond_t wait_;
-
-public:
- SrsGbSipTcpSender(SrsTcpConnection *conn);
- virtual ~SrsGbSipTcpSender();
-
-public:
- // Push message to queue, and sender will send out in dedicate coroutine.
- void enqueue(SrsSipMessage *msg);
- // Interrupt the sender coroutine.
- void interrupt();
- // Set the cid of all coroutines.
- virtual void set_cid(const SrsContextId &cid);
- // Interface ISrsStartable
-public:
- virtual srs_error_t start();
- // Interface ISrsCoroutineHandler
-public:
- virtual srs_error_t cycle();
-
-private:
- srs_error_t do_cycle();
-};
-
// The handler for a pack of PS PES packets.
class ISrsPsPackHandler
{
@@ -557,156 +353,6 @@ private:
virtual void close();
};
-// Response writer for SIP.
-class SrsSipResponseWriter : public SrsHttpResponseWriter
-{
-public:
- SrsSipResponseWriter(ISrsProtocolReadWriter *io);
- virtual ~SrsSipResponseWriter();
- // Interface ISrsHttpFirstLineWriter
-public:
- virtual srs_error_t build_first_line(std::stringstream &ss, char *data, int size);
-};
-
-// Request writer for SIP.
-class SrsSipRequestWriter : public SrsHttpRequestWriter
-{
-public:
- SrsSipRequestWriter(ISrsProtocolReadWriter *io);
- virtual ~SrsSipRequestWriter();
- // Interface ISrsHttpFirstLineWriter
-public:
- virtual srs_error_t build_first_line(std::stringstream &ss, char *data, int size);
-};
-
-// SIP message, covert with HTTP message.
-class SrsSipMessage
-{
-public:
- // SIP message type, request or response.
- http_parser_type type_;
- // For SIP request.
- http_method method_; // For example: HTTP_INVITE
- std::string request_uri_; // For example: sip:34020000001320000001@3402000000
- std::string request_uri_user_; // For example: 34020000001320000001
- std::string request_uri_host_; // For example: 3402000000
- // For SIP response.
- http_status status_; // For example: HTTP_STATUS_OK
-public:
- // The Via header field indicates the path taken by the request so far and indicates the path that should be
- // followed in routing responses. See https://www.ietf.org/rfc/rfc3261.html#section-20.42
- // @param transport TCP or UDP, the transport protocol.
- // @param send_by The host and port which send the packet.
- // @param branch Transaction identifier, see https://www.ietf.org/rfc/rfc3261.html#section-8.1.1.7
- // @param rport For UDP to traverse NATs, see https://www.ietf.org/rfc/rfc3581.html
- std::string via_; // For example: SIP/2.0/TCP 192.168.3.82:5060;rport;branch=z9hG4bK0l31rx
- std::string via_transport_; // For example: TCP
- std::string via_send_by_; // For example: 192.168.3.82:5060
- std::string via_send_by_address_; // For example: 192.168.3.82
- int via_send_by_port_; // For example: 5060
- std::string via_branch_; // For example: branch=z9hG4bK0l31rx
- std::string via_rport_; // For example: rport
-public:
- // See https://www.ietf.org/rfc/rfc3261.html#section-20.20
- // See https://www.ietf.org/rfc/rfc3261.html#section-8.1.1.3
- std::string from_; // For example: ;tag=SRSk1er282t
- std::string from_address_; // For example:
- std::string from_address_user_; // For example: 34020000002000000001
- std::string from_address_host_; // For example: 3402000000
- std::string from_tag_; // For example: tag=SRSk1er282t
-public:
- // See https://www.ietf.org/rfc/rfc3261.html#section-8.1.1.2
- // See https://www.ietf.org/rfc/rfc3261.html#section-20.39
- std::string to_; // For example: ;tag=SRSk1er282t
- std::string to_address_; // For example:
- std::string to_address_user_; // For example: 34020000001320000001
- std::string to_address_host_; // For example: 3402000000
- std::string to_tag_; // For example: tag=SRSk1er282t
-public:
- // See https://www.ietf.org/rfc/rfc3261.html#section-8.1.1.4
- // See https://www.ietf.org/rfc/rfc3261.html#section-20.8
- std::string call_id_; // For example: 854k7337207yxpfj
- // See https://www.ietf.org/rfc/rfc3261.html#section-8.1.1.8
- // See https://www.ietf.org/rfc/rfc3261.html#section-20.10
- std::string contact_; // For example:
- std::string contact_user_; // For example:
- std::string contact_host_; // For example: 3402000000
- std::string contact_host_address_; // For example: 3402000000
- int contact_host_port_; // For example: 5060
- // See https://www.ietf.org/rfc/rfc3261.html#section-20.19
- uint32_t expires_;
- // See https://www.ietf.org/rfc/rfc3261.html#section-8.1.1.6
- // See https://www.ietf.org/rfc/rfc3261.html#section-20.22
- uint32_t max_forwards_;
-
-public:
- // See https://www.ietf.org/rfc/rfc3261.html#section-8.1.1.5
- // See https://www.ietf.org/rfc/rfc3261.html#section-20.16
- std::string cseq_;
- uint32_t cseq_number_;
- std::string cseq_method_;
-
-public:
- // See https://openstd.samr.gov.cn/bzgk/gb/newGbInfo?hcno=469659DC56B9B8187671FF08748CEC89
- std::string subject_;
- // The content type.
- std::string content_type_;
-
-public:
- // SIP message body.
- std::string body_;
- // Escape \r to \\r, \n to \\n.
- std::string body_escaped_;
-
-public:
- SrsSipMessage();
- virtual ~SrsSipMessage();
-
-public:
- SrsSipMessage *copy();
- const std::string &device_id();
- std::string ssrc_domain_id();
- SrsSipMessage *set_body(std::string v);
- srs_error_t parse(ISrsHttpMessage *m);
-
-private:
- srs_error_t parse_via(const std::string &via);
- srs_error_t parse_from(const std::string &from);
- srs_error_t parse_to(const std::string &to);
- srs_error_t parse_cseq(const std::string &cseq);
- srs_error_t parse_contact(const std::string &contact);
-
-public:
- bool is_register()
- {
- return type_ == HTTP_REQUEST && method_ == HTTP_REGISTER;
- }
- bool is_message()
- {
- return type_ == HTTP_REQUEST && method_ == HTTP_MESSAGE;
- }
- bool is_invite()
- {
- return type_ == HTTP_REQUEST && method_ == HTTP_INVITE;
- }
- bool is_trying()
- {
- return type_ == HTTP_RESPONSE && cseq_method_ == "INVITE" && status_ == HTTP_STATUS_CONTINUE;
- }
- bool is_invite_ok()
- {
- return type_ == HTTP_RESPONSE && cseq_method_ == "INVITE" && status_ == HTTP_STATUS_OK;
- }
- bool is_bye()
- {
- return type_ == HTTP_REQUEST && method_ == HTTP_BYE;
- }
- bool is_bye_ok()
- {
- return type_ == HTTP_RESPONSE && cseq_method_ == "BYE" && status_ == HTTP_STATUS_OK;
- }
-};
-
// Recoverable PS context for GB28181.
class SrsRecoverablePsContext
{
@@ -774,16 +420,6 @@ public:
// Find the pack header which starts with bytes (00 00 01 ba).
extern bool srs_skip_util_pack(SrsBuffer *stream);
-// Parse the address from SIP string, for example:
-// sip:bob@ossrs.io:5060
-//
-// Bob
-// Parsed as:
-// user: bob
-// host: ossrs.io:5060
-// Note that the host can be parsed by srs_net_split_hostport as host(ossrs.io) and port(5060).
-extern void srs_sip_parse_address(const std::string &address, std::string &user, std::string &host);
-
// Manager for GB connections.
extern SrsResourceManager *_srs_gb_manager;
diff --git a/trunk/src/core/srs_core_version7.hpp b/trunk/src/core/srs_core_version7.hpp
index a76ba6b5e..b2c448982 100644
--- a/trunk/src/core/srs_core_version7.hpp
+++ b/trunk/src/core/srs_core_version7.hpp
@@ -9,6 +9,6 @@
#define VERSION_MAJOR 7
#define VERSION_MINOR 0
-#define VERSION_REVISION 74
+#define VERSION_REVISION 75
#endif
\ No newline at end of file
diff --git a/trunk/src/protocol/srs_protocol_http_stack.cpp b/trunk/src/protocol/srs_protocol_http_stack.cpp
index 1586d9073..1745d77ae 100644
--- a/trunk/src/protocol/srs_protocol_http_stack.cpp
+++ b/trunk/src/protocol/srs_protocol_http_stack.cpp
@@ -1979,12 +1979,6 @@ enum state { s_dead = 1 /* important that this is > 0 */
s_res_HT,
s_res_HTT,
s_res_HTTP,
- s_res_S /* SIP https://www.ietf.org/rfc/rfc3261.html */
- ,
- s_res_SI /* SIP https://www.ietf.org/rfc/rfc3261.html */
- ,
- s_res_SIP /* SIP https://www.ietf.org/rfc/rfc3261.html */
- ,
s_res_http_major,
s_res_http_dot,
s_res_http_minor,
@@ -2019,12 +2013,6 @@ enum state { s_dead = 1 /* important that this is > 0 */
s_req_http_HTTP,
s_req_http_I,
s_req_http_IC,
- s_req_http_S /* SIP https://www.ietf.org/rfc/rfc3261.html */
- ,
- s_req_http_SI /* SIP https://www.ietf.org/rfc/rfc3261.html */
- ,
- s_req_http_SIP /* SIP https://www.ietf.org/rfc/rfc3261.html */
- ,
s_req_http_major,
s_req_http_dot,
s_req_http_minor,
@@ -2442,11 +2430,6 @@ size_t http_parser_execute(http_parser *parser,
if (ch == 'H') {
UPDATE_STATE(s_res_or_resp_H);
- CALLBACK_NOTIFY(message_begin);
- } else if (ch == 'S') { /* SIP https://www.ietf.org/rfc/rfc3261.html */
- parser->type = HTTP_RESPONSE;
- UPDATE_STATE(s_res_S);
-
CALLBACK_NOTIFY(message_begin);
} else {
parser->type = HTTP_REQUEST;
@@ -2482,8 +2465,6 @@ size_t http_parser_execute(http_parser *parser,
if (ch == 'H') {
UPDATE_STATE(s_res_H);
- } else if (ch == 'S') { /* SIP https://www.ietf.org/rfc/rfc3261.html */
- UPDATE_STATE(s_res_S);
} else {
SET_ERRNO(HPE_INVALID_CONSTANT);
goto error;
@@ -2513,24 +2494,6 @@ size_t http_parser_execute(http_parser *parser,
UPDATE_STATE(s_res_http_major);
break;
- /* SIP https://www.ietf.org/rfc/rfc3261.html */
- case s_res_S:
- STRICT_CHECK(ch != 'I');
- UPDATE_STATE(s_res_SI);
- break;
-
- /* SIP https://www.ietf.org/rfc/rfc3261.html */
- case s_res_SI:
- STRICT_CHECK(ch != 'P');
- UPDATE_STATE(s_res_SIP);
- break;
-
- /* SIP https://www.ietf.org/rfc/rfc3261.html */
- case s_res_SIP:
- STRICT_CHECK(ch != '/');
- UPDATE_STATE(s_res_http_major);
- break;
-
case s_res_http_major:
if (UNLIKELY(!IS_NUM(ch))) {
SET_ERRNO(HPE_INVALID_VERSION);
@@ -2677,9 +2640,6 @@ size_t http_parser_execute(http_parser *parser,
case 'H':
parser->method = HTTP_HEAD;
break;
- case 'I':
- parser->method = HTTP_INVITE;
- break; /* SIP https://www.ietf.org/rfc/rfc3261.html */
case 'L':
parser->method = HTTP_LOCK; /* or LINK */
break;
@@ -2743,8 +2703,6 @@ size_t http_parser_execute(http_parser *parser,
XX(POST, 1, 'A', PATCH)
XX(POST, 1, 'R', PROPFIND)
XX(PUT, 2, 'R', PURGE)
- XX(ACL, 2, 'K', ACK) /* SIP https://www.ietf.org/rfc/rfc3261.html */
- XX(BIND, 1, 'Y', BYE) /* SIP https://www.ietf.org/rfc/rfc3261.html */
XX(CONNECT, 1, 'H', CHECKOUT)
XX(CONNECT, 2, 'P', COPY)
XX(MKCOL, 1, 'O', MOVE)
@@ -2752,11 +2710,9 @@ size_t http_parser_execute(http_parser *parser,
XX(MKCOL, 1, '-', MSEARCH)
XX(MKCOL, 2, 'A', MKACTIVITY)
XX(MKCOL, 3, 'A', MKCALENDAR)
- XX(MERGE, 2, 'S', MESSAGE) /* SIP https://www.ietf.org/rfc/rfc3261.html */
XX(SUBSCRIBE, 1, 'E', SEARCH)
XX(SUBSCRIBE, 1, 'O', SOURCE)
XX(REPORT, 2, 'B', REBIND)
- XX(REPORT, 2, 'G', REGISTER) /* SIP https://www.ietf.org/rfc/rfc3261.html */
XX(PROPFIND, 4, 'P', PROPPATCH)
XX(LOCK, 1, 'I', LINK)
XX(UNLOCK, 2, 'S', UNSUBSCRIBE)
@@ -2785,11 +2741,6 @@ size_t http_parser_execute(http_parser *parser,
UPDATE_STATE(s_req_server_start);
}
- /* SIP https://www.ietf.org/rfc/rfc3261.html */
- if (parser->method >= HTTP_REGISTER && parser->method <= HTTP_BYE) {
- UPDATE_STATE(s_req_path);
- }
-
UPDATE_STATE(parse_url_char(CURRENT_STATE(), ch));
if (UNLIKELY(CURRENT_STATE() == s_dead)) {
SET_ERRNO(HPE_INVALID_URL);
@@ -2857,9 +2808,6 @@ size_t http_parser_execute(http_parser *parser,
case 'H':
UPDATE_STATE(s_req_http_H);
break;
- case 'S': /* SIP https://www.ietf.org/rfc/rfc3261.html */
- UPDATE_STATE(s_req_http_S); /* SIP https://www.ietf.org/rfc/rfc3261.html */
- break; /* SIP https://www.ietf.org/rfc/rfc3261.html */
case 'I':
if (parser->method == HTTP_SOURCE) {
UPDATE_STATE(s_req_http_I);
@@ -2902,24 +2850,6 @@ size_t http_parser_execute(http_parser *parser,
UPDATE_STATE(s_req_http_major);
break;
- /* SIP https://www.ietf.org/rfc/rfc3261.html */
- case s_req_http_S:
- STRICT_CHECK(ch != 'I');
- UPDATE_STATE(s_req_http_SI);
- break;
-
- /* SIP https://www.ietf.org/rfc/rfc3261.html */
- case s_req_http_SI:
- STRICT_CHECK(ch != 'P');
- UPDATE_STATE(s_req_http_SIP);
- break;
-
- /* SIP https://www.ietf.org/rfc/rfc3261.html */
- case s_req_http_SIP:
- STRICT_CHECK(ch != '/');
- UPDATE_STATE(s_req_http_major);
- break;
-
case s_req_http_major:
if (UNLIKELY(!IS_NUM(ch))) {
SET_ERRNO(HPE_INVALID_VERSION);
diff --git a/trunk/src/protocol/srs_protocol_http_stack.hpp b/trunk/src/protocol/srs_protocol_http_stack.hpp
index 9327f67f0..a12ada741 100644
--- a/trunk/src/protocol/srs_protocol_http_stack.hpp
+++ b/trunk/src/protocol/srs_protocol_http_stack.hpp
@@ -905,13 +905,7 @@ enum http_status {
XX(31, LINK, LINK) \
XX(32, UNLINK, UNLINK) \
/* icecast */ \
- XX(33, SOURCE, SOURCE) \
- /* SIP https://www.ietf.org/rfc/rfc3261.html */ \
- XX(34, REGISTER, REGISTER) \
- XX(35, INVITE, INVITE) \
- XX(36, ACK, ACK) \
- XX(37, MESSAGE, MESSAGE) \
- XX(38, BYE, BYE)
+ XX(33, SOURCE, SOURCE)
enum http_method {
#define XX(num, name, string) HTTP_##name = num,
diff --git a/trunk/src/utest/srs_utest_gb28181.cpp b/trunk/src/utest/srs_utest_gb28181.cpp
index 09ec4c193..ac0eaf5f8 100644
--- a/trunk/src/utest/srs_utest_gb28181.cpp
+++ b/trunk/src/utest/srs_utest_gb28181.cpp
@@ -22,1335 +22,6 @@ using namespace std;
#include
#include
-extern void srs_sip_parse_address(const std::string &address, std::string &user, std::string &host);
-
-VOID TEST(ProtocolGbSipTest, SipParseAddress)
-{
- if (true) {
- string user, host;
- srs_sip_parse_address("", user, host);
- EXPECT_STREQ("", user.c_str());
- EXPECT_STREQ("", host.c_str());
- }
-
- if (true) {
- string user, host;
- srs_sip_parse_address("sip:", user, host);
- EXPECT_STREQ("", user.c_str());
- EXPECT_STREQ("", host.c_str());
- }
-
- if (true) {
- string user, host;
- srs_sip_parse_address("sip:bob", user, host);
- EXPECT_STREQ("bob", user.c_str());
- EXPECT_STREQ("", host.c_str());
- }
-
- if (true) {
- string user, host;
- srs_sip_parse_address("sip:bob@", user, host);
- EXPECT_STREQ("bob", user.c_str());
- EXPECT_STREQ("", host.c_str());
- }
-
- if (true) {
- string user, host;
- srs_sip_parse_address("sip:bob@host.com", user, host);
- EXPECT_STREQ("bob", user.c_str());
- EXPECT_STREQ("host.com", host.c_str());
- }
-
- if (true) {
- string user, host;
- srs_sip_parse_address("Bob ", user, host);
- EXPECT_STREQ("bob", user.c_str());
- EXPECT_STREQ("host.com", host.c_str());
- }
-
- if (true) {
- string user, host;
- srs_sip_parse_address("Bob ", user, host);
- EXPECT_STREQ("bob", user.c_str());
- EXPECT_STREQ("host.com", host.c_str());
- }
-}
-
-VOID TEST(ProtocolGbSipTest, SipViaBranchMagic)
-{
- srs_error_t err = srs_success;
-
- // See https://www.ietf.org/rfc/rfc3261.html#section-24.2
- MockMSegmentsReader r;
- r.in_bytes.push_back("REGISTER sip:registrar.biloxi.com SIP/2.0\r\n");
- r.in_bytes.push_back("Via: SIP/2.0/UDP bobspc.biloxi.com:5060;branch=xxxx\r\n");
- r.in_bytes.push_back("To: Bob \r\n");
- r.in_bytes.push_back("From: Bob ;tag=456248\r\n");
- r.in_bytes.push_back("Call-ID: 843817637684230@998sdasdh09\r\n");
- r.in_bytes.push_back("CSeq: 1826 REGISTER\r\n");
- r.in_bytes.push_back("Content-Length: 0\r\n");
- r.in_bytes.push_back("\r\n");
-
- SrsHttpParser p;
- HELPER_ASSERT_SUCCESS(p.initialize(HTTP_BOTH));
-
- ISrsHttpMessage *msg = NULL;
- HELPER_ASSERT_SUCCESS(p.parse_message(&r, &msg));
- SrsUniquePtr msg_uptr(msg);
-
- SrsSipMessage smsg;
- HELPER_ASSERT_FAILED(smsg.parse(msg));
-}
-
-VOID TEST(ProtocolGbSipTest, SipRegisterRequest)
-{
- srs_error_t err = srs_success;
-
- // See https://www.ietf.org/rfc/rfc3261.html#section-24.1
- MockMSegmentsReader source;
- source.in_bytes.push_back("REGISTER sip:registrar.biloxi.com SIP/2.0\r\n");
- source.in_bytes.push_back("Via: SIP/2.0/UDP bobspc.biloxi.com:5060;branch=z9hG4bKnashds7\r\n");
- source.in_bytes.push_back("Max-Forwards: 70\r\n");
- source.in_bytes.push_back("To: Bob \r\n");
- source.in_bytes.push_back("From: Bob ;tag=456248\r\n");
- source.in_bytes.push_back("Call-ID: 843817637684230@998sdasdh09\r\n");
- source.in_bytes.push_back("CSeq: 1826 REGISTER\r\n");
- source.in_bytes.push_back("Contact: \r\n");
- source.in_bytes.push_back("Expires: 7200\r\n");
- source.in_bytes.push_back("Content-Length: 0\r\n");
- source.in_bytes.push_back("\r\n");
-
- if (true) {
- MockMSegmentsReader r = source;
-
- SrsHttpParser p;
- HELPER_ASSERT_SUCCESS(p.initialize(HTTP_REQUEST));
-
- ISrsHttpMessage *msg = NULL;
- HELPER_ASSERT_SUCCESS(p.parse_message(&r, &msg));
- SrsUniquePtr msg_uptr(msg);
-
- EXPECT_EQ(HTTP_REGISTER, msg->method());
- EXPECT_STREQ("/sip:registrar.biloxi.com", msg->path().c_str());
- EXPECT_STREQ("SIP/2.0/UDP bobspc.biloxi.com:5060;branch=z9hG4bKnashds7", msg->header()->get("Via").c_str());
- EXPECT_STREQ("70", msg->header()->get("Max-Forwards").c_str());
- EXPECT_STREQ("Bob ", msg->header()->get("To").c_str());
- EXPECT_STREQ("Bob ;tag=456248", msg->header()->get("From").c_str());
- EXPECT_STREQ("843817637684230@998sdasdh09", msg->header()->get("Call-ID").c_str());
- EXPECT_STREQ("1826 REGISTER", msg->header()->get("CSeq").c_str());
- EXPECT_STREQ("", msg->header()->get("Contact").c_str());
- EXPECT_STREQ("7200", msg->header()->get("Expires").c_str());
- EXPECT_EQ(0, msg->content_length());
-
- SrsSipMessage smsg;
- HELPER_ASSERT_SUCCESS(smsg.parse(msg));
- EXPECT_EQ(HTTP_REQUEST, smsg.type_);
- EXPECT_EQ(HTTP_REGISTER, smsg.method_);
- EXPECT_STREQ("sip:registrar.biloxi.com", smsg.request_uri_.c_str());
- EXPECT_STREQ("SIP/2.0/UDP bobspc.biloxi.com:5060;branch=z9hG4bKnashds7", smsg.via_.c_str());
- EXPECT_STREQ("UDP", smsg.via_transport_.c_str());
- EXPECT_STREQ("bobspc.biloxi.com:5060", smsg.via_send_by_.c_str());
- EXPECT_STREQ("bobspc.biloxi.com", smsg.via_send_by_address_.c_str());
- EXPECT_EQ(5060, smsg.via_send_by_port_);
- EXPECT_STREQ("branch=z9hG4bKnashds7", smsg.via_branch_.c_str());
- EXPECT_STREQ("Bob ", smsg.to_.c_str());
- EXPECT_STREQ("Bob ", smsg.to_address_.c_str());
- EXPECT_STREQ("", smsg.to_tag_.c_str());
- EXPECT_STREQ("Bob ;tag=456248", smsg.from_.c_str());
- EXPECT_STREQ("Bob ", smsg.from_address_.c_str());
- EXPECT_STREQ("tag=456248", smsg.from_tag_.c_str());
- EXPECT_STREQ("843817637684230@998sdasdh09", smsg.call_id_.c_str());
- EXPECT_STREQ("", smsg.contact_.c_str());
- EXPECT_STREQ("bob", smsg.contact_user_.c_str());
- EXPECT_STREQ("192.0.2.4", smsg.contact_host_.c_str());
- EXPECT_STREQ("192.0.2.4", smsg.contact_host_address_.c_str());
- EXPECT_EQ(5060, smsg.contact_host_port_);
- EXPECT_STREQ("1826 REGISTER", smsg.cseq_.c_str());
- EXPECT_EQ((uint32_t)1826, smsg.cseq_number_);
- EXPECT_EQ((uint32_t)7200, smsg.expires_);
- EXPECT_EQ((uint32_t)70, smsg.max_forwards_);
- }
-
- // Parse in HTTP_REQUEST mode.
- if (true) {
- MockMSegmentsReader r = source;
-
- SrsHttpParser p;
- HELPER_ASSERT_SUCCESS(p.initialize(HTTP_REQUEST));
-
- ISrsHttpMessage *msg = NULL;
- HELPER_ASSERT_SUCCESS(p.parse_message(&r, &msg));
- SrsUniquePtr msg_uptr(msg);
-
- EXPECT_EQ(HTTP_REQUEST, (http_parser_type)msg->message_type());
- EXPECT_EQ(HTTP_REGISTER, msg->method());
- EXPECT_STREQ("/sip:registrar.biloxi.com", msg->path().c_str());
- }
-
- // Parse in HTTP_BOTH mode.
- if (true) {
- MockMSegmentsReader r = source;
-
- SrsHttpParser p;
- HELPER_ASSERT_SUCCESS(p.initialize(HTTP_BOTH));
-
- ISrsHttpMessage *msg = NULL;
- HELPER_ASSERT_SUCCESS(p.parse_message(&r, &msg));
- SrsUniquePtr msg_uptr(msg);
-
- EXPECT_EQ(HTTP_REQUEST, (http_parser_type)msg->message_type());
- EXPECT_EQ(HTTP_REGISTER, msg->method());
- EXPECT_STREQ("/sip:registrar.biloxi.com", msg->path().c_str());
- }
-}
-
-VOID TEST(ProtocolGbSipTest, SipRegisterResponse)
-{
- srs_error_t err = srs_success;
-
- // See https://www.ietf.org/rfc/rfc3261.html#section-24.1
- MockMSegmentsReader source;
- source.in_bytes.push_back("SIP/2.0 200 OK\r\n");
- source.in_bytes.push_back("Via: SIP/2.0/UDP bobspc.biloxi.com:5060;branch=z9hG4bKnashds7;received=192.0.2.4\r\n");
- source.in_bytes.push_back("To: Bob ;tag=2493k59kd\r\n");
- source.in_bytes.push_back("From: Bob ;tag=456248\r\n");
- source.in_bytes.push_back("Call-ID: 843817637684230@998sdasdh09\r\n");
- source.in_bytes.push_back("CSeq: 1826 REGISTER\r\n");
- source.in_bytes.push_back("Contact: \r\n");
- source.in_bytes.push_back("Expires: 7200\r\n");
- source.in_bytes.push_back("Content-Length: 0\r\n");
- source.in_bytes.push_back("\r\n");
-
- if (true) {
- MockMSegmentsReader r = source;
-
- SrsHttpParser p;
- HELPER_ASSERT_SUCCESS(p.initialize(HTTP_RESPONSE));
-
- ISrsHttpMessage *msg = NULL;
- HELPER_ASSERT_SUCCESS(p.parse_message(&r, &msg));
- SrsUniquePtr msg_uptr(msg);
-
- EXPECT_EQ(HTTP_RESPONSE, (http_parser_type)msg->message_type());
- EXPECT_EQ(200, msg->status_code());
- EXPECT_STREQ("SIP/2.0/UDP bobspc.biloxi.com:5060;branch=z9hG4bKnashds7;received=192.0.2.4",
- msg->header()->get("Via").c_str());
- EXPECT_STREQ("Bob ;tag=2493k59kd", msg->header()->get("To").c_str());
- EXPECT_STREQ("Bob ;tag=456248", msg->header()->get("From").c_str());
- EXPECT_STREQ("843817637684230@998sdasdh09", msg->header()->get("Call-ID").c_str());
- EXPECT_STREQ("1826 REGISTER", msg->header()->get("CSeq").c_str());
- EXPECT_STREQ("", msg->header()->get("Contact").c_str());
- EXPECT_STREQ("7200", msg->header()->get("Expires").c_str());
- EXPECT_EQ(0, msg->content_length());
-
- SrsSipMessage smsg;
- HELPER_ASSERT_SUCCESS(smsg.parse(msg));
- EXPECT_EQ(HTTP_RESPONSE, smsg.type_);
- EXPECT_EQ(HTTP_STATUS_OK, smsg.status_);
- EXPECT_STREQ("SIP/2.0/UDP bobspc.biloxi.com:5060;branch=z9hG4bKnashds7;received=192.0.2.4", smsg.via_.c_str());
- EXPECT_STREQ("UDP", smsg.via_transport_.c_str());
- EXPECT_STREQ("bobspc.biloxi.com:5060", smsg.via_send_by_.c_str());
- EXPECT_STREQ("bobspc.biloxi.com", smsg.via_send_by_address_.c_str());
- EXPECT_EQ(5060, smsg.via_send_by_port_);
- EXPECT_STREQ("branch=z9hG4bKnashds7", smsg.via_branch_.c_str());
- EXPECT_STREQ("Bob ;tag=2493k59kd", smsg.to_.c_str());
- EXPECT_STREQ("Bob ", smsg.to_address_.c_str());
- EXPECT_STREQ("tag=2493k59kd", smsg.to_tag_.c_str());
- EXPECT_STREQ("Bob ;tag=456248", smsg.from_.c_str());
- EXPECT_STREQ("Bob ", smsg.from_address_.c_str());
- EXPECT_STREQ("tag=456248", smsg.from_tag_.c_str());
- EXPECT_STREQ("843817637684230@998sdasdh09", smsg.call_id_.c_str());
- EXPECT_STREQ("", smsg.contact_.c_str());
- EXPECT_STREQ("bob", smsg.contact_user_.c_str());
- EXPECT_STREQ("192.0.2.4", smsg.contact_host_.c_str());
- EXPECT_STREQ("192.0.2.4", smsg.contact_host_address_.c_str());
- EXPECT_EQ(5060, smsg.contact_host_port_);
- EXPECT_STREQ("1826 REGISTER", smsg.cseq_.c_str());
- EXPECT_EQ((uint32_t)1826, smsg.cseq_number_);
- }
-
- // Parse in HTTP_RESPONSE mode.
- if (true) {
- MockMSegmentsReader r = source;
-
- SrsHttpParser p;
- HELPER_ASSERT_SUCCESS(p.initialize(HTTP_RESPONSE));
-
- ISrsHttpMessage *msg = NULL;
- HELPER_ASSERT_SUCCESS(p.parse_message(&r, &msg));
- SrsUniquePtr msg_uptr(msg);
-
- EXPECT_EQ(HTTP_RESPONSE, (http_parser_type)msg->message_type());
- EXPECT_EQ(200, msg->status_code());
- }
-
- // Parse in HTTP_BOTH mode.
- if (true) {
- MockMSegmentsReader r = source;
-
- SrsHttpParser p;
- HELPER_ASSERT_SUCCESS(p.initialize(HTTP_BOTH));
-
- ISrsHttpMessage *msg = NULL;
- HELPER_ASSERT_SUCCESS(p.parse_message(&r, &msg));
- SrsUniquePtr msg_uptr(msg);
-
- EXPECT_EQ(HTTP_RESPONSE, (http_parser_type)msg->message_type());
- EXPECT_EQ(200, msg->status_code());
- }
-}
-
-VOID TEST(ProtocolGbSipTest, SipSessionUacInviteRequest)
-{
- srs_error_t err = srs_success;
-
- // See https://www.ietf.org/rfc/rfc3261.html#section-24.2
- MockMSegmentsReader r;
- r.in_bytes.push_back("INVITE sip:bob@biloxi.com SIP/2.0\r\n");
- r.in_bytes.push_back("Via: SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bKnashds8\r\n");
- r.in_bytes.push_back("Max-Forwards: 70\r\n");
- r.in_bytes.push_back("To: Bob \r\n");
- r.in_bytes.push_back("From: Alice ;tag=1928301774\r\n");
- r.in_bytes.push_back("Call-ID: a84b4c76e66710\r\n");
- r.in_bytes.push_back("CSeq: 314159 INVITE\r\n");
- r.in_bytes.push_back("Contact: \r\n");
- r.in_bytes.push_back("Content-Type: application/sdp\r\n");
- r.in_bytes.push_back("Content-Length: 142\r\n");
- r.in_bytes.push_back("\r\n");
- r.in_bytes.push_back(string(142, 'x'));
-
- SrsHttpParser p;
- HELPER_ASSERT_SUCCESS(p.initialize(HTTP_BOTH));
-
- ISrsHttpMessage *msg = NULL;
- HELPER_ASSERT_SUCCESS(p.parse_message(&r, &msg));
- SrsUniquePtr msg_uptr(msg);
-
- EXPECT_EQ(HTTP_INVITE, msg->method());
- EXPECT_STREQ("/sip:bob@biloxi.com", msg->path().c_str());
- EXPECT_STREQ("SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bKnashds8", msg->header()->get("Via").c_str());
- EXPECT_STREQ("70", msg->header()->get("Max-Forwards").c_str());
- EXPECT_STREQ("Bob ", msg->header()->get("To").c_str());
- EXPECT_STREQ("Alice ;tag=1928301774", msg->header()->get("From").c_str());
- EXPECT_STREQ("a84b4c76e66710", msg->header()->get("Call-ID").c_str());
- EXPECT_STREQ("314159 INVITE", msg->header()->get("CSeq").c_str());
- EXPECT_STREQ("", msg->header()->get("Contact").c_str());
- EXPECT_EQ(142, msg->content_length());
-
- SrsSipMessage smsg;
- HELPER_ASSERT_SUCCESS(smsg.parse(msg));
- EXPECT_EQ(HTTP_REQUEST, smsg.type_);
- EXPECT_EQ(HTTP_INVITE, smsg.method_);
- EXPECT_STREQ("sip:bob@biloxi.com", smsg.request_uri_.c_str());
- EXPECT_STREQ("SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bKnashds8", smsg.via_.c_str());
- EXPECT_STREQ("UDP", smsg.via_transport_.c_str());
- EXPECT_STREQ("pc33.atlanta.com", smsg.via_send_by_.c_str());
- EXPECT_STREQ("pc33.atlanta.com", smsg.via_send_by_address_.c_str());
- EXPECT_EQ(5060, smsg.via_send_by_port_);
- EXPECT_STREQ("branch=z9hG4bKnashds8", smsg.via_branch_.c_str());
- EXPECT_STREQ("Bob ", smsg.to_.c_str());
- EXPECT_STREQ("Bob ", smsg.to_address_.c_str());
- EXPECT_STREQ("", smsg.to_tag_.c_str());
- EXPECT_STREQ("Alice ;tag=1928301774", smsg.from_.c_str());
- EXPECT_STREQ("Alice ", smsg.from_address_.c_str());
- EXPECT_STREQ("tag=1928301774", smsg.from_tag_.c_str());
- EXPECT_STREQ("a84b4c76e66710", smsg.call_id_.c_str());
- EXPECT_STREQ("", smsg.contact_.c_str());
- EXPECT_STREQ("alice", smsg.contact_user_.c_str());
- EXPECT_STREQ("pc33.atlanta.com", smsg.contact_host_.c_str());
- EXPECT_STREQ("pc33.atlanta.com", smsg.contact_host_address_.c_str());
- EXPECT_EQ(5060, smsg.contact_host_port_);
- EXPECT_STREQ("314159 INVITE", smsg.cseq_.c_str());
- EXPECT_EQ((uint32_t)314159, smsg.cseq_number_);
- EXPECT_EQ((uint32_t)70, smsg.max_forwards_);
- EXPECT_EQ((size_t)142, smsg.body_.length());
-}
-
-VOID TEST(ProtocolGbSipTest, SipSessionUasTryingResponse)
-{
- srs_error_t err = srs_success;
-
- // See https://www.ietf.org/rfc/rfc3261.html#section-24.2
- MockMSegmentsReader r;
- r.in_bytes.push_back("SIP/2.0 100 Trying\r\n");
- r.in_bytes.push_back("Via: SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bKnashds8;received=192.0.2.1\r\n");
- r.in_bytes.push_back("To: Bob \r\n");
- r.in_bytes.push_back("From: Alice ;tag=1928301774\r\n");
- r.in_bytes.push_back("Call-ID: a84b4c76e66710\r\n");
- r.in_bytes.push_back("CSeq: 314159 INVITE\r\n");
- r.in_bytes.push_back("Content-Length: 0\r\n");
- r.in_bytes.push_back("\r\n");
-
- SrsHttpParser p;
- HELPER_ASSERT_SUCCESS(p.initialize(HTTP_RESPONSE));
-
- ISrsHttpMessage *msg = NULL;
- HELPER_ASSERT_SUCCESS(p.parse_message(&r, &msg));
- SrsUniquePtr msg_uptr(msg);
-
- EXPECT_EQ(HTTP_RESPONSE, (http_parser_type)msg->message_type());
- EXPECT_EQ(100, msg->status_code());
- EXPECT_STREQ("SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bKnashds8;received=192.0.2.1", msg->header()->get("Via").c_str());
- EXPECT_STREQ("Bob ", msg->header()->get("To").c_str());
- EXPECT_STREQ("Alice ;tag=1928301774", msg->header()->get("From").c_str());
- EXPECT_STREQ("a84b4c76e66710", msg->header()->get("Call-ID").c_str());
- EXPECT_STREQ("314159 INVITE", msg->header()->get("CSeq").c_str());
- EXPECT_EQ(0, msg->content_length());
-
- SrsSipMessage smsg;
- HELPER_ASSERT_SUCCESS(smsg.parse(msg));
- EXPECT_EQ(HTTP_RESPONSE, smsg.type_);
- EXPECT_EQ(100, smsg.status_);
- EXPECT_STREQ("SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bKnashds8;received=192.0.2.1", smsg.via_.c_str());
- EXPECT_STREQ("UDP", smsg.via_transport_.c_str());
- EXPECT_STREQ("pc33.atlanta.com", smsg.via_send_by_.c_str());
- EXPECT_STREQ("pc33.atlanta.com", smsg.via_send_by_address_.c_str());
- EXPECT_EQ(5060, smsg.via_send_by_port_);
- EXPECT_STREQ("branch=z9hG4bKnashds8", smsg.via_branch_.c_str());
- EXPECT_STREQ("Bob ", smsg.to_.c_str());
- EXPECT_STREQ("Bob ", smsg.to_address_.c_str());
- EXPECT_STREQ("", smsg.to_tag_.c_str());
- EXPECT_STREQ("Alice ;tag=1928301774", smsg.from_.c_str());
- EXPECT_STREQ("Alice ", smsg.from_address_.c_str());
- EXPECT_STREQ("tag=1928301774", smsg.from_tag_.c_str());
- EXPECT_STREQ("a84b4c76e66710", smsg.call_id_.c_str());
- EXPECT_STREQ("314159 INVITE", smsg.cseq_.c_str());
- EXPECT_EQ((uint32_t)314159, smsg.cseq_number_);
-}
-
-VOID TEST(ProtocolGbSipTest, SipSessionUas200OkResponse)
-{
- srs_error_t err = srs_success;
-
- // See https://www.ietf.org/rfc/rfc3261.html#section-24.2
- MockMSegmentsReader r;
- r.in_bytes.push_back("SIP/2.0 200 OK\r\n");
- r.in_bytes.push_back("Via: SIP/2.0/UDP server10.biloxi.com;branch=z9hG4bK4b43c2ff8.1;received=192.0.2.3\r\n");
- r.in_bytes.push_back("Via: SIP/2.0/UDP bigbox3.site3.atlanta.com;branch=z9hG4bK77ef4c2312983.1;received=192.0.2.2\r\n");
- r.in_bytes.push_back("Via: SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bKnashds8;received=192.0.2.1\r\n");
- r.in_bytes.push_back("To: Bob ;tag=a6c85cf\r\n");
- r.in_bytes.push_back("From: Alice ;tag=1928301774\r\n");
- r.in_bytes.push_back("Call-ID: a84b4c76e66710\r\n");
- r.in_bytes.push_back("CSeq: 314159 INVITE\r\n");
- r.in_bytes.push_back("Contact: \r\n");
- r.in_bytes.push_back("Content-Type: application/sdp\r\n");
- r.in_bytes.push_back("Content-Length: 131\r\n");
- r.in_bytes.push_back("\r\n");
- r.in_bytes.push_back(string(131, 'x'));
-
- SrsHttpParser p;
- HELPER_ASSERT_SUCCESS(p.initialize(HTTP_RESPONSE));
-
- ISrsHttpMessage *msg = NULL;
- HELPER_ASSERT_SUCCESS(p.parse_message(&r, &msg));
- SrsUniquePtr msg_uptr(msg);
-
- EXPECT_EQ(HTTP_RESPONSE, (http_parser_type)msg->message_type());
- EXPECT_EQ(200, msg->status_code());
- EXPECT_STREQ("SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bKnashds8;received=192.0.2.1", msg->header()->get("Via").c_str());
- EXPECT_STREQ("Bob ;tag=a6c85cf", msg->header()->get("To").c_str());
- EXPECT_STREQ("Alice ;tag=1928301774", msg->header()->get("From").c_str());
- EXPECT_STREQ("", msg->header()->get("Contact").c_str());
- EXPECT_STREQ("a84b4c76e66710", msg->header()->get("Call-ID").c_str());
- EXPECT_STREQ("314159 INVITE", msg->header()->get("CSeq").c_str());
- EXPECT_EQ(131, msg->content_length());
-
- SrsSipMessage smsg;
- HELPER_ASSERT_SUCCESS(smsg.parse(msg));
- EXPECT_EQ(HTTP_RESPONSE, smsg.type_);
- EXPECT_EQ(200, smsg.status_);
- EXPECT_STREQ("SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bKnashds8;received=192.0.2.1", smsg.via_.c_str());
- EXPECT_STREQ("UDP", smsg.via_transport_.c_str());
- EXPECT_STREQ("pc33.atlanta.com", smsg.via_send_by_.c_str());
- EXPECT_STREQ("pc33.atlanta.com", smsg.via_send_by_address_.c_str());
- EXPECT_EQ(5060, smsg.via_send_by_port_);
- EXPECT_STREQ("branch=z9hG4bKnashds8", smsg.via_branch_.c_str());
- EXPECT_STREQ("Bob ;tag=a6c85cf", smsg.to_.c_str());
- EXPECT_STREQ("Bob ", smsg.to_address_.c_str());
- EXPECT_STREQ("tag=a6c85cf", smsg.to_tag_.c_str());
- EXPECT_STREQ("Alice ;tag=1928301774", smsg.from_.c_str());
- EXPECT_STREQ("Alice ", smsg.from_address_.c_str());
- EXPECT_STREQ("tag=1928301774", smsg.from_tag_.c_str());
- EXPECT_STREQ("", smsg.contact_.c_str());
- EXPECT_STREQ("bob", smsg.contact_user_.c_str());
- EXPECT_STREQ("192.0.2.4", smsg.contact_host_.c_str());
- EXPECT_STREQ("192.0.2.4", smsg.contact_host_address_.c_str());
- EXPECT_EQ(5060, smsg.contact_host_port_);
- EXPECT_STREQ("a84b4c76e66710", smsg.call_id_.c_str());
- EXPECT_STREQ("314159 INVITE", smsg.cseq_.c_str());
- EXPECT_EQ((uint32_t)314159, smsg.cseq_number_);
- EXPECT_EQ((size_t)131, smsg.body_.length());
-}
-
-VOID TEST(ProtocolGbSipTest, SipSessionUacAckRequest)
-{
- srs_error_t err = srs_success;
-
- // See https://www.ietf.org/rfc/rfc3261.html#section-24.2
- MockMSegmentsReader r;
- r.in_bytes.push_back("ACK sip:bob@192.0.2.4 SIP/2.0\r\n");
- r.in_bytes.push_back("Via: SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bKnashds9\r\n");
- r.in_bytes.push_back("Max-Forwards: 70\r\n");
- r.in_bytes.push_back("To: Bob ;tag=a6c85cf\r\n");
- r.in_bytes.push_back("From: Alice ;tag=1928301774\r\n");
- r.in_bytes.push_back("Call-ID: a84b4c76e66710\r\n");
- r.in_bytes.push_back("CSeq: 314159 ACK\r\n");
- r.in_bytes.push_back("Content-Length: 0\r\n");
- r.in_bytes.push_back("\r\n");
-
- SrsHttpParser p;
- HELPER_ASSERT_SUCCESS(p.initialize(HTTP_BOTH));
-
- ISrsHttpMessage *msg = NULL;
- HELPER_ASSERT_SUCCESS(p.parse_message(&r, &msg));
- SrsUniquePtr msg_uptr(msg);
-
- EXPECT_EQ(HTTP_ACK, msg->method());
- EXPECT_STREQ("/sip:bob@192.0.2.4", msg->path().c_str());
- EXPECT_STREQ("SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bKnashds9", msg->header()->get("Via").c_str());
- EXPECT_STREQ("70", msg->header()->get("Max-Forwards").c_str());
- EXPECT_STREQ("Bob ;tag=a6c85cf", msg->header()->get("To").c_str());
- EXPECT_STREQ("Alice ;tag=1928301774", msg->header()->get("From").c_str());
- EXPECT_STREQ("a84b4c76e66710", msg->header()->get("Call-ID").c_str());
- EXPECT_STREQ("314159 ACK", msg->header()->get("CSeq").c_str());
- EXPECT_EQ(0, msg->content_length());
-
- SrsSipMessage smsg;
- HELPER_ASSERT_SUCCESS(smsg.parse(msg));
- EXPECT_EQ(HTTP_REQUEST, smsg.type_);
- EXPECT_EQ(HTTP_ACK, smsg.method_);
- EXPECT_STREQ("sip:bob@192.0.2.4", smsg.request_uri_.c_str());
- EXPECT_STREQ("SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bKnashds9", smsg.via_.c_str());
- EXPECT_STREQ("UDP", smsg.via_transport_.c_str());
- EXPECT_STREQ("pc33.atlanta.com", smsg.via_send_by_.c_str());
- EXPECT_STREQ("pc33.atlanta.com", smsg.via_send_by_address_.c_str());
- EXPECT_EQ(5060, smsg.via_send_by_port_);
- EXPECT_STREQ("branch=z9hG4bKnashds9", smsg.via_branch_.c_str());
- EXPECT_STREQ("Bob ;tag=a6c85cf", smsg.to_.c_str());
- EXPECT_STREQ("Bob ", smsg.to_address_.c_str());
- EXPECT_STREQ("tag=a6c85cf", smsg.to_tag_.c_str());
- EXPECT_STREQ("Alice ;tag=1928301774", smsg.from_.c_str());
- EXPECT_STREQ("Alice ", smsg.from_address_.c_str());
- EXPECT_STREQ("tag=1928301774", smsg.from_tag_.c_str());
- EXPECT_STREQ("a84b4c76e66710", smsg.call_id_.c_str());
- EXPECT_STREQ("314159 ACK", smsg.cseq_.c_str());
- EXPECT_EQ((uint32_t)314159, smsg.cseq_number_);
- EXPECT_EQ((uint32_t)70, smsg.max_forwards_);
-}
-
-VOID TEST(ProtocolGbSipTest, SipSessionUacByeRequest)
-{
- srs_error_t err = srs_success;
-
- // See https://www.ietf.org/rfc/rfc3261.html#section-24.2
- MockMSegmentsReader r;
- r.in_bytes.push_back("BYE sip:alice@pc33.atlanta.com SIP/2.0\r\n");
- r.in_bytes.push_back("Via: SIP/2.0/UDP 192.0.2.4;branch=z9hG4bKnashds10\r\n");
- r.in_bytes.push_back("Max-Forwards: 70\r\n");
- r.in_bytes.push_back("From: Bob ;tag=a6c85cf\r\n");
- r.in_bytes.push_back("To: Alice ;tag=1928301774\r\n");
- r.in_bytes.push_back("Call-ID: a84b4c76e66710\r\n");
- r.in_bytes.push_back("CSeq: 231 BYE\r\n");
- r.in_bytes.push_back("Content-Length: 0\r\n");
- r.in_bytes.push_back("\r\n");
-
- SrsHttpParser p;
- HELPER_ASSERT_SUCCESS(p.initialize(HTTP_BOTH));
-
- ISrsHttpMessage *msg = NULL;
- HELPER_ASSERT_SUCCESS(p.parse_message(&r, &msg));
- SrsUniquePtr msg_uptr(msg);
-
- EXPECT_EQ(HTTP_BYE, msg->method());
- EXPECT_STREQ("/sip:alice@pc33.atlanta.com", msg->path().c_str());
- EXPECT_STREQ("SIP/2.0/UDP 192.0.2.4;branch=z9hG4bKnashds10", msg->header()->get("Via").c_str());
- EXPECT_STREQ("70", msg->header()->get("Max-Forwards").c_str());
- EXPECT_STREQ("Alice ;tag=1928301774", msg->header()->get("To").c_str());
- EXPECT_STREQ("Bob ;tag=a6c85cf", msg->header()->get("From").c_str());
- EXPECT_STREQ("a84b4c76e66710", msg->header()->get("Call-ID").c_str());
- EXPECT_STREQ("231 BYE", msg->header()->get("CSeq").c_str());
- EXPECT_EQ(0, msg->content_length());
-
- SrsSipMessage smsg;
- HELPER_ASSERT_SUCCESS(smsg.parse(msg));
- EXPECT_EQ(HTTP_REQUEST, smsg.type_);
- EXPECT_EQ(HTTP_BYE, smsg.method_);
- EXPECT_STREQ("sip:alice@pc33.atlanta.com", smsg.request_uri_.c_str());
- EXPECT_STREQ("SIP/2.0/UDP 192.0.2.4;branch=z9hG4bKnashds10", smsg.via_.c_str());
- EXPECT_STREQ("UDP", smsg.via_transport_.c_str());
- EXPECT_STREQ("192.0.2.4", smsg.via_send_by_.c_str());
- EXPECT_STREQ("192.0.2.4", smsg.via_send_by_address_.c_str());
- EXPECT_EQ(5060, smsg.via_send_by_port_);
- EXPECT_STREQ("branch=z9hG4bKnashds10", smsg.via_branch_.c_str());
- EXPECT_STREQ("Alice ;tag=1928301774", smsg.to_.c_str());
- EXPECT_STREQ("Alice ", smsg.to_address_.c_str());
- EXPECT_STREQ("tag=1928301774", smsg.to_tag_.c_str());
- EXPECT_STREQ("Bob ;tag=a6c85cf", smsg.from_.c_str());
- EXPECT_STREQ("Bob ", smsg.from_address_.c_str());
- EXPECT_STREQ("tag=a6c85cf", smsg.from_tag_.c_str());
- EXPECT_STREQ("a84b4c76e66710", smsg.call_id_.c_str());
- EXPECT_STREQ("231 BYE", smsg.cseq_.c_str());
- EXPECT_EQ((uint32_t)231, smsg.cseq_number_);
- EXPECT_EQ((uint32_t)70, smsg.max_forwards_);
-}
-
-VOID TEST(ProtocolGbSipTest, SipRegisterExpires)
-{
- srs_error_t err = srs_success;
-
- if (true) {
- MockMSegmentsReader r;
- r.in_bytes.push_back("REGISTER sip:registrar.biloxi.com SIP/2.0\r\n");
- r.in_bytes.push_back("Via: SIP/2.0/UDP bobspc.biloxi.com:5060;branch=z9hG4bKnashds7\r\n");
- r.in_bytes.push_back("To: Bob \r\n");
- r.in_bytes.push_back("From: Bob ;tag=456248\r\n");
- r.in_bytes.push_back("Call-ID: 843817637684230@998sdasdh09\r\n");
- r.in_bytes.push_back("CSeq: 1826 REGISTER\r\n");
- r.in_bytes.push_back("Expires: 7200\r\n");
- r.in_bytes.push_back("Content-Length: 0\r\n");
- r.in_bytes.push_back("\r\n");
-
- SrsHttpParser p;
- HELPER_ASSERT_SUCCESS(p.initialize(HTTP_REQUEST));
-
- ISrsHttpMessage *msg = NULL;
- HELPER_ASSERT_SUCCESS(p.parse_message(&r, &msg));
- SrsUniquePtr msg_uptr(msg);
-
- SrsSipMessage smsg;
- HELPER_ASSERT_SUCCESS(smsg.parse(msg));
- EXPECT_EQ(HTTP_REQUEST, smsg.type_);
- EXPECT_EQ(HTTP_REGISTER, smsg.method_);
- EXPECT_EQ((uint32_t)7200, smsg.expires_);
- }
-
- if (true) {
- MockMSegmentsReader r;
- r.in_bytes.push_back("REGISTER sip:registrar.biloxi.com SIP/2.0\r\n");
- r.in_bytes.push_back("Via: SIP/2.0/UDP bobspc.biloxi.com:5060;branch=z9hG4bKnashds7\r\n");
- r.in_bytes.push_back("To: Bob \r\n");
- r.in_bytes.push_back("From: Bob ;tag=456248\r\n");
- r.in_bytes.push_back("Call-ID: 843817637684230@998sdasdh09\r\n");
- r.in_bytes.push_back("CSeq: 1826 REGISTER\r\n");
- r.in_bytes.push_back("Expires: 0\r\n");
- r.in_bytes.push_back("Content-Length: 0\r\n");
- r.in_bytes.push_back("\r\n");
-
- SrsHttpParser p;
- HELPER_ASSERT_SUCCESS(p.initialize(HTTP_REQUEST));
-
- ISrsHttpMessage *msg = NULL;
- HELPER_ASSERT_SUCCESS(p.parse_message(&r, &msg));
- SrsUniquePtr msg_uptr(msg);
-
- SrsSipMessage smsg;
- HELPER_ASSERT_SUCCESS(smsg.parse(msg));
- EXPECT_EQ(HTTP_REQUEST, smsg.type_);
- EXPECT_EQ(HTTP_REGISTER, smsg.method_);
- EXPECT_EQ((uint32_t)0, smsg.expires_);
- }
-}
-
-VOID TEST(ProtocolGbSipTest, SipSmallMessagesInOneBuffer)
-{
- srs_error_t err = srs_success;
-
- // See https://www.ietf.org/rfc/rfc3261.html#section-24.2
- MockMSegmentsReader r;
- r.in_bytes.push_back(
- "SIP/2.0 100 Trying\r\n"
- "Via: SIP/2.0/TCP 192.168.3.85:5060;rport=5060;branch=z9hG4bK95108j;received=127.0.0.1\r\n"
- "From: ;tag=SRS6600q9p4\r\n"
- "To: \r\n"
- "Call-ID: x220zl3805088272\r\n"
- "CSeq: 831 INVITE\r\n"
- "Content-Length: 0\r\n"
- "\r\n"
- "SIP/2.0 200 OK\r\n"
- "Via: SIP/2.0/TCP 192.168.3.85:5060;rport=5060;branch=z9hG4bK95108j;received=127.0.0.1\r\n"
- "From: ;tag=SRS6600q9p4\r\n"
- "To: \r\n"
- "Call-ID: x220zl3805088272\r\n"
- "CSeq: 831 INVITE\r\n"
- "Content-Length: 0\r\n"
- "\r\n");
-
- SrsHttpParser p;
- HELPER_ASSERT_SUCCESS(p.initialize(HTTP_BOTH));
-
- if (true) {
- ISrsHttpMessage *msg = NULL;
- HELPER_ASSERT_SUCCESS(p.parse_message(&r, &msg));
- SrsUniquePtr msg_uptr(msg);
-
- SrsSipMessage smsg;
- HELPER_ASSERT_SUCCESS(smsg.parse(msg));
- EXPECT_EQ(HTTP_RESPONSE, smsg.type_);
- EXPECT_EQ(100, smsg.status_);
- }
-
- if (true) {
- ISrsHttpMessage *msg = NULL;
- HELPER_ASSERT_SUCCESS(p.parse_message(&r, &msg));
- SrsUniquePtr msg_uptr(msg);
-
- SrsSipMessage smsg;
- HELPER_ASSERT_SUCCESS(smsg.parse(msg));
- EXPECT_EQ(HTTP_RESPONSE, smsg.type_);
- EXPECT_EQ(200, smsg.status_);
- }
-}
-
-VOID TEST(ProtocolGbSipTest, SipSmallMessagesWithBody)
-{
- srs_error_t err = srs_success;
-
- // See https://www.ietf.org/rfc/rfc3261.html#section-24.2
- MockMSegmentsReader r;
- r.in_bytes.push_back(
- "SIP/2.0 100 Trying\r\n"
- "Via: SIP/2.0/TCP 192.168.3.85:5060;rport=5060;branch=z9hG4bK95108j;received=127.0.0.1\r\n"
- "From: ;tag=SRS6600q9p4\r\n"
- "To: \r\n"
- "Call-ID: x220zl3805088272\r\n"
- "CSeq: 831 INVITE\r\n"
- "Content-Length: 10\r\n"
- "\r\n"
- "HelloWorld"
- "SIP/2.0 200 OK\r\n"
- "Via: SIP/2.0/TCP 192.168.3.85:5060;rport=5060;branch=z9hG4bK95108j;received=127.0.0.1\r\n"
- "From: ;tag=SRS6600q9p4\r\n"
- "To: \r\n"
- "Call-ID: x220zl3805088272\r\n"
- "CSeq: 831 INVITE\r\n"
- "Content-Length: 11\r\n"
- "\r\n"
- "HelloServer");
-
- SrsHttpParser p;
- HELPER_ASSERT_SUCCESS(p.initialize(HTTP_BOTH));
-
- if (true) {
- ISrsHttpMessage *msg = NULL;
- HELPER_ASSERT_SUCCESS(p.parse_message(&r, &msg));
- SrsUniquePtr msg_uptr(msg);
-
- SrsSipMessage smsg;
- HELPER_ASSERT_SUCCESS(smsg.parse(msg));
- EXPECT_EQ(HTTP_RESPONSE, smsg.type_);
- EXPECT_EQ(100, smsg.status_);
- EXPECT_STREQ("HelloWorld", smsg.body_.c_str());
- }
-
- if (true) {
- ISrsHttpMessage *msg = NULL;
- HELPER_ASSERT_SUCCESS(p.parse_message(&r, &msg));
- SrsUniquePtr msg_uptr(msg);
-
- SrsSipMessage smsg;
- HELPER_ASSERT_SUCCESS(smsg.parse(msg));
- EXPECT_EQ(HTTP_RESPONSE, smsg.type_);
- EXPECT_EQ(200, smsg.status_);
- EXPECT_STREQ("HelloServer", smsg.body_.c_str());
- }
-}
-
-VOID TEST(ProtocolGbSipTest, SipStandardOfferDecode)
-{
- srs_error_t err = srs_success;
-
- string str =
- "v=0\r\n"
- "o=64010600002020000001 0 0 IN IP4 172.20.16.3\r\n"
- "s=Play\r\n"
- "c=IN IP4 172.20.16.3\r\n"
- "t=0 0\r\n"
- "m=video 6000 RTP/AVP 96 98 97\r\n"
- "a=recvonly\r\n"
- "a=rtpmap:96 PS/90000\r\n"
- "a=rtpmap:98 H264/90000\r\n"
- "a=rtpmap:97 MPEG4/90000\r\n";
- SrsSdp o;
- HELPER_ASSERT_SUCCESS(o.parse(str));
- EXPECT_STREQ("0", o.version_.c_str());
- EXPECT_STREQ("64010600002020000001", o.username_.c_str());
- EXPECT_STREQ("0", o.session_id_.c_str());
- EXPECT_STREQ("0", o.session_version_.c_str());
- EXPECT_STREQ("IN", o.nettype_.c_str());
- EXPECT_STREQ("IP4", o.addrtype_.c_str());
- EXPECT_STREQ("172.20.16.3", o.unicast_address_.c_str());
- EXPECT_STREQ("Play", o.session_name_.c_str());
- EXPECT_EQ(0, o.start_time_);
- EXPECT_EQ(0, o.end_time_);
-
- ASSERT_EQ((size_t)1, o.media_descs_.size());
- const SrsMediaDesc &m = o.media_descs_.at(0);
- EXPECT_STREQ("video", m.type_.c_str());
- EXPECT_EQ(6000, m.port_);
- EXPECT_STREQ("RTP/AVP", m.protos_.c_str());
- EXPECT_EQ((size_t)3, m.payload_types_.size());
-
- const SrsMediaPayloadType &ps = m.payload_types_.at(0);
- EXPECT_EQ(96, ps.payload_type_);
- EXPECT_STREQ("PS", ps.encoding_name_.c_str());
- EXPECT_EQ(90000, ps.clock_rate_);
-
- const SrsMediaPayloadType &h264 = m.payload_types_.at(1);
- EXPECT_EQ(98, h264.payload_type_);
- EXPECT_STREQ("H264", h264.encoding_name_.c_str());
- EXPECT_EQ(90000, h264.clock_rate_);
-
- const SrsMediaPayloadType &mpeg4 = m.payload_types_.at(2);
- EXPECT_EQ(97, mpeg4.payload_type_);
- EXPECT_STREQ("MPEG4", mpeg4.encoding_name_.c_str());
- EXPECT_EQ(90000, mpeg4.clock_rate_);
-}
-
-VOID TEST(ProtocolGbSipTest, SipStandardOfferEncode)
-{
- srs_error_t err = srs_success;
-
- SrsSdp o;
- o.version_ = "0";
- o.username_ = "64010600002020000001";
- o.session_id_ = "0";
- o.session_version_ = "0";
- o.nettype_ = "IN";
- o.addrtype_ = "IP4";
- o.unicast_address_ = "172.20.16.3";
- o.session_name_ = "Play";
- o.start_time_ = 0;
- o.end_time_ = 0;
- o.ice_lite_ = ""; // Disable this line.
- o.connection_ = "c=IN IP4 172.20.16.3"; // Session level connection.
-
- o.media_descs_.push_back(SrsMediaDesc("video"));
- SrsMediaDesc &m = o.media_descs_.at(0);
- m.port_ = 6000;
- m.protos_ = "RTP/AVP";
- m.connection_ = ""; // Disable media level connection.
- m.recvonly_ = true;
-
- m.payload_types_.push_back(SrsMediaPayloadType(96));
- SrsMediaPayloadType &ps = m.payload_types_.at(0);
- ps.encoding_name_ = "PS";
- ps.clock_rate_ = 90000;
-
- m.payload_types_.push_back(SrsMediaPayloadType(98));
- SrsMediaPayloadType &h264 = m.payload_types_.at(1);
- h264.encoding_name_ = "H264";
- h264.clock_rate_ = 90000;
-
- m.payload_types_.push_back(SrsMediaPayloadType(97));
- SrsMediaPayloadType &mpeg4 = m.payload_types_.at(2);
- mpeg4.encoding_name_ = "MPEG4";
- mpeg4.clock_rate_ = 90000;
-
- ostringstream os;
- HELPER_ASSERT_SUCCESS(o.encode(os));
- string ostr = os.str();
- string str =
- "v=0\r\n"
- "o=64010600002020000001 0 0 IN IP4 172.20.16.3\r\n"
- "s=Play\r\n"
- "c=IN IP4 172.20.16.3\r\n"
- "t=0 0\r\n"
- "m=video 6000 RTP/AVP 96 98 97\r\n"
- "a=recvonly\r\n"
- "a=rtpmap:96 PS/90000\r\n"
- "a=rtpmap:98 H264/90000\r\n"
- "a=rtpmap:97 MPEG4/90000\r\n";
- EXPECT_STREQ(ostr.c_str(), str.c_str());
-}
-
-VOID TEST(ProtocolGbSipTest, SipGb28181OfferDecode)
-{
- srs_error_t err = srs_success;
-
- string str =
- "v=0\r\n"
- "o=64010600002020000001 0 0 IN IP4 172.20.16.3\r\n"
- "s=Play\r\n"
- "c=IN IP4 172.20.16.3\r\n"
- "t=0 0\r\n"
- "m=video 6000 RTP/AVP 96 98 97\r\n"
- "a=recvonly\r\n"
- "a=rtpmap:96 PS/90000\r\n"
- "a=rtpmap:98 H264/90000\r\n"
- "a=rtpmap:97 MPEG4/90000\r\n"
- "y=0100008888\r\n";
- SrsSdp o;
- HELPER_ASSERT_SUCCESS(o.parse(str));
- EXPECT_STREQ("0", o.version_.c_str());
- EXPECT_STREQ("64010600002020000001", o.username_.c_str());
- EXPECT_STREQ("0", o.session_id_.c_str());
- EXPECT_STREQ("0", o.session_version_.c_str());
- EXPECT_STREQ("IN", o.nettype_.c_str());
- EXPECT_STREQ("IP4", o.addrtype_.c_str());
- EXPECT_STREQ("172.20.16.3", o.unicast_address_.c_str());
- EXPECT_STREQ("Play", o.session_name_.c_str());
- EXPECT_EQ(0, o.start_time_);
- EXPECT_EQ(0, o.end_time_);
-
- ASSERT_EQ((size_t)1, o.media_descs_.size());
- const SrsMediaDesc &m = o.media_descs_.at(0);
- EXPECT_STREQ("video", m.type_.c_str());
- EXPECT_EQ(6000, m.port_);
- EXPECT_STREQ("RTP/AVP", m.protos_.c_str());
- EXPECT_EQ((size_t)3, m.payload_types_.size());
- ASSERT_EQ((size_t)1, m.ssrc_infos_.size());
-
- const SrsSSRCInfo &ssrc = m.ssrc_infos_.at(0);
- EXPECT_EQ((uint32_t)100008888, ssrc.ssrc_);
- EXPECT_STREQ("0100008888", ssrc.cname_.c_str());
- EXPECT_STREQ("gb28181", ssrc.label_.c_str());
-
- const SrsMediaPayloadType &ps = m.payload_types_.at(0);
- EXPECT_EQ(96, ps.payload_type_);
- EXPECT_STREQ("PS", ps.encoding_name_.c_str());
- EXPECT_EQ(90000, ps.clock_rate_);
-
- const SrsMediaPayloadType &h264 = m.payload_types_.at(1);
- EXPECT_EQ(98, h264.payload_type_);
- EXPECT_STREQ("H264", h264.encoding_name_.c_str());
- EXPECT_EQ(90000, h264.clock_rate_);
-
- const SrsMediaPayloadType &mpeg4 = m.payload_types_.at(2);
- EXPECT_EQ(97, mpeg4.payload_type_);
- EXPECT_STREQ("MPEG4", mpeg4.encoding_name_.c_str());
- EXPECT_EQ(90000, mpeg4.clock_rate_);
-}
-
-VOID TEST(ProtocolGbSipTest, SipGb28181OfferEncode)
-{
- srs_error_t err = srs_success;
-
- SrsSdp o;
- o.version_ = "0";
- o.username_ = "64010600002020000001";
- o.session_id_ = "0";
- o.session_version_ = "0";
- o.nettype_ = "IN";
- o.addrtype_ = "IP4";
- o.unicast_address_ = "172.20.16.3";
- o.session_name_ = "Play";
- o.start_time_ = 0;
- o.end_time_ = 0;
- o.ice_lite_ = ""; // Disable this line.
- o.connection_ = "c=IN IP4 172.20.16.3"; // Session level connection.
-
- o.media_descs_.push_back(SrsMediaDesc("video"));
- SrsMediaDesc &m = o.media_descs_.at(0);
- m.port_ = 6000;
- m.protos_ = "RTP/AVP";
- m.connection_ = ""; // Disable media level connection.
- m.recvonly_ = true;
-
- m.payload_types_.push_back(SrsMediaPayloadType(96));
- SrsMediaPayloadType &ps = m.payload_types_.at(0);
- ps.encoding_name_ = "PS";
- ps.clock_rate_ = 90000;
-
- m.payload_types_.push_back(SrsMediaPayloadType(98));
- SrsMediaPayloadType &h264 = m.payload_types_.at(1);
- h264.encoding_name_ = "H264";
- h264.clock_rate_ = 90000;
-
- m.payload_types_.push_back(SrsMediaPayloadType(97));
- SrsMediaPayloadType &mpeg4 = m.payload_types_.at(2);
- mpeg4.encoding_name_ = "MPEG4";
- mpeg4.clock_rate_ = 90000;
-
- m.ssrc_infos_.push_back(SrsSSRCInfo());
- SrsSSRCInfo &ssrc = m.ssrc_infos_.at(0);
- ssrc.ssrc_ = 100008888;
- ssrc.cname_ = "0100008888";
- ssrc.label_ = "gb28181";
-
- ostringstream os;
- HELPER_ASSERT_SUCCESS(o.encode(os));
- string ostr = os.str();
- string str =
- "v=0\r\n"
- "o=64010600002020000001 0 0 IN IP4 172.20.16.3\r\n"
- "s=Play\r\n"
- "c=IN IP4 172.20.16.3\r\n"
- "t=0 0\r\n"
- "m=video 6000 RTP/AVP 96 98 97\r\n"
- "a=recvonly\r\n"
- "a=rtpmap:96 PS/90000\r\n"
- "a=rtpmap:98 H264/90000\r\n"
- "a=rtpmap:97 MPEG4/90000\r\n"
- "y=0100008888\r\n";
- EXPECT_STREQ(ostr.c_str(), str.c_str());
-}
-
-VOID TEST(ProtocolGbSipTest, GbRegisterRequest)
-{
- srs_error_t err = srs_success;
-
- // See https://www.ietf.org/rfc/rfc3261.html#section-24.1
- MockMSegmentsReader r;
- r.in_bytes.push_back("REGISTER sip:34020000002000000001@3402000000 SIP/2.0\r\n");
- r.in_bytes.push_back("Via: SIP/2.0/UDP 192.168.3.99:5060;rport;branch=z9hG4bK442003727\r\n");
- r.in_bytes.push_back("From: ;tag=307202390\r\n");
- r.in_bytes.push_back("To: \r\n");
- r.in_bytes.push_back("Call-ID: 393945367\r\n");
- r.in_bytes.push_back("CSeq: 1 REGISTER\r\n");
- r.in_bytes.push_back("Contact: \r\n");
- r.in_bytes.push_back("Max-Forwards: 70\r\n");
- r.in_bytes.push_back("User-Agent: IP Camera\r\n");
- r.in_bytes.push_back("Expires: 3600\r\n");
- r.in_bytes.push_back("Content-Length: 0\r\n");
- r.in_bytes.push_back("\r\n");
-
- SrsHttpParser p;
- HELPER_ASSERT_SUCCESS(p.initialize(HTTP_REQUEST));
-
- ISrsHttpMessage *msg = NULL;
- HELPER_ASSERT_SUCCESS(p.parse_message(&r, &msg));
- SrsUniquePtr msg_uptr(msg);
-
- EXPECT_EQ(HTTP_REGISTER, msg->method());
- EXPECT_EQ(0, msg->content_length());
-
- SrsSipMessage smsg;
- HELPER_ASSERT_SUCCESS(smsg.parse(msg));
- EXPECT_EQ(HTTP_REQUEST, smsg.type_);
- EXPECT_EQ(HTTP_REGISTER, smsg.method_);
- EXPECT_STREQ("sip:34020000002000000001@3402000000", smsg.request_uri_.c_str());
- EXPECT_STREQ("SIP/2.0/UDP 192.168.3.99:5060;rport;branch=z9hG4bK442003727", smsg.via_.c_str());
- EXPECT_STREQ("UDP", smsg.via_transport_.c_str());
- EXPECT_STREQ("192.168.3.99:5060", smsg.via_send_by_.c_str());
- EXPECT_STREQ("192.168.3.99", smsg.via_send_by_address_.c_str());
- EXPECT_EQ(5060, smsg.via_send_by_port_);
- EXPECT_STREQ("branch=z9hG4bK442003727", smsg.via_branch_.c_str());
- EXPECT_STREQ(";tag=307202390", smsg.from_.c_str());
- EXPECT_STREQ("", smsg.from_address_.c_str());
- EXPECT_STREQ("34020000001320000001", smsg.from_address_user_.c_str());
- EXPECT_STREQ("3402000000", smsg.from_address_host_.c_str());
- EXPECT_STREQ("tag=307202390", smsg.from_tag_.c_str());
- EXPECT_STREQ("", smsg.to_.c_str());
- EXPECT_STREQ("", smsg.to_address_.c_str());
- EXPECT_STREQ("34020000001320000001", smsg.to_address_user_.c_str());
- EXPECT_STREQ("3402000000", smsg.to_address_host_.c_str());
- EXPECT_STREQ("", smsg.to_tag_.c_str());
- EXPECT_STREQ("393945367", smsg.call_id_.c_str());
- EXPECT_STREQ("1 REGISTER", smsg.cseq_.c_str());
- EXPECT_EQ((uint32_t)1, smsg.cseq_number_);
- EXPECT_STREQ("", smsg.contact_.c_str());
- EXPECT_STREQ("34020000001320000001", smsg.contact_user_.c_str());
- EXPECT_STREQ("192.168.3.99:5060", smsg.contact_host_.c_str());
- EXPECT_STREQ("192.168.3.99", smsg.contact_host_address_.c_str());
- EXPECT_EQ(5060, smsg.contact_host_port_);
- EXPECT_EQ((uint32_t)70, smsg.max_forwards_);
- EXPECT_EQ((uint32_t)3600, smsg.expires_);
-
- EXPECT_STREQ(smsg.from_address_.c_str(), smsg.to_address_.c_str());
-}
-
-VOID TEST(ProtocolGbSipTest, GbRegisterResponse)
-{
- srs_error_t err = srs_success;
-
- // See https://www.ietf.org/rfc/rfc3261.html#section-24.1
- MockMSegmentsReader r;
- r.in_bytes.push_back("SIP/2.0 200 OK\r\n");
- r.in_bytes.push_back("Via: SIP/2.0/UDP 192.168.3.99:5060;rport;branch=z9hG4bK442003727\r\n");
- r.in_bytes.push_back("From: ;tag=307202390\r\n");
- r.in_bytes.push_back("To: \r\n");
- r.in_bytes.push_back("Call-ID: 393945367\r\n");
- r.in_bytes.push_back("CSeq: 1 REGISTER\r\n");
- r.in_bytes.push_back("Contact: \r\n");
- r.in_bytes.push_back("User-Agent: SRS/5.0.65(Bee)\r\n");
- r.in_bytes.push_back("Expires: 3600\r\n");
- r.in_bytes.push_back("Content-Length: 0\r\n");
- r.in_bytes.push_back("\r\n");
-
- SrsHttpParser p;
- HELPER_ASSERT_SUCCESS(p.initialize(HTTP_RESPONSE));
-
- ISrsHttpMessage *msg = NULL;
- HELPER_ASSERT_SUCCESS(p.parse_message(&r, &msg));
- SrsUniquePtr msg_uptr(msg);
-
- EXPECT_EQ(HTTP_RESPONSE, (http_parser_type)msg->message_type());
- EXPECT_EQ(200, msg->status_code());
- EXPECT_EQ(0, msg->content_length());
-
- SrsSipMessage smsg;
- HELPER_ASSERT_SUCCESS(smsg.parse(msg));
- EXPECT_EQ(HTTP_RESPONSE, smsg.type_);
- EXPECT_EQ(HTTP_STATUS_OK, smsg.status_);
- EXPECT_STREQ("SIP/2.0/UDP 192.168.3.99:5060;rport;branch=z9hG4bK442003727", smsg.via_.c_str());
- EXPECT_STREQ("UDP", smsg.via_transport_.c_str());
- EXPECT_STREQ("192.168.3.99:5060", smsg.via_send_by_.c_str());
- EXPECT_STREQ("192.168.3.99", smsg.via_send_by_address_.c_str());
- EXPECT_EQ(5060, smsg.via_send_by_port_);
- EXPECT_STREQ("branch=z9hG4bK442003727", smsg.via_branch_.c_str());
- EXPECT_STREQ(";tag=307202390", smsg.from_.c_str());
- EXPECT_STREQ("", smsg.from_address_.c_str());
- EXPECT_STREQ("34020000001320000001", smsg.from_address_user_.c_str());
- EXPECT_STREQ("3402000000", smsg.from_address_host_.c_str());
- EXPECT_STREQ("tag=307202390", smsg.from_tag_.c_str());
- EXPECT_STREQ("", smsg.to_.c_str());
- EXPECT_STREQ("", smsg.to_address_.c_str());
- EXPECT_STREQ("34020000001320000001", smsg.to_address_user_.c_str());
- EXPECT_STREQ("3402000000", smsg.to_address_host_.c_str());
- EXPECT_STREQ("", smsg.to_tag_.c_str());
- EXPECT_STREQ("393945367", smsg.call_id_.c_str());
- EXPECT_STREQ("1 REGISTER", smsg.cseq_.c_str());
- EXPECT_EQ((uint32_t)1, smsg.cseq_number_);
- EXPECT_STREQ("", smsg.contact_.c_str());
- EXPECT_STREQ("34020000001320000001", smsg.contact_user_.c_str());
- EXPECT_STREQ("192.168.3.99:5060", smsg.contact_host_.c_str());
- EXPECT_STREQ("192.168.3.99", smsg.contact_host_address_.c_str());
- EXPECT_EQ(5060, smsg.contact_host_port_);
- EXPECT_EQ((uint32_t)3600, smsg.expires_);
-}
-
-VOID TEST(ProtocolGbSipTest, GbInviteRequest)
-{
- srs_error_t err = srs_success;
-
- string sdp =
- "v=0\r\n"
- "o=34020000001320000001 0 0 IN IP4 192.168.3.82\r\n"
- "s=Play\r\n"
- "c=IN IP4 192.168.3.82\r\n"
- "t=0 0\r\n"
- "m=video 9000 TCP/RTP/AVP 96\r\n"
- "a=recvonly\r\n"
- "a=rtpmap:96 PS/90000\r\n"
- "y=0200007585\r\n";
-
- MockMSegmentsReader r;
- r.in_bytes.push_back("INVITE sip:34020000001320000001@3402000000 SIP/2.0\r\n");
- r.in_bytes.push_back("Via: SIP/2.0/TCP 192.168.3.82:5060;rport;branch=z9hG4bK0l31rx\r\n");
- r.in_bytes.push_back("From: ;tag=SRSk1er282t\r\n");
- r.in_bytes.push_back("To: \r\n");
- r.in_bytes.push_back("CSeq: 854 INVITE\r\n");
- r.in_bytes.push_back("Call-ID: 854k7337207yxpfj\r\n");
- r.in_bytes.push_back("Content-Type: application/sdp\r\n");
- r.in_bytes.push_back("Contact: \r\n");
- r.in_bytes.push_back("Max-Forwards: 70\r\n");
- r.in_bytes.push_back("Subject: 34020000001320000001:0200007585,34020000002000000001:0\r\n");
- r.in_bytes.push_back("Server: SRS/5.0.65(Bee)\r\n");
- r.in_bytes.push_back(srs_fmt_sprintf("Content-Length: %d\r\n", sdp.length()));
- r.in_bytes.push_back("\r\n");
- r.in_bytes.push_back(sdp);
-
- SrsHttpParser p;
- HELPER_ASSERT_SUCCESS(p.initialize(HTTP_BOTH));
-
- ISrsHttpMessage *msg = NULL;
- HELPER_ASSERT_SUCCESS(p.parse_message(&r, &msg));
- SrsUniquePtr msg_uptr(msg);
-
- SrsSipMessage smsg;
- HELPER_ASSERT_SUCCESS(smsg.parse(msg));
- EXPECT_EQ(HTTP_REQUEST, smsg.type_);
- EXPECT_EQ(HTTP_INVITE, smsg.method_);
- EXPECT_STREQ("sip:34020000001320000001@3402000000", smsg.request_uri_.c_str());
- EXPECT_STREQ("SIP/2.0/TCP 192.168.3.82:5060;rport;branch=z9hG4bK0l31rx", smsg.via_.c_str());
- EXPECT_STREQ("TCP", smsg.via_transport_.c_str());
- EXPECT_STREQ("192.168.3.82:5060", smsg.via_send_by_.c_str());
- EXPECT_STREQ("192.168.3.82", smsg.via_send_by_address_.c_str());
- EXPECT_EQ(5060, smsg.via_send_by_port_);
- EXPECT_STREQ("branch=z9hG4bK0l31rx", smsg.via_branch_.c_str());
- EXPECT_STREQ(";tag=SRSk1er282t", smsg.from_.c_str());
- EXPECT_STREQ("", smsg.from_address_.c_str());
- EXPECT_STREQ("34020000002000000001", smsg.from_address_user_.c_str());
- EXPECT_STREQ("3402000000", smsg.from_address_host_.c_str());
- EXPECT_STREQ("tag=SRSk1er282t", smsg.from_tag_.c_str());
- EXPECT_STREQ("", smsg.to_.c_str());
- EXPECT_STREQ("", smsg.to_address_.c_str());
- EXPECT_STREQ("34020000001320000001", smsg.to_address_user_.c_str());
- EXPECT_STREQ("3402000000", smsg.to_address_host_.c_str());
- EXPECT_STREQ("", smsg.to_tag_.c_str());
- EXPECT_STREQ("854 INVITE", smsg.cseq_.c_str());
- EXPECT_EQ((uint32_t)854, smsg.cseq_number_);
- EXPECT_STREQ("854k7337207yxpfj", smsg.call_id_.c_str());
- EXPECT_STREQ("", smsg.contact_.c_str());
- EXPECT_STREQ("34020000002000000001", smsg.contact_user_.c_str());
- EXPECT_STREQ("3402000000", smsg.contact_host_.c_str());
- EXPECT_STREQ("3402000000", smsg.contact_host_address_.c_str());
- EXPECT_EQ(5060, smsg.contact_host_port_);
- EXPECT_EQ((uint32_t)70, smsg.max_forwards_);
- EXPECT_STREQ("34020000001320000001:0200007585,34020000002000000001:0", smsg.subject_.c_str());
- EXPECT_STREQ(sdp.c_str(), smsg.body_.c_str());
-}
-
-VOID TEST(ProtocolGbSipTest, GbTringResponse)
-{
- srs_error_t err = srs_success;
-
- // See https://www.ietf.org/rfc/rfc3261.html#section-24.1
- MockMSegmentsReader r;
- r.in_bytes.push_back("SIP/2.0 100 Trying\r\n");
- r.in_bytes.push_back("Via: SIP/2.0/TCP 192.168.3.82:5060;rport=5060;branch=z9hG4bK0l31rx\r\n");
- r.in_bytes.push_back("From: ;tag=SRSk1er282t\r\n");
- r.in_bytes.push_back("To: \r\n");
- r.in_bytes.push_back("Call-ID: 854k7337207yxpfj\r\n");
- r.in_bytes.push_back("CSeq: 854 INVITE\r\n");
- r.in_bytes.push_back("User-Agent: IP Camera\r\n");
- r.in_bytes.push_back("Content-Length: 0\r\n");
- r.in_bytes.push_back("\r\n");
-
- SrsHttpParser p;
- HELPER_ASSERT_SUCCESS(p.initialize(HTTP_RESPONSE));
-
- ISrsHttpMessage *msg = NULL;
- HELPER_ASSERT_SUCCESS(p.parse_message(&r, &msg));
- SrsUniquePtr msg_uptr(msg);
-
- SrsSipMessage smsg;
- HELPER_ASSERT_SUCCESS(smsg.parse(msg));
- EXPECT_EQ(HTTP_RESPONSE, smsg.type_);
- EXPECT_EQ(100, smsg.status_);
- EXPECT_STREQ("SIP/2.0/TCP 192.168.3.82:5060;rport=5060;branch=z9hG4bK0l31rx", smsg.via_.c_str());
- EXPECT_STREQ("TCP", smsg.via_transport_.c_str());
- EXPECT_STREQ("192.168.3.82:5060", smsg.via_send_by_.c_str());
- EXPECT_STREQ("192.168.3.82", smsg.via_send_by_address_.c_str());
- EXPECT_EQ(5060, smsg.via_send_by_port_);
- EXPECT_STREQ("branch=z9hG4bK0l31rx", smsg.via_branch_.c_str());
- EXPECT_STREQ(";tag=SRSk1er282t", smsg.from_.c_str());
- EXPECT_STREQ("", smsg.from_address_.c_str());
- EXPECT_STREQ("34020000002000000001", smsg.from_address_user_.c_str());
- EXPECT_STREQ("3402000000", smsg.from_address_host_.c_str());
- EXPECT_STREQ("tag=SRSk1er282t", smsg.from_tag_.c_str());
- EXPECT_STREQ("", smsg.to_.c_str());
- EXPECT_STREQ("", smsg.to_address_.c_str());
- EXPECT_STREQ("34020000001320000001", smsg.to_address_user_.c_str());
- EXPECT_STREQ("3402000000", smsg.to_address_host_.c_str());
- EXPECT_STREQ("", smsg.to_tag_.c_str());
- EXPECT_STREQ("854 INVITE", smsg.cseq_.c_str());
- EXPECT_EQ((uint32_t)854, smsg.cseq_number_);
- EXPECT_STREQ("854k7337207yxpfj", smsg.call_id_.c_str());
- EXPECT_EQ((size_t)0, smsg.body_.length());
-}
-
-VOID TEST(ProtocolGbSipTest, Gb200OkResponse)
-{
- srs_error_t err = srs_success;
-
- string sdp =
- "v=0\r\n"
- "o=34020000001320000001 1941 1941 IN IP4 192.168.3.99\r\n"
- "s=Play\r\n"
- "c=IN IP4 192.168.3.99\r\n"
- "t=0 0\r\n"
- "m=video 15060 TCP/RTP/AVP 96\r\n"
- "a=setup:active\r\n"
- "a=sendonly\r\n"
- "a=rtpmap:96 PS/90000\r\n"
- "a=filesize:0\r\n"
- "y=0200007585\r\n";
-
- // See https://www.ietf.org/rfc/rfc3261.html#section-24.1
- MockMSegmentsReader r;
- r.in_bytes.push_back("SIP/2.0 200 OK\r\n");
- r.in_bytes.push_back("Via: SIP/2.0/TCP 192.168.3.82:5060;rport=5060;branch=z9hG4bK0l31rx\r\n");
- r.in_bytes.push_back("From: ;tag=SRSk1er282t\r\n");
- r.in_bytes.push_back("To: \r\n");
- r.in_bytes.push_back("Call-ID: 854k7337207yxpfj\r\n");
- r.in_bytes.push_back("CSeq: 854 INVITE\r\n");
- r.in_bytes.push_back("Contact: \r\n");
- r.in_bytes.push_back("Content-Type: application/sdp\r\n");
- r.in_bytes.push_back("User-Agent: IP Camera\r\n");
- r.in_bytes.push_back(srs_fmt_sprintf("Content-Length: %d\r\n", sdp.length()));
- r.in_bytes.push_back("\r\n");
- r.in_bytes.push_back(sdp);
-
- SrsHttpParser p;
- HELPER_ASSERT_SUCCESS(p.initialize(HTTP_RESPONSE));
-
- ISrsHttpMessage *msg = NULL;
- HELPER_ASSERT_SUCCESS(p.parse_message(&r, &msg));
- SrsUniquePtr msg_uptr(msg);
-
- SrsSipMessage smsg;
- HELPER_ASSERT_SUCCESS(smsg.parse(msg));
- EXPECT_EQ(HTTP_RESPONSE, smsg.type_);
- EXPECT_EQ(200, smsg.status_);
- EXPECT_STREQ("SIP/2.0/TCP 192.168.3.82:5060;rport=5060;branch=z9hG4bK0l31rx", smsg.via_.c_str());
- EXPECT_STREQ("TCP", smsg.via_transport_.c_str());
- EXPECT_STREQ("192.168.3.82:5060", smsg.via_send_by_.c_str());
- EXPECT_STREQ("192.168.3.82", smsg.via_send_by_address_.c_str());
- EXPECT_EQ(5060, smsg.via_send_by_port_);
- EXPECT_STREQ("branch=z9hG4bK0l31rx", smsg.via_branch_.c_str());
- EXPECT_STREQ(";tag=SRSk1er282t", smsg.from_.c_str());
- EXPECT_STREQ("", smsg.from_address_.c_str());
- EXPECT_STREQ("34020000002000000001", smsg.from_address_user_.c_str());
- EXPECT_STREQ("3402000000", smsg.from_address_host_.c_str());
- EXPECT_STREQ("tag=SRSk1er282t", smsg.from_tag_.c_str());
- EXPECT_STREQ("", smsg.to_.c_str());
- EXPECT_STREQ("", smsg.to_address_.c_str());
- EXPECT_STREQ("34020000001320000001", smsg.to_address_user_.c_str());
- EXPECT_STREQ("3402000000", smsg.to_address_host_.c_str());
- EXPECT_STREQ("", smsg.to_tag_.c_str());
- EXPECT_STREQ("854 INVITE", smsg.cseq_.c_str());
- EXPECT_EQ((uint32_t)854, smsg.cseq_number_);
- EXPECT_STREQ("854k7337207yxpfj", smsg.call_id_.c_str());
- EXPECT_STREQ("", smsg.contact_.c_str());
- EXPECT_STREQ("34020000001320000001", smsg.contact_user_.c_str());
- EXPECT_STREQ("192.168.3.99:5060", smsg.contact_host_.c_str());
- EXPECT_STREQ("192.168.3.99", smsg.contact_host_address_.c_str());
- EXPECT_EQ(5060, smsg.contact_host_port_);
- EXPECT_STREQ(sdp.c_str(), smsg.body_.c_str());
-}
-
-VOID TEST(ProtocolGbSipTest, GbAckRequest)
-{
- srs_error_t err = srs_success;
-
- MockMSegmentsReader r;
- r.in_bytes.push_back("ACK sip:34020000001320000001@3402000000 SIP/2.0\r\n");
- r.in_bytes.push_back("Via: SIP/2.0/TCP 192.168.3.82:5060;rport;branch=z9hG4bK9k30b6\r\n");
- r.in_bytes.push_back("From: ;tag=SRSk1er282t\r\n");
- r.in_bytes.push_back("To: \r\n");
- r.in_bytes.push_back("CSeq: 854 ACK\r\n");
- r.in_bytes.push_back("Call-ID: 854k7337207yxpfj\r\n");
- r.in_bytes.push_back("Max-Forwards: 70\r\n");
- r.in_bytes.push_back("Server: SRS/5.0.65(Bee)\r\n");
- r.in_bytes.push_back("Content-Length: 0\r\n");
- r.in_bytes.push_back("\r\n");
-
- SrsHttpParser p;
- HELPER_ASSERT_SUCCESS(p.initialize(HTTP_BOTH));
-
- ISrsHttpMessage *msg = NULL;
- HELPER_ASSERT_SUCCESS(p.parse_message(&r, &msg));
- SrsUniquePtr msg_uptr(msg);
-
- SrsSipMessage smsg;
- HELPER_ASSERT_SUCCESS(smsg.parse(msg));
- EXPECT_EQ(HTTP_REQUEST, smsg.type_);
- EXPECT_EQ(HTTP_ACK, smsg.method_);
- EXPECT_STREQ("sip:34020000001320000001@3402000000", smsg.request_uri_.c_str());
- EXPECT_STREQ("SIP/2.0/TCP 192.168.3.82:5060;rport;branch=z9hG4bK9k30b6", smsg.via_.c_str());
- EXPECT_STREQ("TCP", smsg.via_transport_.c_str());
- EXPECT_STREQ("192.168.3.82:5060", smsg.via_send_by_.c_str());
- EXPECT_STREQ("192.168.3.82", smsg.via_send_by_address_.c_str());
- EXPECT_EQ(5060, smsg.via_send_by_port_);
- EXPECT_STREQ("branch=z9hG4bK9k30b6", smsg.via_branch_.c_str());
- EXPECT_STREQ(";tag=SRSk1er282t", smsg.from_.c_str());
- EXPECT_STREQ("", smsg.from_address_.c_str());
- EXPECT_STREQ("34020000002000000001", smsg.from_address_user_.c_str());
- EXPECT_STREQ("3402000000", smsg.from_address_host_.c_str());
- EXPECT_STREQ("tag=SRSk1er282t", smsg.from_tag_.c_str());
- EXPECT_STREQ("", smsg.to_.c_str());
- EXPECT_STREQ("", smsg.to_address_.c_str());
- EXPECT_STREQ("34020000001320000001", smsg.to_address_user_.c_str());
- EXPECT_STREQ("3402000000", smsg.to_address_host_.c_str());
- EXPECT_STREQ("", smsg.to_tag_.c_str());
- EXPECT_STREQ("854 ACK", smsg.cseq_.c_str());
- EXPECT_EQ((uint32_t)854, smsg.cseq_number_);
- EXPECT_STREQ("854k7337207yxpfj", smsg.call_id_.c_str());
- EXPECT_EQ((uint32_t)70, smsg.max_forwards_);
- EXPECT_EQ((size_t)0, smsg.body_.length());
-}
-
VOID TEST(KernelPSTest, PsPacketDecodePartialPesHeader)
{
srs_error_t err = srs_success;