从事一年的视频开发工作和架构设计,现在想写点东西给大家分享下。
远程访问控制视频设备有很多协议如RTSP等,但这些协议是要求设备是有明确IP的,因为它们只能完全被动接受请求。但GB28181协议就不是,它使设备主动链接平台 ,主动上线,上线后,平台可以给设备发视频请求等,实现视频的直播、回播等。这样的优势是只要平台在外网的IP段,设备找到平台后,所有设备就可以随意控制了,而设备不需要外围IP。
程序分为好几个单元,下面分别介绍下:
代码如下:
#include"stdafx.h"
#include
#include"SipParaser.h"
#include "String.h"
#include
using namespace std;
const string SipVersionInfo = "SIP/2.0";
const string NewLine = "\r\n";
SipParaser::SipParaser()
{
}
SipParaser::~SipParaser()
{
}
SipMessage SipParaser::ParseToSipMessage(string messageStr, bool isResponse)
{
SipMessage sipMessage;
vector msgArr = String::split(messageStr, " ");
if (messageStr.find("SIP") == 0)
{
sipMessage.Status = (SIPResponseStatusCodesEnum)std::atoi(msgArr[1].c_str());
}
else
{
sipMessage.Method = SIPMethods::GetSIPMethodsEnum(msgArr[0]);// SIPMethods.GetMethod(messageStr.Substring(0, messageStr.IndexOf(" ")).Trim());
sipMessage.URL = msgArr[1];
}
string m_CRLF = "\r\n";
int endFistLinePosn = messageStr.find(m_CRLF);
sipMessage.FirstLine = messageStr.substr(0, endFistLinePosn);
string headerString = "";
string bodyString = "";
int endHeaderPosn = messageStr.find(m_CRLF + m_CRLF);//双倍回车换行表示头结束--廖高波
if (endHeaderPosn == -1)
{
headerString = messageStr.substr(endFistLinePosn + 2, messageStr.size() - endFistLinePosn - 2);
}
else
{
headerString = messageStr.substr(endFistLinePosn + 2, endHeaderPosn - endFistLinePosn - 2);//去掉首行的数据-廖高波
if (messageStr.size() > endHeaderPosn + 4)
{
bodyString = messageStr.substr(endHeaderPosn + 4);
}
}
vector FromArr = String::split(headerString, m_CRLF);
map ValDic;
ValDic.insert(pair("Via", &sipMessage.Via));
ValDic.insert(pair("Via", &sipMessage.Via));
ValDic.insert(pair("From", &sipMessage.From));
ValDic.insert(pair("To", &sipMessage.To));
ValDic.insert(pair("CSeq", &sipMessage.CSeq));
ValDic.insert(pair("Contact", &sipMessage.Contact));
ValDic.insert(pair("Expires", &sipMessage.Expires));
ValDic.insert(pair("Max-Forwards", &sipMessage.MaxForwards));
ValDic.insert(pair("User-Agent", &sipMessage.UserAgent));
ValDic.insert(pair("Route", &sipMessage.Route));
ValDic.insert(pair("Call-ID", &sipMessage.CallID));
ValDic.insert(pair("Content-Type", &sipMessage.ContentType));
ValDic.insert(pair("WWW-Authenticate", &sipMessage.WWWAuthenticate));
ValDic.insert(pair("Authorization", &sipMessage.Authorization));
for each (string one in FromArr)
{
vector oneArr = String::split(one, ":");
map::iterator it = ValDic.find(oneArr[0]);
if (it!= ValDic.end())
{
it->second->Value = one;
}
}
if ((sipMessage.Expires.Value).length()>0)
{
int p = sipMessage.Expires.Value.find(":");
string str = String::trim(sipMessage.Expires.Value.substr(p + 1));//少Trim()
sipMessage.ExpiresTime = stoi(str);
}
if (sipMessage.From.Value.length() > 0)
{
//从From域解析出DeviceID和Realm
//From: ;tag=1555746248
if (isResponse == false)
{
string pat = "";//正确哦。
regex reg1(pat);
smatch s1;
auto pos = sipMessage.From.Value.cbegin();
auto end = sipMessage.From.Value.cend();
regex_search(pos, end, s1, reg1);
if (s1.size() >=2)
{
vector values = String::split(s1.str(1), "@");//可能要问题
sipMessage.DeviceID = values[0];
if (values.size() >= 2)
sipMessage.Realm = values[1];
else
sipMessage.Realm = "0.0.0.0";
}
}
int p = sipMessage.From.Value.find("tag=");
sipMessage.FromTag = sipMessage.From.Value.substr(p + 4);
}
if (sipMessage.CallID.Value.length()>0)
{
int p = sipMessage.CallID.Value.find(":");
string gid = String::trim(sipMessage.CallID.Value.substr(p + 1));
sipMessage.SessionID = gid;
}
if (sipMessage.CSeq.Value.length()>0)
{
vector tmpArr = String::split(sipMessage.CSeq.Value," ");
if (tmpArr.size() >= 3)
sipMessage.CSeqID = stoi(tmpArr[1]);
}
if (sipMessage.To.Value.length() > 0)
{
if (isResponse == true)
{
string pat = "";//正确哦。
regex reg1(pat);
smatch s1;
auto pos = sipMessage.To.Value.cbegin();
auto end = sipMessage.To.Value.cend();
regex_search(pos, end, s1, reg1);
if (s1.size() >= 2)
{
vector values = String::split(s1.str(1), "@");//可能要问题
sipMessage.DeviceID = values[0];
if (values.size() >= 2)
sipMessage.Realm = values[1];
else
sipMessage.Realm = "0.0.0.0";
}
}
int p = sipMessage.To.Value.find("tag=");
if (p >= 0)
sipMessage.ToTag = sipMessage.To.Value.substr(p + 4);;
}
if (sipMessage.Via.Value.length()>0)
{
int p = sipMessage.Via.Value.find(":");
if (p >=0)
sipMessage.TopVia = String::trim(sipMessage.Via.Value.substr(p + 1));
}
if (sipMessage.Route.Value.length()>0)
{
int p = sipMessage.Route.Value.find(":");
if (p > 0)
sipMessage.RouteStr = String::trim(sipMessage.Route.Value.substr(p + 1));
}
sipMessage.BodyInfo = bodyString;
return sipMessage;
}
string SipParaser::ParseSipResponseToStr(SipMessage sipMessage)
{
string sbdMsg;
if (sipMessage.Status != SIPResponseStatusCodesEnum::None)
sbdMsg.append(SipVersionInfo + " " + std::to_string(sipMessage.Status) + " "
+ SIPMethods::GetStatusCodesEnumName(sipMessage.Status) + "\r\n");
else
sbdMsg.append(sipMessage.FirstLine);
sbdMsg.append(sipMessage.To.Value.length() > 0 ? sipMessage.To.Value : "");
if (sipMessage.ToTag.length() > 0)
{
sbdMsg.append(";tag=" + sipMessage.ToTag + NewLine);
}
else
sbdMsg.append(NewLine);
sbdMsg.append(!sipMessage.Via.Value.empty() ? sipMessage.Via.Value + NewLine : "");
sbdMsg.append(!sipMessage.CSeq.Value.empty() ? sipMessage.CSeq.Value + NewLine : "");
sbdMsg.append(!sipMessage.CallID.Value.empty() ? sipMessage.CallID.Value + NewLine : "");
sbdMsg.append(!sipMessage.MaxForwards.Value.empty() ? sipMessage.MaxForwards.Value + NewLine : "");
sbdMsg.append(!sipMessage.Route.Value.empty() ? sipMessage.Route.Value + NewLine : "");
sbdMsg.append(!sipMessage.From.Value.empty() ? sipMessage.From.Value + NewLine : "");
sbdMsg.append(!sipMessage.Contact.Value.empty() ? sipMessage.Contact.Value + NewLine : "");
sbdMsg.append(!sipMessage.UserAgent.Value.empty() ? sipMessage.UserAgent.Value + NewLine : "");
sbdMsg.append(!sipMessage.Authorization.Value.empty() && sipMessage.Authorization.Value != "" ? sipMessage.Authorization.Value + NewLine : "");
sbdMsg.append(!sipMessage.Expires.Value.empty() ? sipMessage.Expires.Value + NewLine : "");
sbdMsg.append(!sipMessage.Date.empty() ? sipMessage.Date + NewLine : "");
sbdMsg.append(!sipMessage.TimeRevise.empty() ? sipMessage.TimeRevise + NewLine : "");
if (!sipMessage.BodyInfo.empty())
{
if (!String::endsWith(sipMessage.BodyInfo, NewLine))
sbdMsg.append(NewLine);
sbdMsg.append("Content-Length: " + to_string(sipMessage.BodyInfo.length()));
sbdMsg.append(NewLine);
sbdMsg.append(sipMessage.BodyInfo);
sbdMsg.append(NewLine);
}
else
{
sbdMsg.append("Content-Length: 0");
sbdMsg.append(NewLine);
}
sbdMsg.append(NewLine);
return sbdMsg;
}
string SipParaser::ParseSIPRequestToStr(SipMessage sipMessage)
{
string sbdMsg;
sbdMsg.append(SIPMethods::GetSIPMethodsEnumName(sipMessage.Method) + " " + SipVersionInfo + " " + sipMessage.DeviceID + "@" + sipMessage.Realm);
sbdMsg.append(NewLine);
sbdMsg.append(SipVersionInfo + " " + to_string((int)sipMessage.Status) + " " + SIPMethods::GetStatusCodesEnumName(sipMessage.Status));
sbdMsg.append(NewLine);
sbdMsg.append(!sipMessage.To.Value.empty() ? sipMessage.To.Value + NewLine : "");
sbdMsg.append(!sipMessage.Via.Value.empty() ? sipMessage.Via.Value + NewLine : "");
sbdMsg.append(!sipMessage.CSeq.Value.empty() ? sipMessage.CSeq.Value + NewLine : "");
sbdMsg.append(!sipMessage.CallID.Value.empty() ? sipMessage.CallID.Value + NewLine : "");
sbdMsg.append(!sipMessage.MaxForwards.Value.empty() ? sipMessage.MaxForwards.Value + NewLine : "");
sbdMsg.append(!sipMessage.Route.Value.empty() ? sipMessage.Route.Value + NewLine : "");
sbdMsg.append(!sipMessage.From.Value.empty() ? sipMessage.From.Value + NewLine : "");
sbdMsg.append(!sipMessage.Contact.Value.empty() ? sipMessage.Contact.Value + NewLine : "");
sbdMsg.append(!sipMessage.UserAgent.Value.empty() ? sipMessage.UserAgent.Value + NewLine : "");
if (!sipMessage.BodyInfo.empty())
{
if (!String::endsWith(sipMessage.BodyInfo, NewLine))
sbdMsg.append(NewLine);
sbdMsg.append("Content-Length: " +to_string( sipMessage.BodyInfo.length()));
sbdMsg.append(NewLine);
sbdMsg.append(NewLine);
sbdMsg.append(sipMessage.BodyInfo);
}
sbdMsg.append(NewLine);
return sbdMsg;
}
static Authorization ParseAuthorization(string AuthString)
{
Authorization auth;
try
{
map valDic;
valDic.insert(pair("Digestusername", &auth.Digest_username));
valDic.insert(pair("nonce", &auth.nonce));
valDic.insert(pair("uri", &auth.uri));
valDic.insert(pair("response", &auth.response));
valDic.insert(pair("opaque", &auth.opaque));
valDic.insert(pair("algorithm", &auth.algorithm));
valDic.insert(pair("realm", &auth.realm));
int valPos = AuthString.find(':') + 1;
AuthString=AuthString.substr(valPos);
AuthString=String::replace_all(AuthString, " ", "");
AuthString = String::replace_all(AuthString, "\"", "");
vector FromArr = String::split(AuthString, ",");
for each (string one in FromArr)
{
vector oneArr = String::split(one, "=");
map::iterator it = valDic.find(oneArr[0]);
if (it != valDic.end())
{
it->second->Value = one;
}
}
}
catch (exception ex)
{
}
return auth;
}
#include "stdafx.h"
#include "SipUdpChannel.h"
#include
#include
#include
#include"SipParaser.h"
#include"RTP.H"
#include
#include"SipConst.h"
#include
#include
#include"EventBase.h"
#pragma warning(disable:4996)
#pragma comment(lib, "WS2_32.lib")
using namespace std;
SipUdpChannel::SipUdpChannel()
{
mtx = new std::mutex();
}
SipUdpChannel::~SipUdpChannel()
{
if (receiveThread != nullptr)
delete receiveThread;
delete mtx;
mtx = nullptr;
}
bool SipUdpChannel::Start(string ip, int port)
{
if (InitSocket() < 0)
return false;
if (BindSocket(ip, port) < 0)
return false;
this->IsRuning = true;
receiveThread = new thread(&SipUdpChannel::ReceiveData, this);
return true;
}
void SipUdpChannel::Stop()
{
this->IsRuning = false;
receiveThread->join();
}
int SipUdpChannel::InitSocket()
{
WSAData wsdata;
if (WSAStartup(MAKEWORD(2, 2), &wsdata) != 0)
{
WSACleanup();
printf("WSAStartup failured \r\n");
return -1;
}
else
{
printf("WSAStartup OK\r\n");
}
return 0;
}
int SipUdpChannel::BindSocket(string ip, int port)
{
serverSocket = socket(AF_INET, SOCK_DGRAM, 0);
if (serverSocket == SOCKET_ERROR)
{
printf("sockclient create fail ! \n");
WSACleanup();
return(-1);
}
struct sockaddr_in serverAdd;
serverAdd.sin_family = AF_INET;
serverAdd.sin_addr.s_addr = htonl(INADDR_ANY);
serverAdd.sin_port = htons(port);
serverAdd.sin_addr.S_un.S_addr = inet_addr(LocalIP);
if (::bind(serverSocket, (SOCKADDR*)&serverAdd, sizeof(SOCKADDR)) == SOCKET_ERROR)
{
WSACleanup();
printf("Bind sipudp socket Failured %d\r\n", GetLastError());
return -1;
}
else {
printf("Bind sipudp OK\r\n");
}
return 0;
}
void SipUdpChannel::ReceiveData()
{
char buffer[1472] = { 0 };
RTP_Header rtp;
memset(&rtp, 0, sizeof(RTP_Header));
int len = 1472;
while (this->IsRuning)
{
try
{
sockaddr remoteEnd;
ZeroMemory((void*)&buffer, sizeof(buffer));
int reccout = recvfrom(serverSocket, buffer, (1472), 0, &remoteEnd, &len);
if (reccout <= 20)
{
Sleep(10);
continue;
}
string strMsg(buffer);
sockaddr_in sin;
memcpy(&sin, &remoteEnd, sizeof(remoteEnd));
string ipAdress = string(inet_ntoa(sin.sin_addr));
USHORT remotePort = sin.sin_port;
cout << "recieveMsg:\r\n" << strMsg << endl;
if (strMsg.find("SIP") == 0)
{
if (this->Response != nullptr)
{
this->Response->OnResponse(remoteEnd, ipAdress, remotePort, strMsg);
}
}
else
{
if (this->Request != nullptr)
{
this->Request->OnRequest(remoteEnd, ipAdress, remotePort, strMsg);
}
}
}
catch (exception ex)
{
cout << "SipUdpChannel::ReceiveData发生异常" << endl;
cout << ex.what() << endl;
}
}
}
void SipUdpChannel::SendData(sockaddr remoteEnd, string messsage)
{
if (!this->IsRuning)
{
return;
}
std::lock_guard mtx_locker(*mtx);
sendto(this->serverSocket, messsage.c_str(), messsage.size(), 0, (sockaddr *)&remoteEnd, sizeof(remoteEnd));
cout << "sendMsg:\r\n" << messsage << endl;
}
void SipUdpChannel::SendData(sockaddr remoteEnd, SipMessage messsage)
{
if (!this->IsRuning)
{
return;
}
string msg = SipParaser::ParseSIPRequestToStr(messsage);
std::lock_guard mtx_locker(*mtx);
sendto(this->serverSocket, msg.c_str(), msg.size(), 0, (sockaddr *)&remoteEnd, sizeof(remoteEnd));
cout << "sendMsg:\r\n" << msg << endl;
}
void SipUdpChannel::SendData(sockaddr remoteEnd, char *buffer)
{
if (!this->IsRuning)
{
return;
}
std::lock_guard mtx_locker(*mtx);
sendto(this->serverSocket, buffer, strlen(buffer), 0, (sockaddr *)&remoteEnd, sizeof(remoteEnd));
cout << "sendMsg:\r\n" << buffer << endl;
}
#include
#include "stdafx.h"
#include "SipServer.h"
#include
#include
#include "Ws2tcpip.h"
#include
#include"SipConst.h"
using namespace std;
#pragma warning(disable:4996)
SipServer::SipServer()
{
sipUdpChannel = new SipUdpChannel();
sipUdpChannel->Request = this;
sipUdpChannel->Response = this;
LastLoginTimeMap = new map();
this->ReadMonitorInfo();
}
SipServer::~SipServer()
{
this->SaveMonitorInfo();
if (sendRtpThread != nullptr)
delete sendRtpThread;
for (vector::iterator it = EventList.begin(); it != EventList.end(); it++)
if (NULL != *it)
{
delete *it;
*it = NULL;
}
EventList.clear();
map::iterator iter = SipMonitorMap.begin();
while (iter!= SipMonitorMap.end())
{
iter->second->StopRealplay();
delete iter->second;
iter++;
}
SipMonitorMap.clear();
delete sipUdpChannel;
delete LastLoginTimeMap;
}
bool SipServer::InitSocket()
{
WSAData wsdata;
if (WSAStartup(MAKEWORD(2, 2), &wsdata) != 0)
{
printf("client WSAStartup failured \r\n");
return FALSE;
}
else
{
printf("client WSAStartup OK\r\n");
return true;
}
}
void SipServer::SaveMonitorInfo()
{
ofstream savefile;
savefile.open("monitor.cfg", std::ofstream::out);
for (const auto& kv : *LastLoginTimeMap) {
savefile << kv.first << "!" << kv.second.toString() << endl;
}
savefile.close();
}
void SipServer::ReadMonitorInfo()
{
ifstream loadFile;
loadFile.open("monitor.cfg");
if (!loadFile)
return;
char buffer[300];
while (loadFile.getline(buffer,300 ))
{
string oneLine = buffer;
vector values = String::split(oneLine, "!");
LastLoginTimeMap->insert(pair(values[0], ec::Date::Date(values[1])));
}
loadFile.close();
}
bool SipServer::Start(string ip, int port)
{
if (InitSocket() == FALSE)
return FALSE;
this->isRuning = true;
sendRtpThread = new thread(&SipServer:: SendRptDataToRemoteCenter, this);
return sipUdpChannel->Start(ip,port);
}
bool SipServer::Stop()
{
/*for each (TaskWorking* oneTask in this->EventList)
{
this->RemoveEvent(oneTask);
}*/
this->isRuning = FALSE;
if (sendRtpThread != nullptr)
{
sendRtpThread->join();
delete sendRtpThread;
}
sipUdpChannel->Stop();
return TRUE;
}
void SipServer::OnResponse(sockaddr remoteEndPoint, string ipAdress, USHORT port, string rawMessage)
{
SipMessage response = SipParaser::ParseToSipMessage(rawMessage, TRUE);
vector stopedList;
for each (TaskWorking* oneTask in EventList)
{
if (oneTask->IsStoped())
{
stopedList.push_back(oneTask);
}
else
oneTask->OnResponse(response);
}
for each (TaskWorking* oneTask in stopedList)
{
this->RemoveEvent(oneTask);
}
SipMonitor *currentMonitor = nullptr;
map::iterator iter= SipMonitorMap.find(response.DeviceID);
if (iter != SipMonitorMap.end())
currentMonitor = iter->second;
else
return;
if (response.Status == SIPResponseStatusCodesEnum::OK)
{
string contentType = String::toLower(response.ContentType.Value);
if (!response.ContentType.Value.empty() && String::endsWith(contentType,"application/sdp"))
{
currentMonitor->AckRequest(response);
//device.CurrentMonitor.AckRequest(response);//开启媒体通道RTP channel,廖高波
//SDP sdp = SDP.ParseSDPDescription(response.BodyInfo);
//ack.ContentType = "SDP";
//ack.FileSize = sdp.filesize;
}
else
{
//设备给平台回复200 OK ,Bye后会收到
currentMonitor->Receive200OK(response);
}
}
else if (response.Status == SIPResponseStatusCodesEnum::Trying)
{
response.Status = SIPResponseStatusCodesEnum::OK;
// currentMonitor->Send200_OK_SDP(response);
}
}
void SipServer::OnRequest(sockaddr remoteEndPoint, string ipAdress, USHORT port, string rawMessage)
{
SipMessage request = SipParaser::ParseToSipMessage(rawMessage, false);
if (request.SessionID.empty())
{
request.Status = SIPResponseStatusCodesEnum::BadRequest;
this->sipUdpChannel->SendData(remoteEndPoint, SipParaser::ParseSipResponseToStr(request));
return;
}
SipMonitor *existSipMonitor = nullptr;
map::iterator iter = SipMonitorMap.find(request.DeviceID);
if (iter != SipMonitorMap.end())
{
existSipMonitor = iter->second;
}
if (request.Method == SIPMethodsEnum::REGISTER)
{
if (request.Authorization.Value.empty())
{
request.Status = SIPResponseStatusCodesEnum::Unauthorized;
char buffer[200];
ec::Time now;
__int64 ticks = now.getUTCFullSeconds();
sprintf_s(buffer, 200, "WWW-Authenticate: Digest realm=\"%s\",nonce=\"%lld\"", SipDomain, ticks);
request.Authorization.Value = buffer;
request.ToTag = CallProperties::CreateNewTag();
request.Contact.Value = "";
request.MaxForwards.Value = "";
request.UserAgent.Value = "";
request.Via.Value = String::replace_all_distinct(request.Via.Value, "rport", "rport" + std::to_string(port) + ";received=" + ipAdress);
string sendMsg = SipParaser::ParseSipResponseToStr(request);
this->sipUdpChannel->SendData(remoteEndPoint, sendMsg);
}
else
{
ec::Date now;
request.Date = "Date: " + now.toString();//test
char buffer[200];
sprintf_s(buffer, 200, "TimeRevise: %d4%d2%d2%d2%d2%d5", now.year(), now.month(), now.day(), now.hour(), now.minute(), now.second());
request.TimeRevise = buffer;
request.Status = SIPResponseStatusCodesEnum::OK;//doRegister return
string sendMsg = SipParaser::ParseSipResponseToStr(request);
this->sipUdpChannel->SendData(remoteEndPoint, sendMsg);
if (request.Status == SIPResponseStatusCodesEnum::OK)
{
if (existSipMonitor == nullptr)
{
existSipMonitor = new SipMonitor(this, this->sipUdpChannel, request.DeviceID, remoteEndPoint, ipAdress, port);
}
else
{
if (existSipMonitor->GetIpAdress() != ipAdress || existSipMonitor->GetRemotePort() != port)
{
SipMonitorMap.erase(request.DeviceID);
delete existSipMonitor;
existSipMonitor = new SipMonitor(this, this->sipUdpChannel, request.DeviceID, remoteEndPoint, ipAdress, port);
}
}
map::iterator result = LastLoginTimeMap->find(request.SessionID);
if (result != LastLoginTimeMap->end())
{
result->second = ec::Date();
}
else
{
LastLoginTimeMap->insert(pair(request.DeviceID, ec::Date()));
}
existSipMonitor->SetRegisterTime(ec::Date::Date());
SipMonitorMap.insert(std::pair(request.DeviceID, existSipMonitor));
Sleep(2000);//test
existSipMonitor->RealVideoReq();//test
}
}
}
else if (request.Method == SIPMethodsEnum::MESSAGE)
{
if (existSipMonitor != nullptr)
{
ec::Duration ts = ec::Date::Date() - existSipMonitor->LastRegisterTime;
if (ts.valueAs(ec::Duration::Second) < 3600)
{
existSipMonitor->LastRegisterTime = ec::Date::Date();
}
else
{
request.Status = SIPResponseStatusCodesEnum::Unauthorized;
this->sipUdpChannel->SendData(remoteEndPoint, SipParaser::ParseSipResponseToStr(request));
return;
}
existSipMonitor->SetRegisterTime(ec::Date::Date());
request.To.Value += ";tag=" + CallProperties::CreateNewTag();//Mesaage回复的时候,添加一个Tag就OK了,其它都一样。
existSipMonitor->Send200_OK(request);
map::iterator result = LastLoginTimeMap->find(request.DeviceID);
if (result != LastLoginTimeMap->end())
{
result->second = ec::Date();
}
else
{
LastLoginTimeMap->insert(pair(request.DeviceID, ec::Date()));
}
}
else
{
map::iterator result = LastLoginTimeMap->find(request.DeviceID);
if (result != LastLoginTimeMap->end())
{
ec::Duration ts = ec::Date::Date() - result->second;
// if (ts.valueAs(ec::Duration::Second) < 3600) test先去掉
{
existSipMonitor = new SipMonitor(this, this->sipUdpChannel, request.DeviceID, remoteEndPoint, ipAdress, port);
existSipMonitor->SetRegisterTime(ec::Date::Date());
SipMonitorMap.insert(std::pair(request.DeviceID, existSipMonitor));
result->second = ec::Date::Date();
existSipMonitor->Send200_OK(request);
existSipMonitor->RealVideoReq();//test
cout << " 已发送视频请求" << endl;
}
}
}
}
else if (request.Method == SIPMethodsEnum::BYE)
{
if (existSipMonitor != nullptr)
{
// device.IsOnline = true;//公有消息,全部发布
// device.LastOnline = DateTime.Now;
existSipMonitor->Send200_OK(request);
}
}
}
void SipServer::AddEvent(TaskWorking *event)
{
this->EventList.push_back(event);
}
void SipServer::RemoveEvent(TaskWorking*event)
{
vector::iterator it = find(EventList.begin(), EventList.end(), event);
if (it != EventList.end())
{
EventList.erase(it);
if (NULL != *it)
{
delete *it;
*it = NULL;
}
}
}
//暂时不用
void SipServer::SendRptDataToRemoteCenter()
{
struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_port = htons(8060);
addr.sin_addr.S_un.S_addr = inet_addr(LandServerIP);
while (this->isRuning)
{
try
{
if (WaitSendRtpQueue.empty())
{
Sleep(10);
continue;
}
std::lock_guard mtx_locker(RtpMtx);
RtpDataPack onePack = WaitSendRtpQueue.front();
WaitSendRtpQueue.pop();
sendto(clientSocket, onePack.buffer, onePack.len, 0, (sockaddr *)&addr, sizeof(addr));
delete onePack.buffer;
}
catch (exception ex)
{
cout << "SendRptDataToRemoteCenter发生异常" << endl;
cout << ex.what() << endl;
}
}
}
#include "stdafx.h"
#include "SipMonitor.h"
#include "SipServer.h"
#include "CommonData.h"
#include "SipConst.h"
#include "SipParaser.h"
#include "CallProperties.h"
#include "TaskWorking.h"
SipMonitor::SipMonitor(SipServer *asipServer, SipUdpChannel *udpChannel, string deviceID, sockaddr remoteEnd, string ipAdress, USHORT remotePort)
{
DeviceID = deviceID;
sipRemoteEnd = remoteEnd;
sipUdpChannel = udpChannel;
sipServer = asipServer;
IpAdress = ipAdress;
sipRemotePort = remotePort;
}
SipMonitor::~SipMonitor()
{
this->StopRealplay();
}
void SipMonitor::RealVideoReq()
{
if (realVideoMsg != nullptr)
{
return;
}
string fromTag = CallProperties::CreateNewTag();
sessionID = CallProperties::CreateNewCallId();
string branch = CallProperties::CreateBranchId();
int SeqRealVideoReq = CallProperties::CreateNewCSeq();
string sdbBody;
sdbBody.append("v=0"+ NewLine);
char buffer[300];
_snprintf_s(buffer,300, "o=%s 0 0 IN IP4 %s", SipID, LandServerIP);
sdbBody.append(buffer + NewLine);
string channleID ="0";
sdbBody.append("s=Play" + NewLine);
sdbBody.append("u=" + channleID + ":3" + NewLine);//通道+类型
_snprintf_s(buffer,300, "c=IN IP4 %s", LandServerIP);
sdbBody.append(buffer + NewLine);
sdbBody.append("t=0 0");
sdbBody.append(NewLine);
_snprintf_s(buffer,300, "m=video %d RTP/AVP 96 98 97", CommonData::RPT_Port);
sdbBody.append(buffer + NewLine);
sdbBody.append("a=recvonly" + NewLine);
sdbBody.append("a=rtpmap:96 PS/90000" + NewLine);
sdbBody.append("a=rtpmap:98 H264/90000" + NewLine);
sdbBody.append("a=rtpmap:97 MPEG4/90000" + NewLine);
sdbBody.append("y=0100000001" + NewLine);
sdbBody.append("a=stream:1" + NewLine);
//主码流a=stream:0(子码流为a=stream:1)
sdbBody.append("f=" + NewLine);
string sbd;
sprintf_s(buffer, 300, "INVITE sip:%s@%s:%d SIP/2.0", this->DeviceID.c_str(), this->IpAdress.c_str(), this->sipRemotePort);
sbd.append(buffer+NewLine);
sprintf_s(buffer, 300, "Call-ID: %s", sessionID.c_str());
sbd.append(buffer);
sbd.append(NewLine);
sprintf_s(buffer, 300, "CSeq: %d INVITE", SeqRealVideoReq);
sbd.append(buffer);
sbd.append(NewLine);
sprintf_s(buffer, 300, "From: ;tag=%s", SipID, LandServerIP, LandServerPort, fromTag.c_str());
sbd.append(buffer);
sbd.append(NewLine);
sprintf_s(buffer, 300, "To: ", this->DeviceID.c_str(), this->IpAdress.c_str(), this->sipRemotePort);
sbd.append(buffer);
sbd.append(NewLine);
sprintf_s(buffer, 300, "Via: SIP/2.0/UDP %s:%d;branch=%s", LandServerIP, LandServerPort, branch.c_str());
sbd.append(buffer);
sbd.append(NewLine);
sbd.append("Max-Forwards: 70");
sbd.append(NewLine);
sprintf_s(buffer, 300, "Contact: \"%s\" ", SipID, LandServerIP, LandServerPort);
sbd.append(buffer);
sbd.append(NewLine);
sbd.append("User-Agent: VisionVera1.0");
//sbd.AppendLine("Subject:34020000001320000001:0,94020000002020000001:0");
//Subject:媒体流发送者设备编码:发送端媒体流序列,媒体流接收者设备编码:接收端媒体流序列号
sbd.append(NewLine);
sbd.append("Content-Type: Application/SDP");
sbd.append(NewLine);
sprintf_s(buffer, 300, "Route: ", this->DeviceID.c_str(), this->IpAdress.c_str(), this->sipRemotePort);
sbd.append(buffer);
sbd.append(NewLine);
sbd.append("User-Agent: yunkun2.0");
sbd.append(NewLine);
sbd.append("Expires: ");
sbd.append(to_string(SipConst::ExpiresTime));
sbd.append(NewLine);
sbd.append("Content-Length: ");
sbd.append(to_string(sdbBody.size()));
sbd.append(NewLine);
sbd.append(NewLine);
sbd.append(sdbBody);
sbd.append(NewLine);
SipMessage request = SipParaser::ParseToSipMessage(sbd, false);
this->realVideoMsg = new SipMessage(request);
request.SessionID = sessionID;
sipUdpChannel->SendData(sipRemoteEnd, sbd);
TaskWorking *taskWoking = new TaskWorking(sipServer, request,sipUdpChannel, sipRemoteEnd);
}
string SipMonitor::GetIpAdress()
{
return this->IpAdress;
}
USHORT SipMonitor::GetRemotePort()
{
return this->sipRemotePort;
}
string SipMonitor::GetDeviceID()
{
return this->DeviceID;
}
void SipMonitor::SetRegisterTime(ec::Date lastRegisterTime)
{
LastRegisterTime = lastRegisterTime;
}
void SipMonitor::Send200_OK(SipMessage request)
{//200 OK 是不考虑重发的哦。
// ISipSession sipSession;
// _device.SipMessageSessions.TryRemove(request.SessionID, out sipSession);
request.BodyInfo = "";
request.Status = SIPResponseStatusCodesEnum::OK;
string rawMsg = SipParaser::ParseSipResponseToStr(request);
this->sipUdpChannel->SendData(this->sipRemoteEnd, rawMsg);
cout <<"sendMessage:"<< rawMsg << endl;
}
void SipMonitor::Send200_OK_SDP(SipMessage request)
{//200 OK 是不考虑重发的哦。
// ISipSession sipSession;
// _device.SipMessageSessions.TryRemove(request.SessionID, out sipSession);
request.Status = SIPResponseStatusCodesEnum::OK;
string rawMsg = SipParaser::ParseSipResponseToStr(request);
this->sipUdpChannel->SendData(this->sipRemoteEnd, rawMsg);
}
void SipMonitor::SayBye(SipMessage sipMsg)
{
string sdbBye;
char buffer[200];
sprintf_s(buffer, 200, "BYTE sip:%s@%s:%d SIP/2.0", this->DeviceID.c_str(), this->IpAdress.c_str(), this->sipRemotePort);
sdbBye.append(buffer + NewLine);
sdbBye.append(sipMsg.CallID.Value + NewLine);
sdbBye.append(sipMsg.To.Value + NewLine);
string fromTag = CallProperties::CreateNewTag();
sprintf_s(buffer, 200, "Via: SIP/2.0/UDP %s:%d;branch=%s", this->IpAdress.c_str(), this->sipRemotePort,fromTag.c_str());
sdbBye.append(buffer + NewLine);
sprintf_s(buffer, 200, "CSeq: %d BYE", CallProperties::CreateNewCSeq());
sdbBye.append(buffer + NewLine);
sdbBye.append(sipMsg.From.Value + NewLine);
sdbBye.append("Max-Forwards: 70" + NewLine);
sdbBye.append("Content-Length: 0" + NewLine);
sdbBye.append(NewLine);
SipMessage sipResult = SipParaser::ParseToSipMessage(sdbBye, false);
this->sipUdpChannel->SendData(this->sipRemoteEnd, sdbBye);
TaskWorking *taskWoking = new TaskWorking(sipServer, sipResult, sipUdpChannel, sipRemoteEnd);
}
void SipMonitor::Receive200OK(SipMessage response)
{
}
void SipMonitor::AckRequest(SipMessage response)
{
if (rtpChannel != nullptr)
return;
// this->StopRealplay();
string sbd;
char buffer[300];
sprintf_s(buffer, 300, "ACK sip:%s@%s:%d SIP/2.0", this->DeviceID.c_str(), this->IpAdress.c_str(), this->sipRemotePort);
sbd.append(buffer + NewLine);
sbd.append(!response.From.Value.empty() ? response.From.Value + NewLine : "");
sbd.append(!response.To.Value.empty() ? response.To.Value + NewLine : "");
sbd.append("Max-Forwards: 70"+NewLine);
string fromTag = CallProperties::CreateNewTag();
sprintf_s(buffer, 300, "Via: SIP/2.0/UDP %s:%d;branch=%s", this->IpAdress.c_str(), this->sipRemotePort, fromTag.c_str());
sbd.append(buffer + NewLine);
int cSeq = CallProperties::CreateNewCSeq();
sprintf_s(buffer, 300, "CSeq: %d INVITE", cSeq);
sbd.append(buffer + NewLine);
sbd.append(response.CallID.Value + NewLine);
sbd.append("User-Agent: sunq1.0" + NewLine);
sbd.append("Content-Length: 0" + NewLine);
sbd.append(NewLine);
this->sipUdpChannel->SendData(this->sipRemoteEnd, sbd);
rtpChannel = new RtpChannel(CommonData::RPT_Port, this->DeviceID, &sipServer->RtpMtx, &sipServer->WaitSendRtpQueue);
// SipMessage sipResult = SipParaser::ParseToSipMessage(sbd, false);
// TaskWorking *taskWoking = new TaskWorking(sipServer, sipResult, sipUdpChannel, sipRemoteEnd);
}
void SipMonitor::StopRealplay()
{
if (realVideoMsg != nullptr)
{
this->SayBye(*realVideoMsg);
delete realVideoMsg;
realVideoMsg = nullptr;
}
if (rtpChannel != nullptr)
{
rtpChannel->Stop();
delete rtpChannel;
rtpChannel = nullptr;
}
}