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;