Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bugfix - Fix the issue of unable to connect with the platform using --with-gb28181 and some minor bugs #2109

Merged
merged 23 commits into from
Jan 6, 2021
Merged
Show file tree
Hide file tree
Changes from 17 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
88769fb
1-新增srs_string_split2函数,该函数支持空串也能按照原有顺序进行切分并放入数组
Dec 17, 2020
a8fbedf
Merge remote-tracking branch 'my_origin/4.0release' of https://github…
Dec 17, 2020
5d8b275
1-修复停用rtp多路复用参数(invite_port_fixed)不起作用bug
Dec 22, 2020
2211767
bugfix: 当srs发送invite时会指定一个ssrc作为流媒体序列号,但有些平台发流时并不使用这个作为ssrc,而是自己新生成一个…
Dec 23, 2020
4afed82
Update push.gb28181.conf
xbpeng121 Dec 24, 2020
c30a69b
bugfix,在取得muxer时需要更新。之前写反了
Dec 31, 2020
0660c69
Merge branch 'develop' into 4.0release
xbpeng121 Jan 4, 2021
e68da89
Merge branch 'develop' into 4.0release
Jan 4, 2021
9c838a0
解决冲突时,优先选择原有代码(还原选择develop的代码)
Jan 4, 2021
5b6f1a5
解决冲突时,优先选择原有代码(还原选择develop的代码)
Jan 4, 2021
c9a7233
解决冲突时,优先选择原有代码(还原选择develop的代码)
Jan 5, 2021
d61f660
解决冲突时,优先选择原有代码(还原选择develop的代码)
Jan 5, 2021
705a3be
修改sdp_map相同属性的连接符
Jan 5, 2021
36a3abc
解决冲突时,优先选择原有代码(还原选择develop的代码)
Jan 5, 2021
fd8228e
修改sdp_map相同属性的连接符
Jan 5, 2021
e37fd66
解决冲突时,优先选择原有代码(还原选择develop的代码)
Jan 5, 2021
f991097
解决冲突时,优先选择原有代码(还原选择develop的代码)
Jan 5, 2021
73d289a
回退原来代码
Jan 5, 2021
33e3611
删除parse_sdp存储至map相关代码
Jan 5, 2021
71d2b40
格式恢复
Jan 5, 2021
0f43d48
格式恢复
Jan 5, 2021
053fcc0
恢复格式
Jan 5, 2021
b285d7e
srs_string_split() 函数的bugfix
Jan 6, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 25 additions & 36 deletions trunk/src/app/srs_app_gb28181.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -306,35 +306,7 @@ srs_error_t SrsGb28181PsRtpProcessor::on_rtp_packet(const sockaddr* from, const
if(key != cache_ps_rtp_packet.end())
{
SrsGb28181RtmpMuxer* muxer = NULL;
//First, search according to the channel_id. Otherwise, search according to the SSRC.
//Some channel_id are created by RTP pool, which are different ports.
//No channel_id are created by multiplexing ports, which are the same port
if (!channel_id.empty()){
muxer = _srs_gb28181->fetch_rtmpmuxer(channel_id);
}else {
muxer = _srs_gb28181->fetch_rtmpmuxer_by_ssrc(pkt.ssrc);
}

//auto crate channel
if (!muxer && config->auto_create_channel){
//auto create channel generated id
std::stringstream ss, ss1;
ss << "chid" << pkt.ssrc;
std::string tmp_id = ss.str();

SrsGb28181StreamChannel channel;
channel.set_channel_id(tmp_id);
channel.set_port_mode(RTP_PORT_MODE_FIXED);
channel.set_ssrc(pkt.ssrc);

srs_error_t err2 = srs_success;
if ((err2 = _srs_gb28181->create_stream_channel(&channel)) != srs_success){
srs_warn("gb28181: RtpProcessor create stream channel error %s", srs_error_desc(err2).c_str());
srs_error_reset(err2);
};

muxer = _srs_gb28181->fetch_rtmpmuxer(tmp_id);
}
muxer = fetch_rtmpmuxer(channel_id,pkt.ssrc);
xbpeng121 marked this conversation as resolved.
Show resolved Hide resolved

if (muxer){
//TODO: fixme: the same device uses the same SSRC to send with different local ports
Expand All @@ -360,7 +332,7 @@ srs_error_t SrsGb28181PsRtpProcessor::on_rtp_packet(const sockaddr* from, const
return err;
}

SrsGb28181RtmpMuxer* SrsGb28181PsRtpProcessor::create_rtmpmuxer(std::string channel_id, uint32_t ssrc)
SrsGb28181RtmpMuxer* SrsGb28181PsRtpProcessor::fetch_rtmpmuxer(std::string channel_id, uint32_t ssrc)
{
if(true){
SrsGb28181RtmpMuxer* muxer = NULL;
Expand All @@ -382,7 +354,13 @@ SrsGb28181RtmpMuxer* SrsGb28181PsRtpProcessor::create_rtmpmuxer(std::string chan

SrsGb28181StreamChannel channel;
channel.set_channel_id(tmp_id);
channel.set_port_mode(RTP_PORT_MODE_FIXED);
// channel.set_port_mode(RTP_PORT_MODE_FIXED);
if (!config->sip_invite_port_fixed) {
channel.set_port_mode(RTP_PORT_MODE_RANDOM);
}else
{
channel.set_port_mode(RTP_PORT_MODE_FIXED);
}
channel.set_ssrc(ssrc);

srs_error_t err2 = srs_success;
Expand Down Expand Up @@ -471,7 +449,7 @@ srs_error_t SrsGb28181PsRtpProcessor::on_rtp_packet_jitter(const sockaddr* from,
);
}

SrsGb28181RtmpMuxer *muxer = create_rtmpmuxer(channel_id, pkt->ssrc);
SrsGb28181RtmpMuxer *muxer = fetch_rtmpmuxer(channel_id, pkt->ssrc);
if (muxer){
rtmpmuxer_enqueue_data(muxer, pkt->ssrc, peer_port, address_string, pkt);
}
Expand Down Expand Up @@ -2367,10 +2345,12 @@ void SrsGb28181Manger::update_rtmpmuxer_to_newssrc_by_id(std::string id, uint32_
SrsGb28181RtmpMuxer* muxer = NULL;

if (rtmpmuxers.find(id) == rtmpmuxers.end()) {
srs_warn("gb28181: at update_rtmpmuxer_to_newssrc_by_id() client_id not found. client_id=%s",id.c_str());
return;
}

muxer = rtmpmuxers[id];
//TODO: find out whether muxer->get_channel().set_ssrc(new_ssrc) is different with the under codes
winlinvip marked this conversation as resolved.
Show resolved Hide resolved
SrsGb28181StreamChannel mc = muxer->get_channel();
uint32_t old_ssrc = mc.get_ssrc();
if (old_ssrc == ssrc) {
Expand All @@ -2382,6 +2362,7 @@ void SrsGb28181Manger::update_rtmpmuxer_to_newssrc_by_id(std::string id, uint32_
mc.set_ssrc(ssrc);
muxer->copy_channel(&mc);
rtmpmuxer_map_by_ssrc(muxer, ssrc);
srs_trace("gb28181: update_rtmpmuxer_to_newssrc_by_id success. client_id=%s, new_ssrc=%#x, old_ssrc=%#x",id.c_str(),ssrc,old_ssrc);
xbpeng121 marked this conversation as resolved.
Show resolved Hide resolved
}

SrsGb28181RtmpMuxer* SrsGb28181Manger::fetch_rtmpmuxer_by_ssrc(uint32_t ssrc)
Expand Down Expand Up @@ -2459,10 +2440,12 @@ srs_error_t SrsGb28181Manger::start_ps_rtp_listen(std::string id, int port)
return srs_error_wrap(err, "start rtp listen port is mux port");
}

map<std::string, SrsGb28181RtmpMuxer*>::iterator key = rtmpmuxers.find(id);
if (key == rtmpmuxers.end()){
return srs_error_wrap(err, "start rtp listen port rtmp muxer is null");
}
/* delete by xbpeng 20201222 should not check rtmpmuxers, becasue it always not find*/
xbpeng121 marked this conversation as resolved.
Show resolved Hide resolved
// map<std::string, SrsGb28181RtmpMuxer*>::iterator key = rtmpmuxers.find(id);
// if (key == rtmpmuxers.end()){
// srs_warn("start rtp listen port rtmp muxer is null. id=%s,port=%d", id.c_str(),port);
// return srs_error_wrap(err, "start rtp listen port rtmp muxer is null");
// }

if (!config->rtp_mux_tcp_enable) {
if (rtp_pool.find(port) == rtp_pool.end())
Expand Down Expand Up @@ -2703,6 +2686,12 @@ srs_error_t SrsGb28181Manger::notify_sip_invite(std::string id, std::string ip,
//channel not exist
SrsGb28181StreamChannel channel;
channel.set_channel_id(key);
if (!this->config->sip_invite_port_fixed) {
channel.set_port_mode(RTP_PORT_MODE_RANDOM);
}else
{
channel.set_port_mode(RTP_PORT_MODE_FIXED);
}
err = create_stream_channel(&channel);
if (err != srs_success){
return err;
Expand Down
5 changes: 3 additions & 2 deletions trunk/src/app/srs_app_gb28181.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ class SrsGb28181Conn;
class SrsGb28181Caster;

//ps rtp header packet parse
//ps doc:
xbpeng121 marked this conversation as resolved.
Show resolved Hide resolved
class SrsPsRtpPacket: public SrsRtpPacket
{
public:
Expand Down Expand Up @@ -160,7 +161,7 @@ class SrsGb28181PsRtpProcessor: public ISrsUdpHandler
SrsPithyPrint* pprint;
SrsGb28181Config* config;
std::map<std::string, SrsPsRtpPacket*> cache_ps_rtp_packet;
std::map<std::string, SrsPsRtpPacket*> pre_packet;
std::map<std::string, SrsPsRtpPacket*> pre_packet;
std::string channel_id;
bool auto_create_channel;
public:
Expand All @@ -170,7 +171,7 @@ class SrsGb28181PsRtpProcessor: public ISrsUdpHandler
bool can_send_ps_av_packet();
void dispose();
void clear_pre_packet();
SrsGb28181RtmpMuxer* create_rtmpmuxer(std::string channel_id, uint32_t ssrc);
SrsGb28181RtmpMuxer* fetch_rtmpmuxer(std::string channel_id, uint32_t ssrc);
srs_error_t rtmpmuxer_enqueue_data(SrsGb28181RtmpMuxer *muxer, uint32_t ssrc,
int peer_port, std::string address_string, SrsPsRtpPacket *pkt);
// Interface ISrsUdpHandler
Expand Down
7 changes: 5 additions & 2 deletions trunk/src/app/srs_app_gb28181_sip.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,10 +68,11 @@ std::string srs_get_sip_session_status_str(SrsGb28181SipSessionStatusType status
SrsGb28181Device::SrsGb28181Device()
{
device_id = "";
device_name = "";
invite_status = SrsGb28181SipSessionUnkonw;
invite_time = 0;
device_status = "";
device_name = "";
xbpeng121 marked this conversation as resolved.
Show resolved Hide resolved


}

Expand Down Expand Up @@ -286,7 +287,7 @@ srs_error_t SrsGb28181SipSession::do_cycle()
invite_duration = 0;
}

srs_trace("gb28181: sip session=%s device=%s status(%s, %s), duration(%u)",
srs_info("gb28181: sip session=%s device=%s status(%s, %s), duration(%u)",
winlinvip marked this conversation as resolved.
Show resolved Hide resolved
_session_id.c_str(), chid.c_str(), device->device_status.c_str(),
srs_get_sip_session_status_str(device->invite_status).c_str(),
(invite_duration / SRS_UTIME_SECONDS));
Expand Down Expand Up @@ -559,6 +560,7 @@ srs_error_t SrsGb28181SipService::on_udp_sip(string peer_ip, int peer_port,

//reponse status
if (req->cmdtype == SrsSipCmdRequest){
send_status(req, from, fromlen);
xbpeng121 marked this conversation as resolved.
Show resolved Hide resolved
send_status(req, from, fromlen);
sip_session->set_alive_status(SrsGb28181SipSessionAliveOk);
sip_session->set_alive_time(srs_get_system_time());
Expand Down Expand Up @@ -632,6 +634,7 @@ srs_error_t SrsGb28181SipService::on_udp_sip(string peer_ip, int peer_port,
device->req_inivate.copy(req);
device->invite_time = srs_get_system_time();
}

}else if (req->status == "100") {
//send_ack(req, from, fromlen);
SrsGb28181Device *device = sip_session->get_device_info(req->sip_auth_id);
Expand Down
2 changes: 1 addition & 1 deletion trunk/src/app/srs_app_gb28181_sip.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,8 @@ class SrsGb28181Device
virtual ~SrsGb28181Device();
public:
std::string device_id;
std::string device_name;
std::string device_status;
std::string device_name;
xbpeng121 marked this conversation as resolved.
Show resolved Hide resolved
SrsGb28181SipSessionStatusType invite_status;
srs_utime_t invite_time;
SrsSipRequest req_inivate;
Expand Down
41 changes: 16 additions & 25 deletions trunk/src/kernel/srs_kernel_utility.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -480,31 +480,22 @@ int srs_string_count(string str, string flag)
return nn;
}

vector<string> srs_string_split(string str, string flag)
{
vector<string> arr;

if (flag.empty()) {
arr.push_back(str);
return arr;
}

size_t pos;
string s = str;

while ((pos = s.find(flag)) != string::npos) {
if (pos != 0) {
arr.push_back(s.substr(0, pos));
}
s = s.substr(pos + flag.length());
}

if (!s.empty()) {
arr.push_back(s);
}

return arr;
}

vector<string> srs_string_split(string s, string seperator) {
winlinvip marked this conversation as resolved.
Show resolved Hide resolved
vector<string> result;
unsigned int posBegin = 0;
winlinvip marked this conversation as resolved.
Show resolved Hide resolved
size_t posSeperator = s.find(seperator);

while (posSeperator != string::npos) {
result.push_back(s.substr(posBegin, posSeperator - posBegin));
posBegin = posSeperator + seperator.size(); // next byte of seperator
winlinvip marked this conversation as resolved.
Show resolved Hide resolved
posSeperator = s.find(seperator, posBegin);
}
if (posBegin != s.length()) // push the last element
result.push_back(s.substr(posBegin));

return result;
}

string srs_string_min_match(string str, vector<string> flags)
{
Expand Down
2 changes: 1 addition & 1 deletion trunk/src/kernel/srs_kernel_utility.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ extern int srs_string_count(std::string str, std::string flag);
// Find the min match in str for flags.
extern std::string srs_string_min_match(std::string str, std::vector<std::string> flags);
// Split the string by flag to array.
extern std::vector<std::string> srs_string_split(std::string str, std::string flag);
extern std::vector<std::string> srs_string_split(std::string s, std::string seperator);
extern std::vector<std::string> srs_string_split(std::string str, std::vector<std::string> flags);

// Compare the memory in bytes.
Expand Down
2 changes: 2 additions & 0 deletions trunk/src/protocol/srs_rtsp_stack.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,8 @@ class ISrsProtocolReadWriter;
// RTSP-Version
#define SRS_RTSP_VERSION "RTSP/1.0"

// GB28181 sdp
#define SRS_GB_SDP_MAP_CONNETOR "`"
// The rtsp sdp parse state.
enum SrsRtspSdpState
{
Expand Down
51 changes: 37 additions & 14 deletions trunk/src/protocol/srs_sip_stack.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,7 @@ void SrsSipRequest::copy(SrsSipRequest* src)
chid = src->chid;

xml_body_map = src->xml_body_map;
sdp_body_map = src->sdp_body_map;
device_list_map = src->device_list_map;

from_realm = src->from_realm;
Expand Down Expand Up @@ -548,6 +549,30 @@ srs_error_t SrsSipStack::parse_xml(std::string xml_msg, std::map<std::string, st
return srs_success;
}

srs_error_t SrsSipStack::parse_sdp(std::string sdp_msg, std::map<std::string, std::string> &json_map){
winlinvip marked this conversation as resolved.
Show resolved Hide resolved
/* SDP描述由许多文本行组成,文本行的格式为<类型>=<值>,<类型>是一个字母,<值>是结构化的文本串,其格式依<类型>而定。
* <type>=<value>[CRLF]
* json_map[type]=value
* json_map[type]=value1`value2`value3 if type is the same
*/
srs_error_t err = srs_success;
std::vector<string> pairs = srs_string_split(sdp_msg, SRS_RTSP_CRLF);
std::vector<string>::iterator it;
for (it = pairs.begin(); it != pairs.end(); ++it) {
std::vector<string> type_value = srs_string_split(*it, "=");
std::string mkey = type_value.at(0);
std::string mvalue = type_value.at(1);
//set map value
if (!mkey.empty()){
if (json_map.find(mkey) == json_map.end()){
json_map[mkey] = mvalue;
}else{
json_map[mkey] = json_map[mkey] + SRS_GB_SDP_MAP_CONNETOR +mvalue;
}
}
}
return err;
}
srs_error_t SrsSipStack::do_parse_request(SrsSipRequest* req, const char* recv_msg)
{
srs_error_t err = srs_success;
Expand All @@ -572,7 +597,7 @@ srs_error_t SrsSipStack::do_parse_request(SrsSipRequest* req, const char* recv_m
srs_info("sip: header=%s\n", header.c_str());
srs_info("sip: body=%s\n", body.c_str());

// parse one by one.
// parse header one by one.
char* start = (char*)header.c_str();
char* end = start + header.size();
char* p = start;
Expand Down Expand Up @@ -763,29 +788,27 @@ srs_error_t SrsSipStack::do_parse_request(SrsSipRequest* req, const char* recv_m
srs_trace("sip: Notify cmdtype=%s not processed", cmdtype.c_str());
}
}// end if(req->xml_body_map)
}//end if (!strcasecmp)
else if (!strcasecmp(req->content_type.c_str(),"application/sdp")) {
std::vector<std::string> sdp_lines = srs_string_split(body.c_str(), SRS_RTSP_CRLF);
for(int i=0 ; i< (int)sdp_lines.size(); i++){
if (!strncasecmp(sdp_lines.at(i).c_str(), "y=", 2)) {
string yline = sdp_lines.at(i);
string ssrc = yline.substr(2);
req->y_ssrc = strtoul(ssrc.c_str(), NULL, 10);
srs_trace("gb28181: ssrc in y line is %u:%x", req->y_ssrc, req->y_ssrc);
break;
}

}//end if(application/manscdp+xml)
//Content-Type: Application/SDP
else if (!strcasecmp(req->content_type.c_str(),"application/sdp")){
//sdp to map
if ((err = parse_sdp(body, req->sdp_body_map)) != srs_success) {
return srs_error_wrap(err, "sip parse sdp");
}
req->y_ssrc = strtoul(srs_string_split(req->sdp_body_map["y"],SRS_GB_SDP_MAP_CONNETOR).at(0).c_str(), NULL, 10);
srs_trace("gb28181: ssrc in y line is %u:%x", req->y_ssrc, req->y_ssrc);
}

srs_info("sip: method=%s uri=%s version=%s cmdtype=%s",
req->method.c_str(), req->uri.c_str(), req->version.c_str(), req->get_cmdtype_str().c_str());
srs_info("sip: method=%s uri=%s version=%s cmdtype=%s",req->method.c_str(), req->uri.c_str(), req->version.c_str(), req->get_cmdtype_str().c_str());
srs_info("via=%s", req->via.c_str());
srs_info("via_branch=%s", req->branch.c_str());
srs_info("cseq=%d", req->seq);
srs_info("contact=%s", req->contact.c_str());
srs_info("from=%s", req->from.c_str());
srs_info("to=%s", req->to.c_str());
srs_info("callid=%s", req->call_id.c_str());
srs_info("ssrc=%s", req->sdp_body_map["y"].c_str());
srs_info("status=%s", req->status.c_str());
srs_info("from_tag=%s", req->from_tag.c_str());
srs_info("to_tag=%s", req->to_tag.c_str());
Expand Down
4 changes: 4 additions & 0 deletions trunk/src/protocol/srs_sip_stack.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,8 @@ class SrsSipRequest
std::string chid;

std::map<std::string, std::string> xml_body_map;
std::map<std::string, std::string> sdp_body_map;

std::map<std::string, std::string> device_list_map;
// add an item_list, you can do a lot of other things
// used by DeviceList, Alarmstatus, RecordList in "GB/T 28181—2016"
Expand Down Expand Up @@ -157,7 +159,9 @@ class SrsSipStack
virtual srs_error_t parse_request(SrsSipRequest** preq, const char *recv_msg, int nb_buf);
protected:
virtual srs_error_t do_parse_request(SrsSipRequest* req, const char *recv_msg);

virtual srs_error_t parse_xml(std::string xml_msg, std::map<std::string, std::string> &json_map, std::vector<std::map<std::string, std::string> > &item_list);
virtual srs_error_t parse_sdp(std::string sdp_msg, std::map<std::string, std::string> &json_map);

private:
//response from
Expand Down