代码拉取完成,页面将自动刷新
同步操作将从 baiyfcu/NodeJS版本基于GB28181的HTTP网关 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
/**
* 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;
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。