1 Star 0 Fork 0

刘聪/GB28181SIPServer

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
SipClient.cpp 23.62 KB
一键复制 编辑 原始数据 按行查看 历史
congliu 提交于 2024-08-30 17:43 . 1、支持TCP、UDP传输
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666
//
// Created by bxc on 2022/12/13.
//
#include "SipClient.h"
#include <stdio.h>
#include <string.h>
#include "Utils/Log.h"
#include "Utils/Utils.h"
#include "SipServerConfig.h"
#include "RtpSendPs.h"
#ifndef WIN32
// Linux系统
#include <arpa/inet.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#else
#include <WinSock2.h>
#pragma comment(lib, "ws2_32.lib")
#endif // !WIN32
extern "C" {
#include "Utils/HTTPDigest.h"
}
namespace BXC {
SipClient::SipClient(SipServerConfig* serverConfig, SipClientConfig* clientConfig, const char* rtspurl)
:mServerConfig(serverConfig), mClientConfig(clientConfig), mrtspurl(rtspurl),
mRegistered(false), mRegisterId(-1) {
#ifdef WIN32
WSADATA wsaData;
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
{
LOGE("WSAStartup Error");
return;
}
#endif // WIN32
}
SipClient::~SipClient() {
#ifdef WIN32
WSACleanup();
#endif // WIN32
}
void SipClient::loop() {
if (this->init_sip_client() != 0) {
return;
}
SipClient* sipClient = this;
static bool allowReg = true;
int64_t lastKeepaliveTimestamp = 0;
int64_t curTimestamp = 0;
int64_t interval = 20000;// 客户端发送keepalive检测的间隔,单位:毫秒
while (!sipClient->mClientConfig->quit) {
// 首次发起注册
if (allowReg && !sipClient->mRegistered) {
allowReg = false;
sipClient->request_register();
}
// 心跳机制 start (开发过程中,为防止影响抓包,可以先注释)
if(sipClient->mRegistered){
curTimestamp = getCurTimestamp();
if(lastKeepaliveTimestamp == 0){
sipClient->request_message_keepalive();
lastKeepaliveTimestamp = curTimestamp;
} else {
if((curTimestamp - lastKeepaliveTimestamp) > interval){
sipClient->request_message_keepalive();
lastKeepaliveTimestamp = curTimestamp;
}
}
}
// 心跳机制 end
eXosip_event_t* evtp = eXosip_event_wait(sipClient->mSipCtx, 0, 200);
if (!evtp) {
eXosip_automatic_action(sipClient->mSipCtx);
osip_usleep(100000);
continue;
}
//eXosip_default_action(sipClient->mSipCtx, evtp);
eXosip_automatic_action(sipClient->mSipCtx);
sipClient->sip_event_handle(evtp);
eXosip_event_free(evtp); // 释放
}
}
int SipClient::init_sip_client() {
mSipCtx = eXosip_malloc();
if (!mSipCtx) {
LOGE("new uas context error");
return -1;
}
if (eXosip_init(mSipCtx)) {
LOGE("exosip init error");
return -1;
}
if (eXosip_listen_addr(mSipCtx, IPPROTO_UDP, NULL, mClientConfig->port, AF_INET, 0)) {
LOGE("listen error");
return -1;
}
eXosip_set_user_agent(mSipCtx, mClientConfig->ua);
if (eXosip_add_authentication_info(mSipCtx, mClientConfig->id, mClientConfig->id, mServerConfig->getSipId(), NULL, NULL) < 0) {
LOGI("eXosip_add_authentication_info error");
return -1;
}
return 0;
}
int SipClient::request_message_keepalive() {
char from[1024] = { 0 };
char to[1024] = { 0 };
sprintf(from, "sip:%s@%s:%d", mClientConfig->id, mClientConfig->ip, mClientConfig->port);
sprintf(to, "sip:%s@%s:%d", mServerConfig->getSipId(), mServerConfig->getIp(), mServerConfig->getPort());
osip_message_t* msg;
char body[1024] = { 0 };
sprintf(
body,
"<?xml version=\"1.0\" encoding=\"GB2312\" standalone=\"yes\" ?>\r\n"
"<Notify>\r\n"
"<CmdType>Keepalive</CmdType>\r\n"
"<SN>1</SN>\r\n"
"<DeviceID>%s</DeviceID>\r\n"
"<Status>OK</Status>\r\n"
"</Notify>\r\n",
mClientConfig->id);
eXosip_message_build_request(mSipCtx, &msg, "MESSAGE", to, from, NULL);
osip_message_set_body(msg, body, strlen(body));
osip_message_set_content_type(msg, "Application/MANSCDP+xml");
eXosip_message_send_request(mSipCtx, msg);
// char *s;
// size_t len;
// osip_message_to_str(msg, &s, &len);
// LOGI("send cmd catalog: \n%s", s);
return 0;
}
int SipClient::request_message_catalog() {
char from[1024] = { 0 };
char to[1024] = { 0 };
sprintf(from, "sip:%s@%s:%d", mClientConfig->id, mClientConfig->ip, mClientConfig->port);
sprintf(to, "sip:%s@%s:%d", mServerConfig->getSipId(), mServerConfig->getIp(), mServerConfig->getPort());
osip_message_t* msg;
char body[1024] = { 0 };
char* s;
size_t len;
sprintf(
body,
"<?xml version=\"1.0\"?>\r\n"
"<Query>\r\n"
"<CmdType>Catalog</CmdType>\r\n"
"<SN>1</SN>\r\n"
"<DeviceID>%s</DeviceID>\r\n"
"</Query>\r\n",
mServerConfig->getSipId());
eXosip_message_build_request(mSipCtx, &msg, "MESSAGE", to, from, NULL);
osip_message_set_body(msg, body, strlen(body));
osip_message_set_content_type(msg, "Application/MANSCDP+xml");
eXosip_message_send_request(mSipCtx, msg);
osip_message_to_str(msg, &s, &len);
LOGI("send cmd catalog: \n%s", s);
return 0;
}
int SipClient::request_register() {
int ret = -1;
osip_message_t* msg = NULL;
char from[1024] = { 0 };
char contact[1024] = { 0 };
char proxy[1024] = { 0 };
if (mRegistered) { // refresh register
LOGI("刷新注册 mRegisterId=%d", mRegisterId);
ret = eXosip_register_build_register(mSipCtx, mRegisterId, mServerConfig->getSipExpiry(), &msg);
if (!ret) {
LOGE("eXosip_register_build_register error: ret=%d", ret);
return -1;
}
}
else { // new register
LOGI("未注册 mRegisterId=%d", mRegisterId);
sprintf(from, "sip:%s@%s:%d", mClientConfig->id, mClientConfig->ip, mClientConfig->port);
sprintf(proxy, "sip:%s@%s:%d", mServerConfig->getSipId(), mServerConfig->getIp(), mServerConfig->getPort());
sprintf(contact, "sip:%s@%s:%d", mClientConfig->id, mClientConfig->ip, mClientConfig->port);
mRegisterId = eXosip_register_build_initial_register(mSipCtx, from, proxy, contact, mServerConfig->getSipExpiry(), &msg);
if (mRegisterId <= 0) {
LOGE("eXosip_register_build_initial_register error: mRegisterId=%d", mRegisterId);
return -1;
}
}
ret = eXosip_register_send_register(mSipCtx, mRegisterId, msg);
if (ret) {
LOGE("eXosip_register_send_register error: ret=%d", ret);
return ret;
}
char* msg_str;
size_t msg_strlen;
osip_message_to_str(msg, &msg_str, &msg_strlen);
LOGI("注册请求体: %s", msg_str);
return ret;
}
int SipClient::response_message_answer(eXosip_event_t* evtp, int code) {
osip_message_t* msg = nullptr;
int returnCode = eXosip_message_build_answer(mSipCtx, evtp->tid, code, &msg);
if (returnCode == 0 && msg) {
eXosip_lock(mSipCtx);
eXosip_message_send_answer(mSipCtx, evtp->tid, code, msg);
eXosip_unlock(mSipCtx);
// osip_message_free(msg);
}
else {
bool msg_state = false;
if (msg) {
msg_state = true;
}
LOGE("error: code=%d,returnCode=%d,msg=%d", code, returnCode, msg_state);
}
return 0;
}
int SipClient::response_message(eXosip_event_t* evtp) {
osip_body_t* req_body = nullptr;
osip_message_get_body(evtp->request, 0, &req_body);
// LOGI("req_body->body: %s", req_body->body);
char cmd[64] = { 0 };
parse_xml(req_body->body, "<CmdType>", false, "</CmdType>", false, cmd);
LOGI("got message: %s", cmd);
char SN_c[20] = { 0 }; // 序列号
int SN = 0;// 序列号
char DeviceID[100] = { 0 }; // 设备编码
char DecoderChannelID[100] = { 0 }; // 解码器通道编码
char PlayUrl[512] = { 0 }; // 源视频地址
parse_xml(req_body->body, "<SN>", false, "</SN>", false, SN_c);
parse_xml(req_body->body, "<DeviceID>", false, "</DeviceID>", false, DeviceID);
parse_xml(req_body->body, "<DecoderChannelID>", false, "</DecoderChannelID>", false, DecoderChannelID);
parse_xml(req_body->body, "<PlayUrl>", false, "</PlayUrl>", false, PlayUrl);
LOGI("DeviceID:%s", DeviceID);
LOGI("DecoderChannelID:%s", DecoderChannelID);
SN = std::stoi(SN_c);
if (!strcmp(cmd, "Catalog")) {
this->response_message_answer(evtp, 200);
char from[1024] = { 0 };
char to[1024] = { 0 };
sprintf(from, "sip:%s@%s:%d", mClientConfig->id, mClientConfig->ip, mClientConfig->port);
sprintf(to, "sip:%s@%s:%d", mServerConfig->getSipId(), mServerConfig->getIp(), mServerConfig->getPort());
osip_message_t* msg;
char body[1024] = { 0 };
char* s;
size_t len;
sprintf(
body,
"<?xml version=\"1.0\"?>\r\n"
"<Response>\r\n"
"<CmdType>Catalog</CmdType>\r\n"
"<SN>%d</SN>\r\n"
"<DeviceID>%s</DeviceID>\r\n"
"<SumNum>1</SumNum>\r\n"
"<DeviceList Num=\"1\">\r\n"
"<Item>\r\n"
"<DeviceID>%s</DeviceID>\r\n"
"<Name>%s</Name>\r\n"
"<Manufacturer>%s</Manufacturer>\r\n"
"<Model>%s</Model>\r\n"
"<Owner>%s</Owner>\r\n"
"<CivilCode>%s</CivilCode>\r\n"
"<Address>%s</Address>\r\n"
"<Parental>%d</Parental>\r\n"
"<SafetyWay>%d</SafetyWay>\r\n"
"<RegisterWay>%d</RegisterWay>\r\n"
"<Secrecy>%d</Secrecy>\r\n"
"<Longitude>%f</Longitude>\r\n"
"<Latitude>%f</Latitude>\r\n"
"<Status>%s</Status>\r\n"
"</Item>\r\n"
"</DeviceList>\r\n"
"</Response>\r\n",
SN,
mClientConfig->id,
//mServerConfig->getSipId(),
mClientConfig->id, "IPC", "Hikvision", "IP Camera", "Owner", "CivilCode",
"Address", 0, 0, 1, 0, 114.0, 23.0, "OK");
eXosip_message_build_request(mSipCtx, &msg, "MESSAGE", to, from, NULL);
osip_message_set_body(msg, body, strlen(body));
osip_message_set_content_type(msg, "Application/MANSCDP+xml");
eXosip_message_send_request(mSipCtx, msg);
osip_message_to_str(msg, &s, &len);
LOGI("send cmd catalog: \n%s", s);
}
else {
this->response_message_answer(evtp, 200);
}
return 0;
}
int SipClient::response_invite(eXosip_event_t* evtp) {
char* username = evtp->request->to->url->username;//对应摄像头的DeviceID
char* CallID = evtp->request->call_id->number;
LOGI("username:%s", username);
LOGI("CallID:%s", CallID);
osip_message_t* answer = nullptr;
eXosip_lock(mSipCtx);
//eXosip_call_send_answer(mSipCtx, evtp->tid, 180, nullptr);
int ret = eXosip_call_build_answer(mSipCtx, evtp->tid, 200, &answer);
if (ret != 0) {
eXosip_call_send_answer(mSipCtx, evtp->tid, 400, nullptr);
LOGE("camera: %s eXosip_call_build_answer error", username);
}
else {
// 采用exosip的函数解析sdp
/*
printf("-----------exosip parse start-----------\n");
sdp_message_t *remote_sdp = eXosip_get_remote_sdp(mSipCtx, evtp->did);
if(remote_sdp){
sdp_media_t *video_sdp = eXosip_get_video_media(remote_sdp);
if (video_sdp) {
int pos = 0;
char *video_port = video_sdp->m_port; // audio_port
for (int i = 0; i < video_sdp->a_attributes.nb_elt; i++)
{
sdp_attribute_t *attr = (sdp_attribute_t *)osip_list_get(&video_sdp->a_attributes, i);
printf("1-%s : %s\n", attr->a_att_field, attr->a_att_value);
}
while (!osip_list_eol(&(remote_sdp->a_attributes), pos)) {
sdp_attribute_t *at;
at = (sdp_attribute_t *)osip_list_get(&remote_sdp->a_attributes, pos);
printf(
"2-%s : %s\n", at->a_att_field,
at->a_att_value); // 这里解释了为什么在SDP消息体中属性a里面存放必须是两列
pos++;
}
while (!osip_list_eol(&(remote_sdp->m_medias), pos)) {
sdp_attribute_t *at;
at = (sdp_attribute_t *)osip_list_get(&remote_sdp->m_medias, pos);
printf(
"3-%s : %s\n", at->a_att_field,
at->a_att_value); // 这里解释了为什么在SDP消息体中属性a里面存放必须是两列
pos++;
}
}
}
printf("-----------exosip parse end-----------\n");
*/
printf("-----------my parse start-----------\n");
int trackSize = 0;
// 下面解析SDP的方式只适合一个媒体流,所有如果同时包含音频和视频流,需要注意!!!
// 采用自定义的方式解析sdp
osip_body_t* req_body = nullptr;
osip_message_get_body(evtp->request, 0, &req_body);
/*获取远端和本地的SDP*/
sdp_message_t* SdpRomte = NULL;
osip_body_t* RqtBody = NULL;
osip_message_get_body(evtp->request, 0, &RqtBody);
sdp_message_init(&SdpRomte);
sdp_message_parse(SdpRomte, RqtBody->body);
std::string ServerProto(sdp_message_m_proto_get(SdpRomte, 0));
std::vector<std::string> lineArray = split(req_body->body, "\n");
for (auto& line : lineArray) {
printf(">>>>>>%s\n", line.data());
if (!strncmp(line.data(), "c=IN", strlen("c=IN"))) {
// example: c=IN IP4 192.168.8.91
if (sscanf(line.data(), "c=IN IP4 %s ", &track.peerIp) != 1) {
LOGE("parse line error:%s", line.data());
break;
}
}
if (!strncmp(line.data(), "y=", strlen("y="))) {
// example: c=IN IP4 192.168.8.91
if (sscanf(line.data(), "y=%s ", &track.peerysource) != 1) {
LOGE("parse line error:%s", line.data());
break;
}
printf("-----------my parse y=%s-----------\n", track.peerysource);
}
if (!strncmp(line.data(), "m=", strlen("m="))) {
// example: m=video 15060 TCP/RTP/AVP 96
if (sscanf(line.data(), "m=%s %d %s %s ", &track.mediaType, &track.peerRtpPort, &track.peerRtpTransport, &track.peerStreamType) != 4) {
LOGE("parse line error:%s", line.data());
break;
}
else {
// success
trackSize++;
}
}
}
printf("-----------my parse end-----------\n");
LOGI("trackSize=%d", trackSize);
//还有一点需要注意,这个设置:a=sendonly
char sdpBuf[2048];
snprintf(
sdpBuf, sizeof(sdpBuf),
"v=0\r\n"
"o=%s 0 0 IN IP4 %s\r\n"
"s=Play\r\n"
"c=IN IP4 %s\r\n"
"t=0 0\r\n"
"m=video %d %s 96\r\n"
"a=sendonly\r\n"
"a=rtpmap:96 PS/90000\r\n"
"y=%s\r\n",
mClientConfig->id,
mClientConfig->ip, mClientConfig->ip,
mClientConfig->localRtpPort, ServerProto.c_str(), track.peerysource);//
osip_message_set_body(answer, sdpBuf, strlen(sdpBuf));
osip_message_set_content_type(answer, "application/sdp");
int ret = eXosip_call_send_answer(mSipCtx, evtp->tid, 200, answer);
printf("ret = %d \n response_invite: \n%s", ret, sdpBuf);
}
eXosip_unlock(mSipCtx);
return 0;
}
int SipClient::response_ack(eXosip_event_t* evtp) {
char* username = evtp->request->to->url->username;//对应摄像头的DeviceID
char* CallID = evtp->request->call_id->number;
LOGI("接收到信令服务的ACK,开始ps over rtp 推流");
printf("username:%s\n", username);
printf("CallID:%s\n", CallID);
/*获取远端和本地的SDP*/
sdp_message_t* SdpRomte = NULL;
//sdp_message_t* SdpLocal = NULL;
osip_body_t* RqtBody = NULL;
//osip_body_t* RpeBody = NULL;
osip_message_get_body(evtp->request, 0, &RqtBody);
sdp_message_init(&SdpRomte);
sdp_message_parse(SdpRomte, RqtBody->body);
//osip_message_get_body(evtp->response, 0, &RpeBody);
//sdp_message_init(&SdpLocal);
//sdp_message_parse(SdpLocal, RpeBody->body);
std::string ServerProto(sdp_message_m_proto_get(SdpRomte, 0));
// 正式开始推流
if(mRtpSendPs){
mRtpSendPs->stop();
delete mRtpSendPs;
mRtpSendPs = nullptr;
}
mRtpSendPs = new RtpSendPs(mServerConfig->getIp(), track.peerRtpPort,mClientConfig->localRtpPort, mrtspurl, ServerProto);
mRtpSendPs->start();
return 0;
}
int SipClient::response_bye(eXosip_event_t* evtp) {
char* username = evtp->request->to->url->username;//对应摄像头的DeviceID
char* CallID = evtp->request->call_id->number;
LOGI("接收到信令服务的BYE,停止ps over rtp 推流");
LOGI("username:%s", username);
LOGI("CallID:%s", CallID);
// 停止推流
if(mRtpSendPs){
mRtpSendPs->stop();
delete mRtpSendPs;
mRtpSendPs = nullptr;
}
return 0;
}
int SipClient::sip_event_handle(eXosip_event_t* evtp) {
LOGI("type=%d -----------------------------", evtp->type);
switch (evtp->type) {
case EXOSIP_MESSAGE_NEW:
LOGI("EXOSIP_MESSAGE_NEW");
if (MSG_IS_REGISTER(evtp->request)) {
LOGI("MSG_IS_REGISTER,不应该出现的响应,请排查问题");
}
else if (MSG_IS_MESSAGE(evtp->request)) {
this->response_message(evtp);
}
else {
LOGI("未定义类型的MESSAGE");
this->dump_request(evtp);
/*
// 可能会出现的请求
BYE sip:00662800000403000001@192.168.8.200:5060 SIP/2.0
Via: SIP/2.0/UDP 192.168.8.114:5060;branch=z9hG4bK695c5ff8b5c014866ffc6a554c242a6d
From: <sip:00662800000401000001@0066280000>;tag=185326220
To: <sip:00662802002006028104@0066280000>;tag=2009556327
Call-ID: 05a7fc88c30878338ff311a788e9cefa@192.168.8.114
CSeq: 185 BYE
Max-forwards: 70
Content-Length: 0
*/
}
break;
case EXOSIP_CALL_ANSWERED:
LOGI("EXOSIP_CALL_ANSWERED type=%d:这里应该主动发送ACK之后的回复", evtp->type);
this->dump_request(evtp);
this->dump_response(evtp);
break;
case EXOSIP_REGISTRATION_FAILURE:
LOGI("EXOSIP_REGISTRATION_FAILURE type=%d", evtp->type);
LOGI("mRegistered=%d,mRegisterId=%d", mRegistered, mRegisterId);
this->mRegistered = false;
if (eXosip_add_authentication_info(mSipCtx, mClientConfig->id, mClientConfig->id, mServerConfig->getSipPass(), NULL, NULL) < 0) {
LOGI("eXosip_add_authentication_info error");
}
break;
case EXOSIP_REGISTRATION_SUCCESS:
LOGI("EXOSIP_REGISTRATION_SUCCESS type=%d", evtp->type);
this->mRegistered = true;
LOGI("mRegistered=%d,mRegisterId=%d", mRegistered, mRegisterId);
// this->dump_request(evtp);
// this->request_message_keepalive();
break;
case EXOSIP_CALL_INVITE:
LOGI("EXOSIP_CALL_INVITE type=%d: 接收到对方发送了Invite请求", evtp->type);
// this->dump_request(evtp);
// this->dump_response(evtp);
this->response_invite(evtp);
//this->response_ack(evtp);
break;
case EXOSIP_CALL_ACK:
LOGI("EXOSIP_CALL_ACK type=%d: 收到来自对方ACK请求。准备国标推流。", evtp->type);
dump_request(evtp);
this->response_ack(evtp);
break;
case EXOSIP_IN_SUBSCRIPTION_NEW:
LOGI("EXOSIP_IN_SUBSCRIPTION_NEW type=%d", evtp->type);
dump_request(evtp);
break;
case EXOSIP_CALL_NOANSWER: {
LOGI("EXOSIP_IN_SUBSCRIPTION_NEW type=%d", evtp->type);
break;
}
case EXOSIP_CALL_MESSAGE_NEW://14
{
LOGI("EXOSIP_CALL_MESSAGE_NEW type=%d", evtp->type);
this->dump_request(evtp);
this->dump_response(evtp);
break;
}
case EXOSIP_CALL_CLOSED://21
{
LOGI("EXOSIP_CALL_CLOSED type=%d", evtp->type);
this->dump_request(evtp);
this->dump_response(evtp);
this->response_bye(evtp);
break;
}
case EXOSIP_CALL_RELEASED://22
{
LOGI("EXOSIP_CALL_RELEASED type=%d: Bye确认", evtp->type);
break;
}
case EXOSIP_MESSAGE_REQUESTFAILURE:
LOGI("EXOSIP_MESSAGE_REQUESTFAILURE type=%d", evtp->type);
LOGI("evtp->textinfo= '%s' ", evtp->textinfo);
if (evtp->ack) {
char* ack_str;
size_t ack_str_len;
osip_message_to_str(evtp->ack, &ack_str, &ack_str_len);
LOGI("ack_str=%s", ack_str);
}
this->dump_request(evtp);
this->dump_response(evtp);
break;
case EXOSIP_MESSAGE_ANSWERED:
LOGI("EXOSIP_MESSAGE_ANSWERED type=%d: 接收到来自对应的MESSAGE请求。", evtp->type);
break;
default: LOGI("type=%d unknown ", evtp->type); break;
}
return 0;
}
int SipClient::parse_xml(const char* data, const char* s_mark, bool with_s_make, const char* e_mark, bool with_e_make, char* dest) {
const char* satrt = strstr(data, s_mark);
if (satrt != NULL) {
const char* end = strstr(satrt, e_mark);
if (end != NULL) {
int s_pos = with_s_make ? 0 : strlen(s_mark);
int e_pos = with_e_make ? strlen(e_mark) : 0;
strncpy(dest, satrt + s_pos, (end + e_pos) - (satrt + s_pos));
}
return 0;
}
return -1;
}
void SipClient::dump_request(eXosip_event_t* evt) {
char* s;
size_t len;
osip_message_to_str(evt->request, &s, &len);
LOGI("\n打印请求包开始\ntype=%d\n%s\n打印请求包结束\n", evt->type, s);
}
void SipClient::dump_response(eXosip_event_t* evt) {
char* s;
size_t len;
osip_message_to_str(evt->response, &s, &len);
LOGI("\n打印响应包开始\ntype=%d\n%s\n打印响应包结束\n", evt->type, s);
}
}
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/justdying/gb28181-sipser.git
git@gitee.com:justdying/gb28181-sipser.git
justdying
gb28181-sipser
GB28181SIPServer
master

搜索帮助

23e8dbc6 1850385 7e0993f3 1850385