diff --git a/.vscode/launch.json b/.vscode/launch.json index 8c8115f..085744b 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -29,10 +29,35 @@ "type": "cppdbg", "request": "launch", "program": "${workspaceFolder}/release/out/PcapSender", - "args": ["/media/alan/Data/Alan/Documents/WorkSpace/SecMedia/PcapSender/hw28181.pcap", - "127.0.0.1","30001","udp src port 20180"], + // "args": ["/media/alan/Data/Alan/Documents/WorkSpace/SecMedia/PcapSender/hw28181.pcap", + // "127.0.0.1","40001","udp src port 20180"], + // "args": ["/media/alan/Data/Alan/Documents/WorkSpace/SecMedia/PcapSender/all.pcap", + // "127.0.0.1","40001","udp src port 20002"], // "args": ["/media/alan/Data/Alan/Documents/WorkSpace/SecMedia/PcapSender/signhw28181.pcap", // "127.0.0.1","30001","udp src port 55763"], + "args": ["/media/alan/Data/Alan/Documents/WorkSpace/SecMedia/PcapRawSender/h265-hikvision-10min.pcap", + "127.0.0.1","40001","udp src port 15060"], //h265 + "stopAtEntry": false, + "cwd": "${workspaceFolder}", + "environment": [], + "externalConsole": false, + "MIMode": "gdb", + "setupCommands": [ + { + "description": "为 gdb 启用整齐打印", + "text": "-enable-pretty-printing", + "ignoreFailures": true + } + ], + "miDebuggerPath": "/usr/bin/gdb" + }, + { + "name": "pcapRawsender", + "type": "cppdbg", + "request": "launch", + "program": "${workspaceFolder}/release/out/PcapRawSender", + "args": ["/media/alan/Data/Alan/Documents/WorkSpace/SecMedia/PcapRawSender/h265-hikvision-10min.pcap", + "127.0.0.1","40001","udp src port 15060"], "stopAtEntry": false, "cwd": "${workspaceFolder}", "environment": [], diff --git a/CMakeLists.txt b/CMakeLists.txt index 4021aeb..76efd0f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -122,4 +122,6 @@ endif() add_subdirectory(test) -add_subdirectory(PcapSender) \ No newline at end of file +add_subdirectory(PcapSender) +add_subdirectory(PcapRawSender) +add_subdirectory(SecSetGen) \ No newline at end of file diff --git a/PcapRawSender/CMakeLists.txt b/PcapRawSender/CMakeLists.txt new file mode 100644 index 0000000..d36f4dc --- /dev/null +++ b/PcapRawSender/CMakeLists.txt @@ -0,0 +1,16 @@ +include_directories(../include) + +file(GLOB sender_src_list ./*.cpp ./*.h ../include/*.h) +MESSAGE(STATUS ${sender_src_list}) + +find_package(PcapPlusPlus CONFIG REQUIRED) +find_package(DPDK REQUIRED) +message(STATUS "Using Pcap++ ${PcapPlusPlus_VERSION}") +message(STATUS "Include dir: ${PcapPlusPlus_INCLUDE_DIR}") + + +add_executable(PcapRawSender ${sender_src_list}) + +target_link_libraries(PcapRawSender PUBLIC ${LINK_LIB_LIST} PUBLIC PcapPlusPlus::Pcap++ PUBLIC DPDK::DPDK) +# target_link_libraries(PcapSender PUBLIC PcapPlusPlus::Pcap++) + diff --git a/PcapRawSender/main.cpp b/PcapRawSender/main.cpp new file mode 100644 index 0000000..b57c7a4 --- /dev/null +++ b/PcapRawSender/main.cpp @@ -0,0 +1,194 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "HuaWei/HWsign.h" +#include "HuaWei/HWsec.h" + +using namespace std; +using namespace pcpp; + +std::string getProtocolTypeAsString(pcpp::ProtocolType protocolType) +{ + switch (protocolType) + { + case pcpp::Ethernet: + return "Ethernet"; + case pcpp::IPv4: + return "IPv4"; + case pcpp::TCP: + return "TCP"; + case pcpp::HTTPRequest: + case pcpp::HTTPResponse: + return "HTTP"; + case pcpp::UDP: + return "UDP"; + default: + return "Unknown"; + } + +} + +inline void sleep(timeval & delta){ + // delta.tv_sec + select(0,NULL,NULL,NULL,&delta); +} +template +timespec TimeDiff(T && minu,U && sub){ + timespec deltatime; + deltatime.tv_nsec=minu.tv_nsec-sub.tv_nsec; + deltatime.tv_sec=minu.tv_sec-sub.tv_sec; + if(deltatime.tv_nsec<0 && deltatime.tv_sec>0){ + deltatime.tv_nsec+=1000000000; + deltatime.tv_sec--; + } + return move(deltatime); +} + +int ReadPcapAndSend(int socket,sockaddr_in & addr,const string & filename,const string & filter,void * sign_handle){ + auto reader=pcpp::IFileReaderDevice::getReader(filename); + // verify that a reader interface was indeed created + if (reader == NULL) + { + std::cerr << "Cannot determine reader for file type" << std::endl; + return 1; + } + // open the reader for reading + if (!reader->open()) + { + std::cerr << "Cannot open input.pcap for reading" << std::endl; + return 1; + } + + if (!reader->setFilter(filter)) + { + std::cerr << "Cannot set filter for file reader" << std::endl; + return 1; + } + + uint8_t * payload; + size_t payload_len; + pcpp::RawPacket rawPacket; + bool first_flag=true; + timespec nowtime,gaptime; + timespec real_now; + timespec inital_time,current_time; + static char sign_out_buf[3096]; + unsigned int sign_out_len; + void *param=nullptr; + uint16_t offset_len,append_len; + while (reader->getNextPacket(rawPacket)) + { + pcpp::Packet parsedPacket(&rawPacket,OsiModelTransportLayer); + auto layer = parsedPacket.getLayerOfType(false); + + if(layer){ + payload=layer->getLayerPayload(); + payload_len=layer->getLayerPayloadSize(); + // cout<<" payload_len:" << payload_len<=0 && gaptime.tv_sec>=0) + { + nanosleep(&gaptime,NULL); + }else{ + // cout<<" s:" << gaptime.tv_sec<<" ns:" << gaptime.tv_nsec <getNextPacket(rawPacket); + + // for (pcpp::Layer* curLayer = parsedPacket.getFirstLayer(); curLayer != NULL; curLayer = curLayer->getNextLayer()) + // { + // std::cout + // << "Layer type: " <getProtocol()) << "; " // get layer type + // << "Total data: " << curLayer->getDataLen() << " [bytes]; " // get total length of the layer + // << "Layer data: " << curLayer->getHeaderLen() << " [bytes]; " // get the header length of the layer + // << "Layer payload: " << curLayer->getLayerPayloadSize() << " [bytes]" // get the payload length of the layer (equals total length minus header length) + // << std::endl; + // } + // create the stats object + pcpp::IPcapDevice::PcapStats stats; + reader->getStatistics(stats); + std::cout << "Read " << stats.packetsRecv << " packets successfully and " << stats.packetsDrop << " packets could not be read" << std::flush; + return 0; +} +int main(int argc, char *argv[]){ + + char ip[16] = {0}; + int sockfd, port; + if (argc>4) + { + string filename(argv[1]); + strcpy(ip, argv[2]); + port = atoi(argv[3]); + string filter(argv[4]); + printf("filename:%s\nip:%s\nport:%d\nfilter:%s\n", filename.data(), ip,port,filter.data()); + + sockfd = socket(AF_INET, SOCK_DGRAM , IPPROTO_UDP);//SOCK_STREAM + if (sockfd == -1) { + printf("create socket failed : %s\n", strerror(errno)); + return -1; + } + int rcvBufSize = 2097152; + int rcvlen = sizeof(rcvBufSize); + setsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, (char*)&rcvBufSize, sizeof(rcvBufSize)); + if (getsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, (char*)&rcvBufSize, (socklen_t *)&rcvlen) >= 0) + { + printf("set udp socket send buff size to : %d\n", rcvBufSize); + if (rcvBufSize < 4194304) + { + printf("socket send buff too small, please set up to 2097152(2M)"); + } + }else { + printf("socket failed : %s\n", strerror(errno)); + return -1; + } + struct sockaddr_in addr; + addr.sin_family = AF_INET; + addr.sin_port = htons(port); + addr.sin_addr.s_addr =inet_addr(ip); + // if(connect(sockfd, (struct sockaddr*)&addr, sizeof(addr))==-1){ + // printf("connection error : %s\n", strerror(errno)); + // return -1; + // } + // bind(sockfd, (struct sockaddr*)&addr, sizeof(addr)); + // while (1) + // { + cout.flush(); + ReadPcapAndSend(sockfd,addr,filename,filter,NULL); + // } + + } + else + { + printf("CMD as: filename.pcap ip port\n"); + system("pause"); + return 0; + } + return 0; + +} \ No newline at end of file diff --git a/SecSetGen/CMakeLists.txt b/SecSetGen/CMakeLists.txt new file mode 100644 index 0000000..2ed7ffd --- /dev/null +++ b/SecSetGen/CMakeLists.txt @@ -0,0 +1,10 @@ +include_directories(../include) + +file(GLOB sender_src_list ./*.cpp ./*.h ../include/*.h) +MESSAGE(STATUS ${sender_src_list}) + +add_executable(SecSetGen ${sender_src_list}) + +target_link_libraries(SecSetGen PUBLIC ${LINK_LIB_LIST}) +# target_link_libraries(PcapSender PUBLIC PcapPlusPlus::Pcap++) + diff --git a/SecSetGen/main.cpp b/SecSetGen/main.cpp new file mode 100644 index 0000000..0c36063 --- /dev/null +++ b/SecSetGen/main.cpp @@ -0,0 +1,62 @@ +#include +#include +#include +#include +#include +#include +using namespace std; + + +class SecSet +{ +public: + typedef shared_ptr Ptr; +private: + vector _buf; + // char * _buf=nullptr; + size_t _len=0; +public: + SecSet(/* args */){}; + ~SecSet(){ + // if(_buf) delete _buf; + _len=0; + } + void setBuf(const char * buf, size_t len){ + + // _buf.clear(); + _buf.assign(buf,buf+len); + // if(!_buf){ + // _buf=new char[len] ;_len=len; + // } + // if (len>_len) + // { + // _buf=(char*)realloc(_buf,len) ;_len=len; + // } + // memcpy(_buf,buf,len); + } + void printBuf(){ + printf("%s len %lu\n",_buf.data(),_buf.size()); + } + + Ptr clone(){ + return make_shared::type>(*this); + } +}; + + + +int main(){ + const char hl[]={"Hello World!"}; + const char hl2[]={"Hello World_twic!"}; + SecSet::Ptr A=make_shared() ; + A->setBuf(hl,sizeof(hl)); + A->printBuf(); + auto B=A->clone(); + A->setBuf(hl2,sizeof(hl2)); + A->printBuf(); + B->printBuf(); + A->setBuf(hl,sizeof(hl));A->printBuf(); + B->printBuf(); + return 0; +} + diff --git a/src/GB28181/L2PSstream.cpp b/src/GB28181/L2PSstream.cpp index db2012a..05c1129 100644 --- a/src/GB28181/L2PSstream.cpp +++ b/src/GB28181/L2PSstream.cpp @@ -70,8 +70,15 @@ bool L2PSstream::splitPES(const uint8_t * data, uint16_t len,const std::function ret= stream_split_nd((char*)start,len-(start-data),prefix,ned,sizeof(ned),[&](const char *ptr, int len, int prefix){ pes_head=(char*)ptr; stream_split((char*)ptr,len,prefix,[&](const char *ptr, int len, int prefix){ - // INFOL("%02X %02X %02X %02X %02X \n",(uint8_t)ptr[0],(uint8_t)ptr[1],(uint8_t)ptr[2],(uint8_t)ptr[3],(uint8_t)ptr[4]); - ret=cb(ptr,pes_head,len,prefix); + //INFOL("%02X %02X %02X %02X %02X \n",(uint8_t)ptr[0],(uint8_t)ptr[1],(uint8_t)ptr[2],(uint8_t)ptr[3],(uint8_t)ptr[4]); + if(cb){ + ret=cb(ptr,pes_head,len,prefix); + }else + { + throw runtime_error("empty callback function"); + } + + }); return ret; }); @@ -174,6 +181,21 @@ void L2PSstream::decodeH264(const char *data, int bytes, int64_t dts, int prefix }; void L2PSstream::decodeH265(const char *data, int bytes, int64_t dts, int prefix){ int type=H265_TYPE(((uint8_t *)data+prefix)[0]); + switch (type) + { + case H265Nal::NAL_BLA_W_LP ... H265Nal::NAL_RSV_IRAP_VCL23: //keyframe + TRACEL("NAL_IDR dts:%lu, bytes:%d\n",dts,bytes); + addSignData(data+prefix,bytes-prefix,dts,type); + break; + case H265Nal::NAL_SEI_PREFIX : + TRACEL("NAL_SEI_PREFIX dts:%lu, bytes:%d\n",dts,bytes); + break; + case H265Nal::NAL_SEI_SUFFIX : + TRACEL("NAL_SEI_SUFFIX dts:%lu, bytes:%d\n",dts,bytes); + break; + default: + break; + } }; diff --git a/src/GB28181/L2SecurityStream.cpp b/src/GB28181/L2SecurityStream.cpp index 7176d4c..a52b462 100644 --- a/src/GB28181/L2SecurityStream.cpp +++ b/src/GB28181/L2SecurityStream.cpp @@ -26,7 +26,14 @@ L2SecurityStream::L2SecurityStream(sec_set_info* set_info){ _keyframe_seq=-1; _code_id=CodecInvalid; sm3_init(&_sm3); - _set_info=*set_info; + if(set_info){ + _set_info=*set_info; + }else + { + throw runtime_error("L2SecurityStream initial error: empty sec_set_info"); + } + + uint8_t security_set_version[19] = "Ver 0.0.2"; memset(&sec_set,0,sizeof(sec_set));