diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json
new file mode 100644
index 0000000..a33b5b9
--- /dev/null
+++ b/.vscode/c_cpp_properties.json
@@ -0,0 +1,18 @@
+{
+ "configurations": [
+ {
+ "name": "linux-gcc-arm64",
+ "includePath": [
+ "${workspaceFolder}/**"
+ ],
+ "compilerPath": "/usr/bin/gcc",
+ "cStandard": "${default}",
+ "cppStandard": "${default}",
+ "intelliSenseMode": "linux-gcc-arm64",
+ "compilerArgs": [
+ ""
+ ]
+ }
+ ],
+ "version": 4
+}
\ No newline at end of file
diff --git a/.vscode/settings.json b/.vscode/settings.json
index f8b7f72..ec738ba 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -1,82 +1,139 @@
{
- "files.associations": {
- "*.ipp": "cpp",
- "cctype": "cpp",
- "clocale": "cpp",
- "cmath": "cpp",
- "csetjmp": "cpp",
- "csignal": "cpp",
- "cstdarg": "cpp",
- "cstddef": "cpp",
- "cstdio": "cpp",
- "cstdlib": "cpp",
- "cstring": "cpp",
- "ctime": "cpp",
- "cwchar": "cpp",
- "cwctype": "cpp",
- "any": "cpp",
- "array": "cpp",
- "atomic": "cpp",
- "strstream": "cpp",
- "bit": "cpp",
- "*.tcc": "cpp",
- "bitset": "cpp",
- "cfenv": "cpp",
- "charconv": "cpp",
- "chrono": "cpp",
- "cinttypes": "cpp",
- "codecvt": "cpp",
- "complex": "cpp",
- "condition_variable": "cpp",
- "cstdint": "cpp",
- "deque": "cpp",
- "forward_list": "cpp",
- "list": "cpp",
- "map": "cpp",
- "set": "cpp",
- "unordered_map": "cpp",
- "unordered_set": "cpp",
- "vector": "cpp",
- "exception": "cpp",
- "algorithm": "cpp",
- "functional": "cpp",
- "iterator": "cpp",
- "memory": "cpp",
- "memory_resource": "cpp",
- "numeric": "cpp",
- "optional": "cpp",
- "random": "cpp",
- "ratio": "cpp",
- "regex": "cpp",
- "source_location": "cpp",
- "string": "cpp",
- "string_view": "cpp",
- "system_error": "cpp",
- "tuple": "cpp",
- "type_traits": "cpp",
- "utility": "cpp",
- "rope": "cpp",
- "slist": "cpp",
- "fstream": "cpp",
- "future": "cpp",
- "initializer_list": "cpp",
- "iomanip": "cpp",
- "iosfwd": "cpp",
- "iostream": "cpp",
- "istream": "cpp",
- "limits": "cpp",
- "mutex": "cpp",
- "new": "cpp",
- "ostream": "cpp",
- "scoped_allocator": "cpp",
- "shared_mutex": "cpp",
- "sstream": "cpp",
- "stdexcept": "cpp",
- "streambuf": "cpp",
- "thread": "cpp",
- "typeindex": "cpp",
- "typeinfo": "cpp",
- "valarray": "cpp",
- "variant": "cpp"
- }
+ "files.associations": {
+ "*.ipp": "cpp",
+ "cctype": "cpp",
+ "clocale": "cpp",
+ "cmath": "cpp",
+ "csetjmp": "cpp",
+ "csignal": "cpp",
+ "cstdarg": "cpp",
+ "cstddef": "cpp",
+ "cstdio": "cpp",
+ "cstdlib": "cpp",
+ "cstring": "cpp",
+ "ctime": "cpp",
+ "cwchar": "cpp",
+ "cwctype": "cpp",
+ "any": "cpp",
+ "array": "cpp",
+ "atomic": "cpp",
+ "strstream": "cpp",
+ "bit": "cpp",
+ "*.tcc": "cpp",
+ "bitset": "cpp",
+ "cfenv": "cpp",
+ "charconv": "cpp",
+ "chrono": "cpp",
+ "cinttypes": "cpp",
+ "codecvt": "cpp",
+ "complex": "cpp",
+ "condition_variable": "cpp",
+ "cstdint": "cpp",
+ "deque": "cpp",
+ "forward_list": "cpp",
+ "list": "cpp",
+ "map": "cpp",
+ "set": "cpp",
+ "unordered_map": "cpp",
+ "unordered_set": "cpp",
+ "vector": "cpp",
+ "exception": "cpp",
+ "algorithm": "cpp",
+ "functional": "cpp",
+ "iterator": "cpp",
+ "memory": "cpp",
+ "memory_resource": "cpp",
+ "numeric": "cpp",
+ "optional": "cpp",
+ "random": "cpp",
+ "ratio": "cpp",
+ "regex": "cpp",
+ "source_location": "cpp",
+ "string": "cpp",
+ "string_view": "cpp",
+ "system_error": "cpp",
+ "tuple": "cpp",
+ "type_traits": "cpp",
+ "utility": "cpp",
+ "rope": "cpp",
+ "slist": "cpp",
+ "fstream": "cpp",
+ "future": "cpp",
+ "initializer_list": "cpp",
+ "iomanip": "cpp",
+ "iosfwd": "cpp",
+ "iostream": "cpp",
+ "istream": "cpp",
+ "limits": "cpp",
+ "mutex": "cpp",
+ "new": "cpp",
+ "ostream": "cpp",
+ "scoped_allocator": "cpp",
+ "shared_mutex": "cpp",
+ "sstream": "cpp",
+ "stdexcept": "cpp",
+ "streambuf": "cpp",
+ "thread": "cpp",
+ "typeindex": "cpp",
+ "typeinfo": "cpp",
+ "valarray": "cpp",
+ "variant": "cpp"
+ },
+ "C_Cpp_Runner.cCompilerPath": "gcc",
+ "C_Cpp_Runner.cppCompilerPath": "g++",
+ "C_Cpp_Runner.debuggerPath": "gdb",
+ "C_Cpp_Runner.cStandard": "",
+ "C_Cpp_Runner.cppStandard": "",
+ "C_Cpp_Runner.msvcBatchPath": "",
+ "C_Cpp_Runner.useMsvc": false,
+ "C_Cpp_Runner.warnings": [
+ "-Wall",
+ "-Wextra",
+ "-Wpedantic",
+ "-Wshadow",
+ "-Wformat=2",
+ "-Wcast-align",
+ "-Wconversion",
+ "-Wsign-conversion",
+ "-Wnull-dereference"
+ ],
+ "C_Cpp_Runner.msvcWarnings": [
+ "/W4",
+ "/permissive-",
+ "/w14242",
+ "/w14287",
+ "/w14296",
+ "/w14311",
+ "/w14826",
+ "/w44062",
+ "/w44242",
+ "/w14905",
+ "/w14906",
+ "/w14263",
+ "/w44265",
+ "/w14928"
+ ],
+ "C_Cpp_Runner.enableWarnings": true,
+ "C_Cpp_Runner.warningsAsError": false,
+ "C_Cpp_Runner.compilerArgs": [],
+ "C_Cpp_Runner.linkerArgs": [],
+ "C_Cpp_Runner.includePaths": [],
+ "C_Cpp_Runner.includeSearch": [
+ "*",
+ "**/*"
+ ],
+ "C_Cpp_Runner.excludeSearch": [
+ "**/build",
+ "**/build/**",
+ "**/.*",
+ "**/.*/**",
+ "**/.vscode",
+ "**/.vscode/**"
+ ],
+ "C_Cpp_Runner.useAddressSanitizer": false,
+ "C_Cpp_Runner.useUndefinedSanitizer": false,
+ "C_Cpp_Runner.useLeakSanitizer": false,
+ "C_Cpp_Runner.showCompilationTime": false,
+ "C_Cpp_Runner.useLinkTimeOptimization": false,
+ "C_Cpp_Runner.msvcSecureNoWarnings": false
}
\ No newline at end of file
diff --git a/bin/sip_server b/bin/sip_server
deleted file mode 100755
index 522bc39..0000000
--- a/bin/sip_server
+++ /dev/null
diff --git a/bin/sip_server_cfg.xml b/bin/sip_server_cfg.xml
index cbc3ce0..abbb682 100644
--- a/bin/sip_server_cfg.xml
+++ b/bin/sip_server_cfg.xml
@@ -9,5 +9,5 @@
1800
3600
- 9006
+ 9007
diff --git a/sip/ConfigParser.hpp b/sip/ConfigParser.hpp
index 21cff96..44aa0db 100644
--- a/sip/ConfigParser.hpp
+++ b/sip/ConfigParser.hpp
@@ -2,7 +2,7 @@
#define __CONFIG_PARSER_H__
#include
-#include "./Message/CatalogParser.h"
+#include "./Message/GBXmlParser.h"
#include "sip_header.h"
#include "./Utils/logger.hpp"
@@ -48,7 +48,7 @@ bool ConfigParser::init() {
{
strConfig += str;
}
- CCatalogParser catPaser;
+ GBXmlParser catPaser;
mInfo = catPaser.DecodeServerConfig(strConfig.c_str());
} else {
LOG_ERROR("read config file failed!");
diff --git a/sip/Message/CatalogParser.cpp b/sip/Message/GBXmlParser.cpp
index ef7cc58..c5c91dc 100644
--- a/sip/Message/CatalogParser.cpp
+++ b/sip/Message/GBXmlParser.cpp
@@ -1,8 +1,9 @@
-#include "CatalogParser.h"
+#include "GBXmlParser.h"
#include
#include
#include "../Utils/logger.hpp"
+#include "../Utils/StringTools.hpp"
static const char* g_event_desc[] =
{
@@ -16,7 +17,7 @@ static const char* g_event_desc[] =
};
-bool CCatalogParser::Encode( std::string &message )
+bool GBXmlParser::Encode( std::string &message )
{
std::ostringstream content;
content<<"\r\n";
@@ -170,7 +171,7 @@ bool CCatalogParser::Encode( std::string &message )
return true;
}
-std::vector< DeviceInfo > CCatalogParser::Decode( const std::vector< tinyxml2::XMLNode* > &nodes)
+std::vector< DeviceInfo > GBXmlParser::Decode( const std::vector< tinyxml2::XMLNode* > &nodes)
{
std::vector< DeviceInfo > cat_list;
// 必须参数校验
@@ -439,7 +440,13 @@ std::vector< DeviceInfo > CCatalogParser::Decode( const std::vector< tinyxml2::X
}
else if( CGBMessage::CompareNoCase( type, "Status" ) )
{
- catalog.status = value;
+ string status = StringTools::trim(value);
+ transform(status.begin(), status.end(), status.begin(),::tolower);
+ if (status == "on"){
+ catalog.status = STATUS_ON;
+ } else {
+ catalog.status = STATUS_OFF;
+ }
}
else if( CGBMessage::CompareNoCase( type, "Longitude" ) )
{
@@ -557,7 +564,7 @@ std::vector< DeviceInfo > CCatalogParser::Decode( const std::vector< tinyxml2::X
return m_devices;
}
-std::vector< DeviceInfo > CCatalogParser::DecodeCatlog(const char* body)
+std::vector< DeviceInfo > GBXmlParser::DecodeCatlog(const char* body)
{
std::vector< DeviceInfo > cat_list;
if (body == NULL)
@@ -632,7 +639,7 @@ std::vector< DeviceInfo > CCatalogParser::DecodeCatlog(const char* body)
return cat_list;
}
-DeviceInfo CCatalogParser::DecodeDeviceInfo(const char* body)
+DeviceInfo GBXmlParser::DecodeDeviceInfo(const char* body)
{
DeviceInfo info;
@@ -671,7 +678,7 @@ DeviceInfo CCatalogParser::DecodeDeviceInfo(const char* body)
return info;
}
-string CCatalogParser::getItemValue(tinyxml2::XMLNode *pItem) {
+string GBXmlParser::getItemValue(tinyxml2::XMLNode *pItem) {
tinyxml2::XMLNode *pValue = pItem->FirstChild();
if( pValue == NULL ) {
@@ -688,7 +695,7 @@ string CCatalogParser::getItemValue(tinyxml2::XMLNode *pItem) {
return value;
}
-ServerInfo CCatalogParser::DecodeServerConfig(const char* body)
+ServerInfo GBXmlParser::DecodeServerConfig(const char* body)
{
ServerInfo info;
if (body == NULL) {
@@ -757,4 +764,45 @@ ServerInfo CCatalogParser::DecodeServerConfig(const char* body)
}
return info;
+}
+
+vector GBXmlParser::ParseKeepalive(const char* body) {
+ // LOG_DEBUG( "{}", body);
+
+ std::vector< string > device_id_list;
+ if (body == NULL)
+ {
+ return device_id_list;
+ }
+
+ tinyxml2::XMLDocument doc;
+ doc.Parse(body);
+ tinyxml2::XMLElement* pRoot = doc.RootElement();
+ if (pRoot == nullptr) {
+ return device_id_list;
+ }
+
+ tinyxml2::XMLNode* pInfo = nullptr;
+ std::vector< tinyxml2::XMLNode* > nodes;
+ for (tinyxml2::XMLNode* pNode = pRoot->FirstChild(); pNode != 0; pNode = pNode->NextSibling()) {
+ std::string value = pNode->Value();
+ if (value == "Info") {
+ pInfo = pNode;
+ break;
+ }
+ }
+
+ if (pInfo == nullptr) {
+ return device_id_list;
+ }
+
+ for (tinyxml2::XMLNode* pNode = pInfo->FirstChild(); pNode != 0; pNode = pNode->NextSibling()) {
+ std::string type = pNode->Value();
+
+ if (CGBMessage::CompareNoCase( type, "DeviceID" )) {
+ device_id_list.push_back(getItemValue(pNode));
+ }
+ }
+
+ return device_id_list;
}
\ No newline at end of file
diff --git a/sip/Message/CatalogParser.h b/sip/Message/GBXmlParser.h
index f336c1d..5afd148 100644
--- a/sip/Message/CatalogParser.h
+++ b/sip/Message/GBXmlParser.h
@@ -6,10 +6,10 @@
#include "../sip_header.h"
-class CCatalogParser : public CGBMessage
+class GBXmlParser : public CGBMessage
{
public:
- CCatalogParser()
+ GBXmlParser()
{
}
@@ -22,6 +22,8 @@ public:
ServerInfo DecodeServerConfig(const char* body);
+ vector ParseKeepalive(const char* body);
+
static std::string GetStrName(EEventType eType)
{
switch (eType)
diff --git a/sip/SipServer.cpp b/sip/SipServer.cpp
index 7442d91..a64e67f 100644
--- a/sip/SipServer.cpp
+++ b/sip/SipServer.cpp
@@ -35,16 +35,6 @@ static void event_loop_thread(void* arg) {
}
}
-static void timing_getcatlog_thread(void* arg) {
- SipServer* _this = (SipServer*)arg;
- if (_this != nullptr) {
- _this->timing_getcatlog();
- }
- else {
- LOG_ERROR("timing_getcatlog 线程启动失败 !");
- }
-}
-
static void dt_printSipMsg(osip_message_t* msg) {
osip_message_t* clone_event = NULL;
size_t length = 0;
@@ -276,8 +266,6 @@ void SipServer::event_loop() {
}
LOG_INFO("sip server init succeed: {}:{}", mInfo.getIp(), mInfo.getPort());
-
- thread* timing_getcatlog_threadptr = new std::thread(timing_getcatlog_thread, this);
while(!mQuit) {
eXosip_event_t *evtp = eXosip_event_wait(mSipCtx, 0, 20);
@@ -292,11 +280,6 @@ void SipServer::event_loop() {
}
mQuit = true;
- if (timing_getcatlog_threadptr) {
- timing_getcatlog_threadptr->join();
- delete timing_getcatlog_threadptr;
- timing_getcatlog_threadptr = nullptr;
- }
}
void SipServer::Close() {
@@ -310,14 +293,6 @@ void SipServer::Close() {
}
-void SipServer::timing_getcatlog() {
- while(!mQuit) {
- // 5分钟更新一次
- std::this_thread::sleep_for(std::chrono::minutes(5));
- cacheCatalog();
- }
-}
-
void SipServer::response_message_answer(eXosip_event_t *evtp,int code){
int returnCode = 0 ;
@@ -497,10 +472,13 @@ void SipServer::cacheClient(osip_uri_t *url, int expiry) {
if (type >= 111 && type <= 130) {
// NVR注册成功,立即请求设备目录
RequestCatalog(client);
+ client->setDeviceType(DEVICE_TYPE_NVR);
} else if (type >= 131 && type <= 199) {
RequestDeviceInfo(client);
+ client->setDeviceType(DEVICE_TYPE_IPC);
} else if (type >= 200 && type <= 299) {
RequestCatalog(client);
+ client->setDeviceType(DEVICE_TYPE_PLATFORM);
} else {
LOG_WARN("device type is not supported:{}",type);
}
@@ -555,12 +533,12 @@ void SipServer::response_message(eXosip_event_t *evtp) {
return;
}
- LOG_INFO("CmdType={},DeviceID={}", CmdType, DeviceID);
+ LOG_INFO("{} - {}", CmdType, DeviceID);
if(!strcmp(CmdType, "Catalog")) {
this->response_message_answer(evtp,200);
// 需要根据对方的Catelog请求,做一些相应的应答请求
- CCatalogParser catPaser;
+ GBXmlParser catPaser;
std::vector vec_device = catPaser.DecodeCatlog(body->body);
printDevice(vec_device);
@@ -572,9 +550,9 @@ void SipServer::response_message(eXosip_event_t *evtp) {
} else if (!strcmp(CmdType, "DeviceInfo")) {
this->response_message_answer(evtp, 200);
// 需要根据对方的Catelog请求,做一些相应的应答请求
- CCatalogParser catPaser;
+ GBXmlParser catPaser;
DeviceInfo info = catPaser.DecodeDeviceInfo(body->body);
- info.status = "on"; // 有值返回就已经可以表明设备状态在线了
+ info.status = STATUS_ON; // 有值返回就已经可以表明设备状态在线了
std::lock_guard l(m_device_map_mtx);
m_device_map[info.id] = info;
@@ -583,8 +561,35 @@ void SipServer::response_message(eXosip_event_t *evtp) {
std::lock_guard l_c(m_client_map_mtx);
auto it = mClientMap.find(DeviceID);
if (it != mClientMap.end()) {
+
+ Client* client = it->second;
+ client->updateHeartBeat(Utools::get_cur_time_ms());
+ DeviceType type = client->getDeviceType();
+ if (DEVICE_TYPE_NVR == type || DEVICE_TYPE_PLATFORM == type) {
+ GBXmlParser xmlPaser;
+ vector vec_id = xmlPaser.ParseKeepalive(body->body);
+
+ std::lock_guard l_d(m_device_map_mtx);
+ for (auto it_device = m_device_map.begin(); it_device != m_device_map.end(); it_device++) {
+ string device_id = it_device->first;
+ bool bOff = false;
+ for (size_t i = 0; i < vec_id.size(); i++) {
+ string dev_id = vec_id[i];
+ if (dev_id == device_id) {
+ it_device->second.status = STATUS_OFF;
+ bOff = true;
+ }
+ }
+ if (!bOff) {
+ //修正短时间off又on后无法变回on的问题
+ it_device->second.status = STATUS_ON;
+ }
+
+ }
+ }
+
response_message_answer(evtp,200);
- it->second->updateHeartBeat(Utools::get_cur_time_ms());
+
return ;
} else {
// 未注册设备发保活信息,超过设备的最大超时次数后,设备将进行初始注册
@@ -602,9 +607,8 @@ bool SipServer::check_device_status(string id) {
return false;
}
- string status = StringTools::trim(it_info->second.status);
- transform(status.begin(), status.end(), status.begin(),::tolower);
- if (status == "on"){
+ DeviceStatus status = it_info->second.status;
+ if (STATUS_ON == status){
return true;
}
@@ -844,59 +848,6 @@ int SipServer::RequestInvite_TCP_a(const char* dst_channel, const char* rtpIp, i
return call_id;
}
-void SipServer::cacheCatalog() {
-
- std::lock_guard l(m_client_map_mtx);
-
- if (mClientMap.size() <= 0){
- LOG_WARN("NO IPC");
- return ;
- }
-
- long cur_ts = Utools::get_cur_time_ms();
-
- vector vec_sip_id;
-
- LOG_INFO("client size:{}", mClientMap.size());
- for (auto it = mClientMap.begin(); it != mClientMap.end(); it++) {
- //RequestCatalog(it->second);
- Client* client = it->second;
- if (!client) {
- continue;
- }
-
- string sip_id = client->getDevice();
-
- unsigned long gap = client->getHeartBeatGap();
- if (gap > 0 && (cur_ts - client->getHeartBeat()) > 10 * gap) {
- LOG_WARN("{}:超过10个心跳周期未收到心跳", sip_id);
- vec_sip_id.push_back(sip_id);
- continue;
- }
-
- int type = check_device_type(sip_id);
- if (-1 == type) {
- continue;
- }
-
- if (type >= 111 && type <= 130) {
- // NVR注册成功,立即请求设备目录
- RequestCatalog(client);
- } else if (type >= 131 && type <= 199) {
- RequestDeviceInfo(client);
- } else if (type >= 200 && type <= 299) {
- RequestCatalog(client);
- } else {
- LOG_WARN("device type is not supported:{}",type);
- }
- }
-
- // 超过10个心跳周期未收到心跳,做下线处理
- for (size_t i = 0; i < vec_sip_id.size(); i++) {
- deleteClientByDevice(vec_sip_id[i]);
- }
-}
-
void SipServer::RequestCatalog(Client* client) {
eXosip_lock(mSipCtx);
diff --git a/sip/SipServer.h b/sip/SipServer.h
index a28cfec..1a9f069 100644
--- a/sip/SipServer.h
+++ b/sip/SipServer.h
@@ -13,11 +13,18 @@ extern "C" {
#include
#include
-#include "./Message/CatalogParser.h"
+#include "./Message/GBXmlParser.h"
#include "sip_header.h"
using namespace std;
+enum DeviceType {
+ DEVICE_TYPE_UNKNOWN,
+ DEVICE_TYPE_IPC,
+ DEVICE_TYPE_NVR,
+ DEVICE_TYPE_PLATFORM
+};
+
class Client {
public:
Client(string ip, int port, string device) :
@@ -25,6 +32,7 @@ public:
{
mRtpPort = 0;
mIsReg = false;
+ mType = DEVICE_TYPE_UNKNOWN;
}
~Client() = default;
@@ -75,6 +83,14 @@ public:
mExipry = expiry;
}
+ DeviceType getDeviceType() {
+ return mType;
+ }
+
+ void setDeviceType(DeviceType type) {
+ mType = type;
+ }
+
private:
string mIp; // client ip
int mPort; // client port
@@ -86,6 +102,7 @@ private:
unsigned long mHeartBeatGap{1};
unsigned long mHeartBeatCount{0};
long mExipry{0};
+ DeviceType mType;
};
@@ -108,14 +125,12 @@ public:
public:
void event_loop();
- void timing_getcatlog();
private:
int init_sip_server();
int sip_event_handle(eXosip_event_t *evtp);
void RequestCatalog(Client* client);
- void cacheCatalog();
void RequestDeviceInfo(Client* client);
diff --git a/sip/sip_header.h b/sip/sip_header.h
index c493e12..dcd118c 100644
--- a/sip/sip_header.h
+++ b/sip/sip_header.h
@@ -18,6 +18,12 @@ enum EEventType
EVENT_UNKNOW,
};
+enum DeviceStatus {
+ STATUS_UNKNOWN,
+ STATUS_ON,
+ STATUS_OFF
+};
+
struct DeviceInfo
{
EEventType event;
@@ -41,7 +47,7 @@ struct DeviceInfo
std::string ip;
std::string port;
std::string password;
- std::string status;
+ DeviceStatus status;
std::string longitude;
std::string latitude;
std::string ptz;