加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
sip_command.js 6.81 KB
一键复制 编辑 原始数据 按行查看 历史
/**
* GB28181服务程序
*/
const xml2js = require('xml2js');
const digest = require('sip/digest');
const config = require('./sip_config');
const log4js = require('./sip_log');
const logger = log4js.getLogger('info');
const realm = config.sip.server.realm;
// 设备信息
let registry = config.registry;
/**
* 封装发送的命令
*/
let command={
// 公用sip对象
sip:null,
/**
* 发送请求目录 命令
*/
catalog: function(rs,deviceId){
//TODO: 这个SN以后看怎么赋值才合理
let SN=1;
const json = {
Query: {
CmdType: 'Catalog',
SN: SN,
DeviceID: deviceId
}
};
const builder = new xml2js.Builder();
const content = builder.buildObject(json);
const username = this.sip.parseUri(rs.headers.to.uri).user;
// 从via解析摄像头的ip 端口
const via = this.sip.parseUri(rs.headers.via)[0];
let cseq = rs.headers.cseq;
cseq.method = 'MESSAGE';
let res = {
method:'MESSAGE',
uri: 'sip:' + username + '@' + via.host + ':' + via.port,
version:rs.version,
headers:{
via : rs.headers.via,
from : rs.headers.from,
to : rs.headers.to,
'call-id' : rs.headers['call-id'],
cseq:cseq,
'Content-Type':'Application/MANSCDP+xml',
'expires':'3600',
'Max-Forwards':70
},
content:content
};
logger.info(res);
this.sip.send(res);
},
/**
* 请求目录回应
* @param {*} rq
* @param {*} result
*/
catalogAck:function(rq,DeviceList){
if(DeviceList){
for(let s in DeviceList[0].Item){
let temp = DeviceList[0].Item[s];
let exists = config.devices.indexOf(temp)>-1;
if(!exists) {
config.devices.push(temp);
}
}
}
this.sip.send(this.sip.makeResponse(rq,200,'OK'));
},
/**
* 接收注册信息,并完成授权过程
*/
register:function(rq){
let username = this.sip.parseUri(rq.headers.to.uri).user;
let userinfo = registry[username];
// 如果不需要认证,生成用户信息
if(!config.authentication && !userinfo){
registry[username] = {password:config.sip.server.password,online:false};
userinfo = registry[username];
}
if(!userinfo) {
logger.error('没有登记的用户 禁止授权:' , username);
let session = {realm: realm};
this.sip.send(digest.challenge(session, this.sip.makeResponse(rq, 401, 'Unauthorized')));
return;
}
else {
userinfo.session = userinfo.session || {realm: realm};
if(!digest.authenticateRequest(userinfo.session, rq, {user: username, password: userinfo.password})) {
let ret0 = digest.challenge(userinfo.session, this.sip.makeResponse(rq, 401, 'Unauthorized'));
this.sip.send(ret0);
}
else {
// 完成授权
userinfo.contact = rq.headers.contact;
let rs = this.sip.makeResponse(rq, 200, 'Ok');
this.sip.send(rs);
logger.info('请求设备目录');
registry[username].online=true;
command.catalog(rq,username);
}
}
},
/**
* 发送invite请求
*/
invite:function(rs,target){
let userinfo = registry[target];
if(userinfo ) { //&& Array.isArray(userinfo.contact) && userinfo.contact.length > 0
let content = 'v=0\r\n'+
'o=fxdigital 0 0 IN IP4 ' + config.sip.server.ip + '\r\n' +
's=Play\r\n'+
'c=IN IP4 ' + config.sip.server.ip + '\r\n'+
't=0 0\r\n'+
'm=video ' + config.sip.media.port + ' RTP/AVP 96 97 98\r\n' +
'a=sendrecv\r\n'+
'a=rtpmap:96 PS/90000\r\n'+
'a=rtpmap:97 MPEG4/90000\r\n'+
'a=rtpmap:98 H264/90000\r\n' +
'y=0000000003\r\n'
;
// 从via解析摄像头的ip 端口
const via = this.sip.parseUri(rs.headers.via)[0];
var via1 = JSON.parse( JSON.stringify(via));
via1.host = config.sip.server.ip;
via1.port = config.sip.server.port;
via1.params.received=config.sip.server.ip;
let cseq = rs.headers.cseq;
cseq.method = 'INVITE';
let res = {
method : cseq.method,
uri : 'sip:' + target + '@' + via.host + ':' + via.port,
version : rs.version,
headers : {
via : [[via1]],
from : {uri: 'sip:' + config.sip.server.account + '@' + config.sip.server.realm,params:{tag:config.rstring()}},
to : {uri: 'sip:' + '34020000001110000001' + '@' + via.host+':' + via.port}, //TODO: 这里暂时写死
'call-id': rs.headers['call-id'],
cseq:cseq,
'Content-Type':'Application/SDP',
'expires':'3600',
'Max-Forwards':70,
'User-Agent':'nodejs gb server',
contact : [{uri:'sip:' + config.sip.server.account + '@' + config.sip.server.ip + ':' + config.sip.server.port}],
subject : target +':1' + ',' + config.sip.server.account + ':0'
},
content:content
};
logger.info(res);
this.sip.send(res);
}
else {
logger.error('username',target,userinfo);
this.sip.send(this.sip.makeResponse(rs, 404, 'Not Found'));
}
},
/**
* 回应心跳
* @param {*} rq
*/
keepalive:function(rq){
// 心跳
const rs = this.sip.makeResponse(rq,200,'OK');
const username = this.sip.parseUri( rq.headers.from.uri).user;
config.registry[username].online = true;
config.registry[username].last = (new Date()).getTime();
this.sip.send(rs);
},
/**
* 回应invite
* @param {*} rs
* @param {*} target
*/
ack:function(rs){
let cseq = rs.headers.cseq;
cseq.method = 'ACK';
let res = {
method:'ACK',
uri: rs.headers.to.uri,
headers:{
via : [],
from : {uri: 'sip:' + config.sip.server.account + '@' + config.sip.server.realm , params:rs.headers.from.params},
to : rs.headers.to,
'call-id': rs.headers['call-id'],
cseq:cseq,
'Max-Forwards':70,
'User-Agent':'nodejs gb server',
contact : [{uri:'sip:' + config.sip.server.account + '@' + config.sip.server.ip + ':' + config.sip.server.port}],
}
};
this.sip.send(res);
}
};
module.exports = command;
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化