support sip ptz cmd

pull/1748/head
kyxlx550 5 years ago
parent 167711400a
commit 6a070a9a64

@ -318,11 +318,21 @@
</div> </div>
</div> </div>
<div> <div>
<div class="btn-group dropup">
<button class="btn btn-primary" id="btn_ptz_up"> 上↑ </button>
<button class="btn btn-primary" id="btn_ptz_down"> 下↓ </button>
<button class="btn btn-primary" id="btn_ptz_left"> ←左 </button>
<button class="btn btn-primary" id="btn_ptz_right"> 右→ </button>
<button class="btn btn-primary" id="btn_ptz_zoomin"> 放大+ </button>
<button class="btn btn-primary" id="btn_ptz_zoomout"> 缩小- </button>
</div>
[注意] !!! 云台控制需要启用内部sip功能
<div class="input-prepend" title="首播时间,点播放到开始播放的时间,秒"> <div class="input-prepend" title="首播时间,点播放到开始播放的时间,秒">
<span class="add-on">@PST</span> <span class="add-on">@PST</span>
<input class="span1" style="width:60px" id="txt_pst" type="text" placeholder="N秒"> <input class="span1" style="width:60px" id="txt_pst" type="text" placeholder="N秒">
</div> </div>
</div> </div>
</div> </div>
</div> </div>
@ -335,6 +345,17 @@
<video id="rtc_media_player" controls autoplay ></video> <video id="rtc_media_player" controls autoplay ></video>
</div> </div>
<div class="modal-footer" id="my_modal_footer"> <div class="modal-footer" id="my_modal_footer">
<div>
<div class="btn-group dropup">
<button class="btn btn-primary" id="btn_ptz_up_rtc"> 上↑ </button>
<button class="btn btn-primary" id="btn_ptz_down_rtc"> 下↓ </button>
<button class="btn btn-primary" id="btn_ptz_left_rtc"> ←左 </button>
<button class="btn btn-primary" id="btn_ptz_right_rtc"> 右→ </button>
<button class="btn btn-primary" id="btn_ptz_zoomin_rtc"> 放大+ </button>
<button class="btn btn-primary" id="btn_ptz_zoomout_rtc"> 缩小- </button>
</div>
[注意] !!! 云台控制需要启用内部sip功能
</div>
</div> </div>
</div> </div>
@ -963,9 +984,13 @@
}); });
var time_query = function(){
$("#btn_sip_query_session").click();
setTimeout(function () {$("#btn_sip_query_session").click()}, 1000);
}
$("#btn_sip_unregister").click(function(){ $("#btn_sip_unregister").click(function(){
var id = $("#sipSessionId").text(); var id = $("#sipSessionId").text();
alert(id);
if (id.indexOf("id:") != -1) { if (id.indexOf("id:") != -1) {
var str = id.split(":") var str = id.split(":")
@ -977,7 +1002,7 @@
$('#sipSessionMessage').html(syntaxHighlight(ret)); $('#sipSessionMessage').html(syntaxHighlight(ret));
if (ret != undefined && ret.code == 0){ if (ret != undefined && ret.code == 0){
$("#btn_sip_query_session").click(); time_query();
} }
} }
}); });
@ -996,7 +1021,7 @@
$('#sipSessionMessage').html(syntaxHighlight(ret)); $('#sipSessionMessage').html(syntaxHighlight(ret));
if (ret != undefined && ret.code == 0){ if (ret != undefined && ret.code == 0){
$("#btn_sip_query_session").click(); time_query();
} }
} }
}); });
@ -1015,7 +1040,7 @@
$('#sipSessionMessage').html(syntaxHighlight(ret)); $('#sipSessionMessage').html(syntaxHighlight(ret));
if (ret != undefined && ret.code == 0){ if (ret != undefined && ret.code == 0){
$("#btn_sip_query_session").click(); time_query();
} }
} }
}); });
@ -1033,7 +1058,7 @@
var ret = http_get(apiurl); var ret = http_get(apiurl);
$('#sipSessionMessage').html(syntaxHighlight(ret)); $('#sipSessionMessage').html(syntaxHighlight(ret));
if (ret != undefined && ret.code == 0){ if (ret != undefined && ret.code == 0){
$("#btn_sip_query_session").click(); time_query();
} }
} }
}); });
@ -1060,6 +1085,44 @@
} }
}); });
var call_ptz_cmd = function(cmd) {
var str = $("#gb28181ChannelId").text();
var str_array = str.split("@")
var chid = "";
var id = "";
if (str_array.length < 1){
return;
}
var speed = "136";
id = str_array[0];
chid = str_array[1];
url = $("#txt_api_url").val();
var apiurl = url + "/api/v1/gb28181?action=sip_ptz&id=" + id + "&chid="+chid+ "&ptzcmd="+cmd + "&speed=" + speed;
var ret = http_get(apiurl);
$('#gb28181ChannelMessage').html(syntaxHighlight(ret));
};
var ptz_cmd = ["up", "down", "right", "left", "zoomin", "zoomout"]
for (var i=0; i<ptz_cmd.length; i++){
var bt_fun = function(id, cmd){
$(bt_id).mousedown(function(){
call_ptz_cmd(cmd);
});
$(bt_id).mouseup(function(){
call_ptz_cmd("stop");
});
};
var bt_id = "#btn_ptz_"+ptz_cmd[i]+ "_rtc";
bt_fun(bt_id, ptz_cmd[i]);
bt_id = "#btn_ptz_"+ptz_cmd[i];
bt_fun(bt_id, ptz_cmd[i]);
}
$("#btn_create_channel").click(function(){ $("#btn_create_channel").click(function(){
$("#create_channel_modal").modal({show: true, keyboard: false}); $("#create_channel_modal").modal({show: true, keyboard: false});
}); });
@ -1100,7 +1163,6 @@
$("#rtc_player_modal").on("hide", function(){ $("#rtc_player_modal").on("hide", function(){
console.log("rtc stop");
if (pc) { if (pc) {
pc.close(); pc.close();
} }

@ -1774,6 +1774,18 @@ srs_error_t SrsGb28181Manger::notify_sip_bye(std::string id, std::string chid)
return sip_service->send_bye(&req, chid); return sip_service->send_bye(&req, chid);
} }
srs_error_t SrsGb28181Manger::notify_sip_ptz(std::string id, std::string chid, std::string cmd,
uint8_t speed, int priority)
{
if (!sip_service){
return srs_error_new(ERROR_GB28181_SIP_NOT_RUN, "sip not run");
}
SrsSipRequest req;
req.sip_auth_id = id;
return sip_service->send_ptz(&req, chid, cmd, speed, priority);
}
srs_error_t SrsGb28181Manger::notify_sip_raw_data(std::string id, std::string data) srs_error_t SrsGb28181Manger::notify_sip_raw_data(std::string id, std::string data)
{ {
if (!sip_service){ if (!sip_service){

@ -422,6 +422,7 @@ public:
srs_error_t notify_sip_raw_data(std::string id, std::string data); srs_error_t notify_sip_raw_data(std::string id, std::string data);
srs_error_t notify_sip_unregister(std::string id); srs_error_t notify_sip_unregister(std::string id);
srs_error_t notify_sip_query_catalog(std::string id); srs_error_t notify_sip_query_catalog(std::string id);
srs_error_t notify_sip_ptz(std::string id, std::string chid, std::string cmd, uint8_t speed, int priority);
srs_error_t query_sip_session(std::string id, SrsJsonArray* arr); srs_error_t query_sip_session(std::string id, SrsJsonArray* arr);
private: private:

@ -100,6 +100,7 @@ SrsGb28181SipSession::SrsGb28181SipSession(SrsGb28181SipService *c, SrsSipReques
_peer_port = 0; _peer_port = 0;
_fromlen = 0; _fromlen = 0;
_sip_cseq = 100;
} }
SrsGb28181SipSession::~SrsGb28181SipSession() SrsGb28181SipSession::~SrsGb28181SipSession()
@ -485,23 +486,30 @@ srs_error_t SrsGb28181SipService::on_udp_sip(string peer_ip, int peer_port,
}else if (req->is_message()) { }else if (req->is_message()) {
SrsGb28181SipSession* sip_session = fetch(session_id); SrsGb28181SipSession* sip_session = fetch(session_id);
if (!sip_session){
sip_session = fetch_session_by_callid(req->call_id);
}
if (!sip_session || sip_session->register_status() == SrsGb28181SipSessionUnkonw){ if (!sip_session || sip_session->register_status() == SrsGb28181SipSessionUnkonw){
srs_trace("gb28181: %s client not registered", req->sip_auth_id.c_str()); srs_trace("gb28181: %s client not registered", req->sip_auth_id.c_str());
return err; return err;
} }
//reponse status //reponse status
send_status(req, from, fromlen); if (req->cmdtype == SrsSipCmdRequest){
sip_session->set_alive_status(SrsGb28181SipSessionAliveOk); send_status(req, from, fromlen);
sip_session->set_alive_time(srs_get_system_time()); sip_session->set_alive_status(SrsGb28181SipSessionAliveOk);
sip_session->set_sockaddr((sockaddr)*from); sip_session->set_alive_time(srs_get_system_time());
sip_session->set_sockaddr_len(fromlen); sip_session->set_sockaddr((sockaddr)*from);
sip_session->set_peer_port(peer_port); sip_session->set_sockaddr_len(fromlen);
sip_session->set_peer_ip(peer_ip); sip_session->set_peer_port(peer_port);
sip_session->set_peer_ip(peer_ip);
//update device list
if (req->device_list_map.size() > 0){ //update device list
sip_session->update_device_list(req->device_list_map); if (req->device_list_map.size() > 0){
sip_session->update_device_list(req->device_list_map);
}
} }
}else if (req->is_invite()) { }else if (req->is_invite()) {
@ -675,6 +683,7 @@ srs_error_t SrsGb28181SipService::send_invite(SrsSipRequest *req, string ip, i
req->realm = config->sip_realm; req->realm = config->sip_realm;
req->serial = config->sip_serial; req->serial = config->sip_serial;
req->chid = chid; req->chid = chid;
req->seq = sip_session->sip_cseq();
SrsSipRequest register_req = sip_session->request(); SrsSipRequest register_req = sip_session->request();
req->to_realm = register_req.to_realm; req->to_realm = register_req.to_realm;
@ -730,6 +739,7 @@ srs_error_t SrsGb28181SipService::send_bye(SrsSipRequest *req, std::string chid)
req->realm = config->sip_realm; req->realm = config->sip_realm;
req->serial = config->sip_serial; req->serial = config->sip_serial;
req->chid = chid; req->chid = chid;
req->seq = sip_session->sip_cseq();
SrsSipRequest register_req = sip_session->request(); SrsSipRequest register_req = sip_session->request();
req->to_realm = register_req.to_realm; req->to_realm = register_req.to_realm;
@ -774,11 +784,22 @@ srs_error_t SrsGb28181SipService::send_sip_raw_data(SrsSipRequest *req, std::st
srs_error_t SrsGb28181SipService::send_query_catalog(SrsSipRequest *req) srs_error_t SrsGb28181SipService::send_query_catalog(SrsSipRequest *req)
{ {
srs_error_t err = srs_success;
srs_assert(req);
SrsGb28181SipSession *sip_session = fetch(req->sip_auth_id);
if (!sip_session){
return srs_error_new(ERROR_GB28181_SESSION_IS_NOTEXIST, "sip session not exist");
}
req->host = config->host; req->host = config->host;
req->host_port = config->sip_port; req->host_port = config->sip_port;
req->realm = config->sip_realm; req->realm = config->sip_realm;
req->serial = config->sip_serial; req->serial = config->sip_serial;
req->chid = req->sip_auth_id; req->chid = req->sip_auth_id;
req->seq = sip_session->sip_cseq();
//get protocol stack //get protocol stack
std::stringstream ss; std::stringstream ss;
@ -787,6 +808,85 @@ srs_error_t SrsGb28181SipService::send_query_catalog(SrsSipRequest *req)
return send_sip_raw_data(req, ss.str()); return send_sip_raw_data(req, ss.str());
} }
srs_error_t SrsGb28181SipService::send_ptz(SrsSipRequest *req, std::string chid, std::string cmd,
uint8_t speed, int priority)
{
srs_error_t err = srs_success;
srs_assert(req);
SrsGb28181SipSession *sip_session = fetch(req->sip_auth_id);
if (!sip_session){
return srs_error_new(ERROR_GB28181_SESSION_IS_NOTEXIST, "sip session not exist");
}
SrsGb28181Device *device = sip_session->get_device_info(chid);
if (!device){
return srs_error_new(ERROR_GB28181_SIP_CH_NOTEXIST, "sip device channel not exist");
}
if (device->invite_status != SrsGb28181SipSessionInviteOk){
return srs_error_new(ERROR_GB28181_SIP_NOT_INVITE, "sip device channel not inviting");
}
//prame branch, from_tag, to_tag, call_id,
//The parameter of 'bye' must be the same as 'invite'
//SrsSipRequest r = sip_session->request();
req->copy(&device->req_inivate);
req->host = config->host;
req->host_port = config->sip_port;
req->realm = config->sip_realm;
req->serial = config->sip_serial;
req->chid = chid;
req->seq = sip_session->sip_cseq();
SrsSipPtzCmdType ptzcmd = SrsSipPtzCmdRight;
const char *ss_cmd = cmd.c_str();
if (!strcasecmp(ss_cmd, "stop")){
ptzcmd = SrsSipPtzCmdStop;
}else if (!strcasecmp(ss_cmd, "right")){
ptzcmd = SrsSipPtzCmdRight;
}else if (!strcasecmp(ss_cmd, "left")){
ptzcmd = SrsSipPtzCmdLeft;
}else if (!strcasecmp(ss_cmd, "down")){
ptzcmd = SrsSipPtzCmdDown;
}else if (!strcasecmp(ss_cmd, "up")){
ptzcmd = SrsSipPtzCmdUp;
}else if (!strcasecmp(ss_cmd, "zoomout")){
ptzcmd = SrsSipPtzCmdZoomOut;
}else if (!strcasecmp(ss_cmd, "zoomin")){
ptzcmd = SrsSipPtzCmdZoomIn;
}else{
return srs_error_new(ERROR_GB28181_SIP_PTZ_CMD_INVALID, "sip ptz cmd no support");
}
if (speed < 0 || speed > 0xFF){
return srs_error_new(ERROR_GB28181_SIP_PTZ_CMD_INVALID, "sip ptz cmd speed out of range");
}
if (priority <= 0 ){
priority = 5;
}
//get protocol stack
std::stringstream ss;
sip->req_ptz(ss, req, ptzcmd, speed, priority);
sockaddr addr = sip_session->sockaddr_from();
if (send_message(&addr, sip_session->sockaddr_fromlen(), ss) <= 0)
{
return srs_error_new(ERROR_GB28181_SIP_PTZ_FAILED, "sip ptz failed");
}
//call_id map sip_session
sip_session_map_by_callid(sip_session, req->call_id);
return err;
}
srs_error_t SrsGb28181SipService::query_sip_session(std::string sid, SrsJsonArray* arr) srs_error_t SrsGb28181SipService::query_sip_session(std::string sid, SrsJsonArray* arr)
{ {
srs_error_t err = srs_success; srs_error_t err = srs_success;

@ -92,6 +92,7 @@ private:
std::map<std::string, SrsGb28181Device*> _device_list; std::map<std::string, SrsGb28181Device*> _device_list;
//std::map<std::string, int> _device_status; //std::map<std::string, int> _device_status;
int _sip_cseq;
public: public:
SrsGb28181SipSession(SrsGb28181SipService *c, SrsSipRequest* r); SrsGb28181SipSession(SrsGb28181SipService *c, SrsSipRequest* r);
@ -128,6 +129,7 @@ public:
sockaddr sockaddr_from() { return _from;} sockaddr sockaddr_from() { return _from;}
int sockaddr_fromlen() { return _fromlen;} int sockaddr_fromlen() { return _fromlen;}
SrsSipRequest request() { return *req;} SrsSipRequest request() { return *req;}
int sip_cseq(){ return _sip_cseq++;}
std::string session_id() { return _session_id;} std::string session_id() { return _session_id;}
public: public:
@ -175,6 +177,7 @@ public:
srs_error_t send_invite(SrsSipRequest *req, std::string ip, int port, uint32_t ssrc, std::string chid); srs_error_t send_invite(SrsSipRequest *req, std::string ip, int port, uint32_t ssrc, std::string chid);
srs_error_t send_bye(SrsSipRequest *req, std::string chid); srs_error_t send_bye(SrsSipRequest *req, std::string chid);
srs_error_t send_query_catalog(SrsSipRequest *req); srs_error_t send_query_catalog(SrsSipRequest *req);
srs_error_t send_ptz(SrsSipRequest *req, std::string chid, std::string cmd, uint8_t speed, int priority);
// The SIP command is transmitted through HTTP API, // The SIP command is transmitted through HTTP API,
// and the body content is transmitted to the device, // and the body content is transmitted to the device,

@ -1774,6 +1774,26 @@ srs_error_t SrsGoApiGb28181::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessa
return srs_api_response_code(w, r, code); return srs_api_response_code(w, r, code);
} }
else if(action == "sip_ptz"){
string chid = r->query_get("chid");
string ptzcmd = r->query_get("ptzcmd");
string speed = r->query_get("speed");
string priority = r->query_get("priority");
if (id.empty() || chid.empty() || ptzcmd.empty() || speed.empty()){
return srs_api_response_code(w, r, ERROR_GB28181_VALUE_EMPTY);
}
uint8_t _speed = (uint8_t)(strtoul(speed.c_str(), NULL, 10));
int _priority = (int)(strtoul(priority.c_str(), NULL, 10));
err = _srs_gb28181->notify_sip_ptz(id, chid, ptzcmd, _speed, _priority);
int code = srs_error_code(err);
if (err != srs_success) {
srs_error_reset(err);
}
return srs_api_response_code(w, r, code);
}
else if(action == "sip_raw_data"){ else if(action == "sip_raw_data"){
if (id.empty()){ if (id.empty()){
return srs_api_response_code(w, r, ERROR_GB28181_VALUE_EMPTY); return srs_api_response_code(w, r, ERROR_GB28181_VALUE_EMPTY);

@ -367,6 +367,9 @@
#define ERROR_GB28181_SIP_CH_NOTEXIST 6013 #define ERROR_GB28181_SIP_CH_NOTEXIST 6013
#define ERROR_GB28181_SIP_RAW_DATA_FAILED 6014 #define ERROR_GB28181_SIP_RAW_DATA_FAILED 6014
#define ERROR_GB28181_SIP_PRASE_FAILED 6015 #define ERROR_GB28181_SIP_PRASE_FAILED 6015
#define ERROR_GB28181_SIP_PTZ_FAILED 6016
#define ERROR_GB28181_SIP_NOT_INVITE 6017
#define ERROR_GB28181_SIP_PTZ_CMD_INVALID 6018
/////////////////////////////////////////////////////// ///////////////////////////////////////////////////////
// HTTP API error. // HTTP API error.

@ -45,10 +45,51 @@ using namespace std;
unsigned int srs_sip_random(int min,int max) unsigned int srs_sip_random(int min,int max)
{ {
srand(int(time(0))); //it is possible to duplicate data with time(0)
srand(unsigned(srs_update_system_time()));
return rand() % (max - min + 1) + min; return rand() % (max - min + 1) + min;
} }
std::string srs_sip_generate_branch()
{
int rand = srs_sip_random(10000000, 99999999);
std::stringstream branch;
branch << "SrsGbB" << rand;
return branch.str();
}
std::string srs_sip_generate_to_tag()
{
uint32_t rand = srs_sip_random(10000000, 99999999);
std::stringstream branch;
branch << "SrsGbT" << rand;
return branch.str();
}
std::string srs_sip_generate_from_tag()
{
uint32_t rand = srs_sip_random(10000000, 99999999);
std::stringstream branch;
branch << "SrsGbF" << rand;
return branch.str();
}
std::string srs_sip_generate_call_id()
{
uint32_t rand = srs_sip_random(10000000, 99999999);
std::stringstream branch;
branch << "2020" << rand;
return branch.str();
}
std::string srs_sip_generate_sn()
{
uint32_t rand = srs_sip_random(10000000, 99999999);
std::stringstream sn;
sn << rand;
return sn.str();
}
std::string srs_sip_get_form_to_uri(std::string msg) std::string srs_sip_get_form_to_uri(std::string msg)
{ {
//<sip:34020000002000000001@3402000000>;tag=536961166 //<sip:34020000002000000001@3402000000>;tag=536961166
@ -897,15 +938,13 @@ void SrsSipStack::req_invite(stringstream& ss, SrsSipRequest *req, string ip, in
<< "y=" << _ssrc << SRS_RTSP_CRLF; << "y=" << _ssrc << SRS_RTSP_CRLF;
int rand = srs_sip_random(1000, 9999); std::stringstream from, to, uri;
std::stringstream from, to, uri, branch, from_tag, call_id;
//"INVITE sip:34020000001320000001@3402000000 SIP/2.0\r\n //"INVITE sip:34020000001320000001@3402000000 SIP/2.0\r\n
uri << "sip:" << req->chid << "@" << req->realm; uri << "sip:" << req->chid << "@" << req->realm;
//From: <sip:34020000002000000001@%s:%s>;tag=500485%d\r\n //From: <sip:34020000002000000001@%s:%s>;tag=500485%d\r\n
from << req->serial << "@" << req->realm; from << req->serial << "@" << req->realm;
to << req->chid << "@" << req->realm; to << req->chid << "@" << req->realm;
call_id << "2020" << rand ;
req->from = from.str(); req->from = from.str();
req->to = to.str(); req->to = to.str();
@ -918,19 +957,17 @@ void SrsSipStack::req_invite(stringstream& ss, SrsSipRequest *req, string ip, in
} }
req->uri = uri.str(); req->uri = uri.str();
req->call_id = call_id.str();
branch << "z9hG4bK3420" << rand; req->call_id = srs_sip_generate_call_id();
from_tag << "51235" << rand; req->branch = srs_sip_generate_branch();
req->branch = branch.str(); req->from_tag = srs_sip_generate_from_tag();
req->from_tag = from_tag.str();
ss << "INVITE " << req->uri << " " << SRS_SIP_VERSION << SRS_RTSP_CRLF ss << "INVITE " << req->uri << " " << SRS_SIP_VERSION << SRS_RTSP_CRLF
<< "Via: " << SRS_SIP_VERSION << "/UDP "<< req->host << ":" << req->host_port << ";rport;branch=" << req->branch << SRS_RTSP_CRLF << "Via: " << SRS_SIP_VERSION << "/UDP "<< req->host << ":" << req->host_port << ";rport;branch=" << req->branch << SRS_RTSP_CRLF
<< "From: " << get_sip_from(req) << SRS_RTSP_CRLF << "From: " << get_sip_from(req) << SRS_RTSP_CRLF
<< "To: " << get_sip_to(req) << SRS_RTSP_CRLF << "To: " << get_sip_to(req) << SRS_RTSP_CRLF
<< "Call-ID: " << req->call_id <<SRS_RTSP_CRLF << "Call-ID: " << req->call_id <<SRS_RTSP_CRLF
<< "CSeq: 20 INVITE" << SRS_RTSP_CRLF << "CSeq: " << req->seq << " INVITE" << SRS_RTSP_CRLF
<< "Content-Type: Application/SDP" << SRS_RTSP_CRLF << "Content-Type: Application/SDP" << SRS_RTSP_CRLF
<< "Contact: <sip:" << req->to << ">" << SRS_RTSP_CRLF << "Contact: <sip:" << req->to << ">" << SRS_RTSP_CRLF
<< "Max-Forwards: 70" << SRS_RTSP_CRLF << "Max-Forwards: 70" << SRS_RTSP_CRLF
@ -1039,7 +1076,6 @@ void SrsSipStack::req_bye(std::stringstream& ss, SrsSipRequest *req)
req->uri = uri.str(); req->uri = uri.str();
int seq = srs_sip_random(22, 99);
ss << "BYE " << req->uri << " "<< SRS_SIP_VERSION << SRS_RTSP_CRLF ss << "BYE " << req->uri << " "<< SRS_SIP_VERSION << SRS_RTSP_CRLF
//<< "Via: "<< SRS_SIP_VERSION << "/UDP "<< req->host << ":" << req->host_port << ";rport" << branch << SRS_RTSP_CRLF //<< "Via: "<< SRS_SIP_VERSION << "/UDP "<< req->host << ":" << req->host_port << ";rport" << branch << SRS_RTSP_CRLF
<< "Via: " << SRS_SIP_VERSION << "/UDP " << req->host << ":" << req->host_port << ";rport;branch=" << req->branch << SRS_RTSP_CRLF << "Via: " << SRS_SIP_VERSION << "/UDP " << req->host << ":" << req->host_port << ";rport;branch=" << req->branch << SRS_RTSP_CRLF
@ -1047,7 +1083,7 @@ void SrsSipStack::req_bye(std::stringstream& ss, SrsSipRequest *req)
<< "To: " << get_sip_to(req) << SRS_RTSP_CRLF << "To: " << get_sip_to(req) << SRS_RTSP_CRLF
//bye callid is inivte callid //bye callid is inivte callid
<< "Call-ID: " << req->call_id << SRS_RTSP_CRLF << "Call-ID: " << req->call_id << SRS_RTSP_CRLF
<< "CSeq: "<< seq <<" BYE" << SRS_RTSP_CRLF << "CSeq: "<< req->seq <<" BYE" << SRS_RTSP_CRLF
<< "Max-Forwards: 70" << SRS_RTSP_CRLF << "Max-Forwards: 70" << SRS_RTSP_CRLF
<< "User-Agent: " << SRS_SIP_USER_AGENT << SRS_RTSP_CRLF << "User-Agent: " << SRS_SIP_USER_AGENT << SRS_RTSP_CRLF
<< "Content-Length: 0" << SRS_RTSP_CRLFCRLF; << "Content-Length: 0" << SRS_RTSP_CRLFCRLF;
@ -1149,40 +1185,134 @@ void SrsSipStack::req_query_catalog(std::stringstream& ss, SrsSipRequest *req)
std::stringstream xml; std::stringstream xml;
std::string xmlbody; std::string xmlbody;
int sn = srs_sip_random(10000000, 99999999);
xml << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" << SRS_RTSP_CRLF xml << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" << SRS_RTSP_CRLF
<< "<Query>" << SRS_RTSP_CRLF << "<Query>" << SRS_RTSP_CRLF
<< "<CmdType>Catalog</CmdType>" << SRS_RTSP_CRLF << "<CmdType>Catalog</CmdType>" << SRS_RTSP_CRLF
<< "<SN>" << sn << "</SN>" << SRS_RTSP_CRLF << "<SN>" << srs_sip_generate_sn() << "</SN>" << SRS_RTSP_CRLF
<< "<DeviceID>" << req->sip_auth_id << "</DeviceID>" << SRS_RTSP_CRLF << "<DeviceID>" << req->sip_auth_id << "</DeviceID>" << SRS_RTSP_CRLF
<< "</Query>" << SRS_RTSP_CRLF; << "</Query>" << SRS_RTSP_CRLF;
xmlbody = xml.str(); xmlbody = xml.str();
int rand = srs_sip_random(1000, 9999); std::stringstream from, to, uri;
std::stringstream from, to, uri, branch, from_tag, call_id;
//"INVITE sip:34020000001320000001@3402000000 SIP/2.0\r\n //"INVITE sip:34020000001320000001@3402000000 SIP/2.0\r\n
uri << "sip:" << req->sip_auth_id << "@" << req->realm; uri << "sip:" << req->sip_auth_id << "@" << req->realm;
//From: <sip:34020000002000000001@%s:%s>;tag=500485%d\r\n //From: <sip:34020000002000000001@%s:%s>;tag=500485%d\r\n
from << req->serial << "@" << req->host << ":" << req->host_port; from << req->serial << "@" << req->host << ":" << req->host_port;
to << req->sip_auth_id << "@" << req->realm; to << req->sip_auth_id << "@" << req->realm;
call_id << "2020" << rand;
req->from = from.str(); req->from = from.str();
req->to = to.str(); req->to = to.str();
req->uri = uri.str(); req->uri = uri.str();
req->call_id = call_id.str();
req->call_id = srs_sip_generate_call_id();
branch << "z9hG4bK3420" << rand; req->branch = srs_sip_generate_branch();
from_tag << "51235" << rand; req->from_tag = srs_sip_generate_from_tag();
req->branch = branch.str();
req->from_tag = from_tag.str();
ss << "MESSAGE " << req->uri << " " << SRS_SIP_VERSION << SRS_RTSP_CRLF ss << "MESSAGE " << req->uri << " " << SRS_SIP_VERSION << SRS_RTSP_CRLF
<< "Via: " << SRS_SIP_VERSION << "/UDP "<< req->host << ":" << req->host_port << ";rport;branch=" << req->branch << SRS_RTSP_CRLF << "Via: " << SRS_SIP_VERSION << "/UDP "<< req->host << ":" << req->host_port << ";rport;branch=" << req->branch << SRS_RTSP_CRLF
<< "From: " << get_sip_from(req) << SRS_RTSP_CRLF << "From: " << get_sip_from(req) << SRS_RTSP_CRLF
<< "To: " << get_sip_to(req) << SRS_RTSP_CRLF << "To: " << get_sip_to(req) << SRS_RTSP_CRLF
<< "Call-ID: " << req->call_id << SRS_RTSP_CRLF << "Call-ID: " << req->call_id << SRS_RTSP_CRLF
<< "CSeq: 25 MESSAGE" << SRS_RTSP_CRLF << "CSeq: " << req->seq << " MESSAGE" << SRS_RTSP_CRLF
<< "Content-Type: Application/MANSCDP+xml" << SRS_RTSP_CRLF
<< "Max-Forwards: 70" << SRS_RTSP_CRLF
<< "User-Agent: " << SRS_SIP_USER_AGENT << SRS_RTSP_CRLF
<< "Content-Length: " << xmlbody.length() << SRS_RTSP_CRLFCRLF
<< xmlbody;
}
void SrsSipStack::req_ptz(std::stringstream& ss, SrsSipRequest *req, uint8_t cmd, uint8_t speed, int priority)
{
/*
<?xml version="1.0"?>
<Control>
<CmdType>DeviceControl</CmdType>
<SN>11</SN>
<DeviceID>34020000001310000053</DeviceID>
<PTZCmd>A50F01021F0000D6</PTZCmd>
</Control>
*/
uint8_t ptz_cmd[8] = {0};
ptz_cmd[0] = SRS_SIP_PTZ_START;
ptz_cmd[1] = 0x0F;
ptz_cmd[2] = 0x01;
ptz_cmd[3] = cmd;
switch(cmd){
case SrsSipPtzCmdStop: // = 0x00
ptz_cmd[4] = 0;
ptz_cmd[5] = 0;
ptz_cmd[6] = 0;
break;
case SrsSipPtzCmdRight: // = 0x01,
case SrsSipPtzCmdLeft: // = 0x02,
ptz_cmd[4] = speed;
break;
case SrsSipPtzCmdDown: // = 0x04,
case SrsSipPtzCmdUp: // = 0x08,
ptz_cmd[5] = speed;
break;
case SrsSipPtzCmdZoomOut: // = 0x10,
case SrsSipPtzCmdZoomIn: // = 0x20
ptz_cmd[6] = (speed & 0x0F) << 4;
break;
default:
return;
}
uint32_t check = 0;
for (int i = 0; i < 7; i++){
check += ptz_cmd[i];
}
ptz_cmd[7] = (uint8_t)(check % 256);
std::stringstream ss_ptzcmd;
for (int i = 0; i < 8; i++){
char hex_cmd[3] = {0};
sprintf(hex_cmd, "%02X", ptz_cmd[i]);
ss_ptzcmd << hex_cmd;
}
std::stringstream xml;
std::string xmlbody;
xml << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" << SRS_RTSP_CRLF
<< "<Control>" << SRS_RTSP_CRLF
<< "<CmdType>DeviceControl</CmdType>" << SRS_RTSP_CRLF
<< "<SN>" << srs_sip_generate_sn() << "</SN>" << SRS_RTSP_CRLF
<< "<DeviceID>" << req->sip_auth_id << "</DeviceID>" << SRS_RTSP_CRLF
<< "<PTZCmd>" << ss_ptzcmd.str() << "</PTZCmd>" << SRS_RTSP_CRLF
<< "<Info>" << SRS_RTSP_CRLF
<< "<ControlPriority>" << priority << "</ControlPriority>" << SRS_RTSP_CRLF
<< "</Info>" << SRS_RTSP_CRLF
<< "</Control>" << SRS_RTSP_CRLF;
xmlbody = xml.str();
std::stringstream from, to, uri, call_id;
//"INVITE sip:34020000001320000001@3402000000 SIP/2.0\r\n
uri << "sip:" << req->sip_auth_id << "@" << req->realm;
//From: <sip:34020000002000000001@%s:%s>;tag=500485%d\r\n
from << req->serial << "@" << req->host << ":" << req->host_port;
to << req->sip_auth_id << "@" << req->realm;
req->from = from.str();
req->to = to.str();
req->uri = uri.str();
req->call_id = srs_sip_generate_call_id();
req->branch = srs_sip_generate_branch();
req->from_tag = srs_sip_generate_from_tag();
ss << "MESSAGE " << req->uri << " "<< SRS_SIP_VERSION << SRS_RTSP_CRLF
//<< "Via: "<< SRS_SIP_VERSION << "/UDP "<< req->host << ":" << req->host_port << ";rport" << branch << SRS_RTSP_CRLF
<< "Via: " << SRS_SIP_VERSION << "/UDP " << req->host << ":" << req->host_port << ";rport;branch=" << req->branch << SRS_RTSP_CRLF
<< "From: " << get_sip_from(req) << SRS_RTSP_CRLF
<< "To: " << get_sip_to(req) << SRS_RTSP_CRLF
<< "Call-ID: " << req->call_id << SRS_RTSP_CRLF
<< "CSeq: "<< req->seq <<" MESSAGE" << SRS_RTSP_CRLF
<< "Content-Type: Application/MANSCDP+xml" << SRS_RTSP_CRLF << "Content-Type: Application/MANSCDP+xml" << SRS_RTSP_CRLF
<< "Max-Forwards: 70" << SRS_RTSP_CRLF << "Max-Forwards: 70" << SRS_RTSP_CRLF
<< "User-Agent: " << SRS_SIP_USER_AGENT << SRS_RTSP_CRLF << "User-Agent: " << SRS_SIP_USER_AGENT << SRS_RTSP_CRLF

@ -50,12 +50,24 @@ class SrsAudioFrame;
#define SRS_SIP_VERSION "SIP/2.0" #define SRS_SIP_VERSION "SIP/2.0"
#define SRS_SIP_USER_AGENT RTMP_SIG_SRS_SERVER #define SRS_SIP_USER_AGENT RTMP_SIG_SRS_SERVER
#define SRS_SIP_PTZ_START 0xA5
enum SrsSipCmdType{ enum SrsSipCmdType{
SrsSipCmdRequest=0, SrsSipCmdRequest=0,
SrsSipCmdRespone=1 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(); std::string srs_sip_get_utc_date();
class SrsSipRequest class SrsSipRequest
@ -162,6 +174,7 @@ public:
virtual void req_bye(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_401_unauthorized(std::stringstream& ss, SrsSipRequest *req);
virtual void req_query_catalog(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);
}; };

Loading…
Cancel
Save