目录
参考目录
https://gitee.com/Vanishi/BXC_SipServer.git
https://github.com/lyyyuna/gb28181_client.git
一、注册消息示范(附件J)
1.1 注册信令
二、注册,注销基本要求
- IP客户端、网关、SIP设备、联网系统等SIP代理(SIPUA)使用IETFRFC3261中定义的方法
Register
进行注册和注销。 - 注册和注销时应
进行认证
, 认证方式应支持数字摘要
认证方式; - 高安全级别的宜支持
数字证书
认证方式; 数字证书的格式符合附录I中的规定。 - SIP代理在注册过期时间到来之前,应向注册服务器进行刷新注册。刷新注册消息流程应与9.1.2.1的流程描述一致,并遵循IETFRFC3261对刷新注册的规定。
- 若注册失败,SIP代理应间隔一定时间后继续发起注册过程,与上一次注册时间间隔应可调,一般情况下不应短于60s。
- 系统、设备注册过期时间应可配置,缺省值为86400s(1d),应在注册过期时间到来之前发送刷新注册消息,为SIP服务器预留适当刷新注册处理时间,注册过期时间不应短于3600s。
- SIP代理注册成功则认为SIP服务器为在线状态,注册失败则认为SIP服务器为离线状态;SIP服务器在SIP代理注册成功后认为其为在线状态,SIP代理注册过期则认为其为离线状态。
2.1 细节梳理
- 使用REGISTER方法进行注册,注销。
- 支持两种认证方式:数字摘要,数字证书。
- 注册过期时间可以配置,不应小于3600s。
- 注册过期前,需要SIP UA重新发起一次注册。
- 注册失败,SIP UA需要间隔重新发起注册。重新发起注册间隔可调,不小于60s。
2.2 基本注册
2.2.1 SIP Device类
class Device {
public:
Device() {
}
Device(string server_sip_id, string server_ip, int server_port,
string device_sip_id, string username, string password,
int local_port,
string manufacture,
string filepath):
server_sip_id(server_sip_id),
server_ip(server_ip),
server_port(server_port),
device_sip_id(device_sip_id),
username(username),
password(password),
local_port(local_port),
manufacture(manufacture),
filepath(filepath) {
sip_context = nullptr;
is_running = false;
is_register = false;
local_ip = string(128, '0');
#if 0
load(filepath.c_str());
#endif
}
~Device(){
}
void start();
void stop();
void process_request();
void process_catalog_query(string sn);
void process_deviceinfo_query(string sn);
void process_devicestatus_query(string sn);
void process_devicecontrol_query(string sn);
void heartbeat_task();
void send_request(osip_message_t * request);
void send_response(shared_ptr<eXosip_event_t> evt, osip_message_t * msg);
osip_message_t * create_msg();
void send_response_ok(shared_ptr<eXosip_event_t> evt);
std::tuple<string, string> get_cmd(const char * body);
void push_rtp_stream();
public:
string server_sip_id;
string server_ip;
int server_port;
string device_sip_id;
string username;
string password;
string local_ip;
int local_port;
string manufacture;
string rtp_ip;
int rtp_port;
string rtp_protocol;
string filepath;
private:
eXosip_t* sip_context;
bool is_running;
bool is_register;
bool is_pushing;
string from_sip;
string to_sip;
string ssrc;
int sockfd;
int bind();
void send_network_packet(const char * data, int length);
};
2.2.2 SIP监听
void Device::start() {
...
sip_context = eXosip_malloc();
/**
* Initiate the eXtented oSIP library.
*
* @param excontext eXosip_t instance.
*/
if (OSIP_SUCCESS != eXosip_init(sip_context)) {
spdlog::error("sip init failed.");
return;
}
/**
* Listen on a specified socket.
*
* @param excontext eXosip_t instance.
* @param transport IPPROTO_UDP for udp. (soon to come: TCP/TLS?)
* @param addr the address to bind (NULL for all interface)
* @param port the listening port. (0 for random port)
* @param family the IP family (AF_INET or AF_INET6).
* @param secure 0 for UDP or TCP, 1 for TLS (with TCP).
*/
if (OSIP_SUCCESS != eXosip_listen_addr(sip_context, IPPROTO_UDP, nullptr, local_port, AF_INET, 0)) {
spdlog::critical("sip port bind failed.");
eXosip_quit(sip_context);
sip_context = nullptr;
return;
}
...
}
2.2.3 SIP代理发送Regitster请求:
void Device::start() {