1
0
Fork 0
mirror of https://github.com/ossrs/srs.git synced 2025-03-09 15:49:59 +00:00
srs/trunk/src/protocol/srs_sip_stack.hpp
Pieere Pi ffae1720ec gb28181模块可用性增强
主要改动,
1. 支持作为GB/T 28181上级平台
2. 新的目录接口sip_query_devicelist (/api/v1/gb28181?action=sip_query_devicelist)
3. 各种异常和问题修复
4. 其他一些小改动

以上改动基于feature/rtc分支,因为需要网页用WebRTC来拉GB28181的监控流,gb28181分支代码有点老了。

下面的序号n是指第n个差异块("@@ -"之间的内容)。

srs_gb28181.html
1. 原页面上多加了一个端口号
2-4. 给摄像头加上名称显示
5. 查询目录去掉chid
6. 删除通道参数分解为id和chid
7. API端口固定为1985

srs_app_gb28181.cpp
1-4. 四处因为错误而退出GB28181媒体处理循环,修改为不退出
5. payload为空异常
6. 修正判断startcode越界一个字符导致内存写越界的问题
ps流有可能末尾是全零填充,而且越界的那个字符正好是0x01,这样会多出一个nalu(末尾的三个0x00和一个越界的0x01),后面写video_data内存越界(if (first_pos != pre_pos){块,此处size - pre_pos - 4为-1,uint32_t naluLen得到的值为0,video_data[pre_pos+3] = p[0];写越界)破坏了其他数据,后续video_stream析构出错程序异常退出。
7. 此处srs后来已修复
8. 更新ssrc为被叫返回的值
原代码只支持标准中的《点播域内设备媒体流SSRC处理方式》(设备注册上来),不支持《点播外域设备媒体流SSRC处理方式》(即作为上级平台)。
这是因为如果srs作为上级平台,ssrc不是自己生成的,而是下级平台生成的。
9. 删除通道参数分解为id和chid
10. notify_sip_unregister后delete_stream_channel无效
11. notify_sip_query_catalog清空内存中的设备列表
12. 新函数query_device_list

srs_app_gb28181.hpp
1. update_rtmpmuxer_to_newssrc_by_id声明
2. 新函数get_gb28181_config_ptr和函数delete_stream_channel声明修改
3. 新函数query_device_list

srs_app_gb28181_sip.cpp
1-4. 在调试界面给摄像头加上名称显示;新函数clear_device_list和新函数dumpItemList
5-6. 两处因为错误而退出GB28181信令处理循环,修改为不退出
7. 设备注册上来,不检查服务器ID匹不匹配(支持作为上级平台)
8. 收到一个目录上报消息,更新内存中的数据
9. 更新ssrc为被叫返回的值
10. 新函数query_device_list

srs_app_gb28181_sip.hpp
1. 在调试界面给摄像头加上名称显示
2. 每个设备加上item_list,用于存储目录;新函数clear_device_list和新函数dumpItemList
3. 新函数clear_device_list

srs_app_http_api.cpp
1. 删除通道参数分解为id和chid
2. 新的接口sip_query_devicelist,用于查询所有设备的目录

srs_sip_stack.cpp
1. GB2312转UTF-8类
2. 被叫返回的ssrc初始化
3. parse_xml声明修改
4. 对XML内容进行字符集检测和转换
5-7. parse_xml定义修改
8. SIP BODY里面也有可能有\r\n
9-10. 防止恶意SIP消息 by vicious sip prober
11-12. 新的XML解析目录代码
13. 获取被叫返回的ssrc

srs_sip_stack.hpp
1. 依赖vector
2. 每个设备加上item_list,用于存储目录
3. 被叫返回的ssrc
4. parse_xml声明修改
2020-11-15 23:14:34 +08:00

189 lines
5.3 KiB
C++

/**
* The MIT License (MIT)
*
* Copyright (c) 2013-2020 Lixin
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef SRS_PROTOCOL_SIP_HPP
#define SRS_PROTOCOL_SIP_HPP
#include <srs_core.hpp>
#if !defined(SRS_EXPORT_LIBRTMP)
#include <string>
#include <sstream>
#include <vector>
#include <map>
#include <srs_kernel_consts.hpp>
#include <srs_rtsp_stack.hpp>
class SrsBuffer;
class SrsSimpleStream;
class SrsAudioFrame;
// SIP methods
#define SRS_SIP_METHOD_REGISTER "REGISTER"
#define SRS_SIP_METHOD_MESSAGE "MESSAGE"
#define SRS_SIP_METHOD_INVITE "INVITE"
#define SRS_SIP_METHOD_ACK "ACK"
#define SRS_SIP_METHOD_BYE "BYE"
// SIP-Version
#define SRS_SIP_VERSION "SIP/2.0"
#define SRS_SIP_USER_AGENT RTMP_SIG_SRS_SERVER
#define SRS_SIP_PTZ_START 0xA5
enum SrsSipCmdType{
SrsSipCmdRequest=0,
SrsSipCmdRespone=1
};
enum SrsSipPtzCmdType{
SrsSipPtzCmdStop = 0x00,
SrsSipPtzCmdRight = 0x01,
SrsSipPtzCmdLeft = 0x02,
SrsSipPtzCmdDown = 0x04,
SrsSipPtzCmdUp = 0x08,
SrsSipPtzCmdZoomIn = 0x10,
SrsSipPtzCmdZoomOut = 0x20
};
std::string srs_sip_get_utc_date();
class SrsSipRequest
{
public:
//sip header member
std::string method;
std::string uri;
std::string version;
std::string status;
std::string via;
std::string from;
std::string to;
std::string from_tag;
std::string to_tag;
std::string branch;
std::string call_id;
long seq;
std::string contact;
std::string user_agent;
std::string content_type;
long content_length;
long expires;
int max_forwards;
std::string www_authenticate;
std::string authorization;
std::string chid;
std::map<std::string, std::string> xml_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"
std::vector<std::map<std::string, std::string> > item_list;
public:
std::string serial;
std::string realm;
std::string sip_auth_id;
std::string sip_auth_pwd;
std::string sip_username;
std::string peer_ip;
int peer_port;
std::string host;
int host_port;
SrsSipCmdType cmdtype;
std::string from_realm;
std::string to_realm;
uint32_t y_ssrc;
public:
SrsRtspSdp* sdp;
SrsRtspTransport* transport;
public:
SrsSipRequest();
virtual ~SrsSipRequest();
public:
virtual bool is_register();
virtual bool is_invite();
virtual bool is_message();
virtual bool is_ack();
virtual bool is_bye();
virtual void copy(SrsSipRequest* src);
public:
virtual std::string get_cmdtype_str();
};
// The gb28181 sip protocol stack.
class SrsSipStack
{
private:
// The cached bytes buffer.
SrsSimpleStream* buf;
public:
SrsSipStack();
virtual ~SrsSipStack();
public:
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);
private:
//response from
virtual std::string get_sip_from(SrsSipRequest const *req);
//response to
virtual std::string get_sip_to(SrsSipRequest const *req);
//response via
virtual std::string get_sip_via(SrsSipRequest const *req);
public:
//response: request sent by the sip-agent, wait for sip-server response
virtual void resp_status(std::stringstream& ss, SrsSipRequest *req);
virtual void resp_keepalive(std::stringstream& ss, SrsSipRequest *req);
//request: request sent by the sip-server, wait for sip-agent response
virtual void req_invite(std::stringstream& ss, SrsSipRequest *req, std::string ip,
int port, uint32_t ssrc, bool tcpFlag);
virtual void req_ack(std::stringstream& ss, SrsSipRequest *req);
virtual void req_bye(std::stringstream& ss, SrsSipRequest *req);
virtual void req_401_unauthorized(std::stringstream& ss, SrsSipRequest *req);
virtual void req_query_catalog(std::stringstream& ss, SrsSipRequest *req);
virtual void req_ptz(std::stringstream& ss, SrsSipRequest *req, uint8_t cmd, uint8_t speed, int priority);
};
#endif
#endif