説明なし
選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

GB28181Server.js 9.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269
  1. const digest = require('./sip/digest');
  2. const SIP = require('./sip/sip');
  3. const context = require('./core/ctx');
  4. const Logger = require('./core/logger');
  5. const NodeSipSession = require('./GB28181Session');
  6. const NtvAuthModule = require('./NtvAuthModule');
  7. //GB28181 SIP服务器
  8. class NodeSIPServer {
  9. constructor(config) {
  10. //console.log(config);
  11. this.listen = config.GB28181.sipServer.listen || 5060;
  12. this.host = config.GB28181.sipServer.host || '127.0.0.1';//SIP服务器主机地址
  13. this.defaultPassword = config.GB28181.sipServer.password || '12345678';
  14. this.id = config.GB28181.sipServer.serial||'34020000002000000001';
  15. this.domain = config.GB28181.sipServer.realm || "3402000000";//SIP服务器域
  16. this.config = config;
  17. //临时用户信息
  18. this.userinfo = {};
  19. //会话
  20. this.dialogs = {};
  21. //ntv 认证
  22. this.authModule = new NtvAuthModule(config.GB28181.authServer);
  23. }
  24. run() {
  25. //监听端口,接收消息
  26. this.uas = SIP.create({ publicAddress: this.host, port: this.listen }, (request, remote) => {
  27. switch (request.method) {
  28. //当前域 注册/注销 REGISTER
  29. case 'REGISTER':
  30. context.nodeEvent.emit('register', request, remote);
  31. break;
  32. //上级域/媒体接收者 INVITE
  33. case 'INVITE':
  34. context.nodeEvent.emit('invite', request, remote);
  35. break;
  36. //当前域 MESSAGE 消息
  37. case 'MESSAGE':
  38. context.nodeEvent.emit('message', request, remote);
  39. break;
  40. //上级域/媒体接收者 ACK/BYE Step(11/13)
  41. case 'ACK':
  42. context.nodeEvent.emit('ack', request, remote);
  43. break;
  44. case 'BYE':
  45. context.nodeEvent.emit('bye', request, remote);
  46. break;
  47. default:
  48. this.uas.send(SIP.makeResponse(request, 405, 'Method not allowed'));
  49. break;
  50. }
  51. });
  52. //注册&注销 请求
  53. context.nodeEvent.on('register', (request, remote) => {
  54. this.ntv_auth(request, remote);
  55. });
  56. //处理消息
  57. context.nodeEvent.on('message', (request) => {
  58. this.uas.send(SIP.makeResponse(request, 200, 'Ok'));
  59. let userid = SIP.parseUri(request.headers.from.uri).user;
  60. //处理消息
  61. if (context.sessions.has(userid)) {
  62. let session = context.sessions.get(userid);
  63. session.onMessage(request);
  64. }
  65. });
  66. Logger.log(`GB28181 Sip Server Started on Port: ${this.listen}`);
  67. }
  68. stop() {
  69. //服务器下线
  70. this.uas.destroy();
  71. }
  72. ntv_auth(request, remote){
  73. let serverInfo = SIP.parseUri(request.uri);
  74. if (!request.headers || !request.headers.to || !request.headers.from || !serverInfo.user) {
  75. this.uas.send(SIP.makeResponse(request, 400, 'missing to header.'));
  76. return;
  77. }
  78. else if (!request.headers.to.uri) {
  79. this.uas.send(SIP.makeResponse(request, 400, 'missing username on to header.'));
  80. return;
  81. }
  82. else if (!request.headers.contact || request.headers.contact.length == 0) {
  83. this.uas.send(SIP.makeResponse(request, 400, 'missing contact header.'));
  84. return;
  85. }
  86. let toInfo = SIP.parseUri(request.headers.to.uri);
  87. let fromInfo = SIP.parseUri(request.headers.from.uri);
  88. //用户 标识
  89. let userId = fromInfo.user;
  90. Logger.log(`[${userId}] register protocol=${remote.protocol} ip=${remote.address} port=${remote.port} `);
  91. //安全性检查
  92. if (toInfo.user.length != 20 || fromInfo.user.length != 20 || toInfo.user != fromInfo.user/* || serverInfo.user != this.id*/) {
  93. Logger.log(`[${userId}] check fail. `);
  94. return;
  95. }
  96. let that = this;
  97. //TODO ntv 在这里对接接口
  98. this.authModule.auth(userId,function (data){
  99. if(data.code==0){
  100. let auto_play = "";
  101. if("err_desc" in data) auto_play = data.err_desc;
  102. that.auth(request, remote,auto_play);
  103. }else{
  104. Logger.log(`[${userId}] 业务层认证失败:${data.err_desc} `);
  105. }
  106. });
  107. }
  108. //身份验证
  109. auth(request, remote,auto_play) {
  110. let serverInfo = SIP.parseUri(request.uri);
  111. if (!request.headers || !request.headers.to || !request.headers.from || !serverInfo.user) {
  112. this.uas.send(SIP.makeResponse(request, 400, 'missing to header.'));
  113. return;
  114. }
  115. else if (!request.headers.to.uri) {
  116. this.uas.send(SIP.makeResponse(request, 400, 'missing username on to header.'));
  117. return;
  118. }
  119. else if (!request.headers.contact || request.headers.contact.length == 0) {
  120. this.uas.send(SIP.makeResponse(request, 400, 'missing contact header.'));
  121. return;
  122. }
  123. let toInfo = SIP.parseUri(request.headers.to.uri);
  124. let fromInfo = SIP.parseUri(request.headers.from.uri);
  125. //用户 标识
  126. let userId = fromInfo.user;
  127. Logger.log(`[${userId}] register protocol=${remote.protocol} ip=${remote.address} port=${remote.port} `);
  128. //安全性检查
  129. if (toInfo.user.length != 20 || fromInfo.user.length != 20 || toInfo.user != fromInfo.user /*|| serverInfo.user != this.id*/) {
  130. Logger.log(`[${userId}] check fail. `);
  131. return;
  132. }
  133. //判断是否携带鉴权字段
  134. if (!this.userinfo[userId] || !request.headers.authorization) {
  135. //会话标识
  136. this.userinfo[userId] = { realm: this.domain };
  137. Logger.log(`[${userId}] auth start. `);
  138. this.uas.send(digest.challenge(this.userinfo[userId], SIP.makeResponse(request, 401, 'Authentication Required.')));
  139. return;
  140. }
  141. else {
  142. if (request.headers.authorization && !digest.authenticateRequest(this.userinfo[userId], request, { password: this.defaultPassword })) {
  143. this.uas.send(digest.challenge(this.userinfo[userId], SIP.makeResponse(request, 406, 'Not Acceptable.')));
  144. Logger.log(`[${userId}] auth fail. `);
  145. return;
  146. }
  147. delete this.userinfo[userId];
  148. Logger.log(`[${userId}] auth success. `);
  149. }
  150. //注册有效期
  151. let expires = request.headers.expires;
  152. //注册/保存会话信息
  153. if (parseInt(expires) != 0) {
  154. //ntv TODO这里的逻辑有问题,或者可以删掉
  155. //新的会话
  156. if (context.sessions.has(userId)) {
  157. let session = context.sessions.get(userId);
  158. //在注册有效期内,刷新注册还是重新注册
  159. //重新注册
  160. if (session.request.headers['call-id'] != request.headers['call-id']) {
  161. //重新注册是否需要断开之前的会话
  162. let dialogs = [];
  163. context.dialogs.forEach(dialog => {
  164. if (dialog.deviceId === userId)
  165. dialogs.push(dialog);
  166. });
  167. //删除对话
  168. dialogs.forEach(dialog => {
  169. let index = context.dialogs.indexOf(dialog);
  170. if (index > -1) {
  171. context.dialogs.splice(index, 1);
  172. }
  173. });
  174. session.request = request;
  175. }
  176. //刷新过期时间
  177. session.expires = expires || this.expires;
  178. Logger.log(`[${userId}] device register refresh.`);
  179. }
  180. else {
  181. //新的设备加入
  182. Logger.log(`[${userId}] new sip session start.`);
  183. let session = new NodeSipSession(this.config, userId, { request: request, info: remote }, this.uas);
  184. session.expires = expires || this.expires;
  185. session.run(this.authModule,auto_play);
  186. }
  187. }
  188. else {
  189. //注销 ntv modify
  190. if (context.sessions.has(userId)){
  191. let session = context.sessions.get(userId);
  192. Logger.log(`[${userId}] lotout.`);
  193. context.nodeEvent.emit('logout', session);
  194. session.stop();
  195. }
  196. }
  197. //通过验证 ,增加 Date 字段 (上下级和设备之间校时功能)
  198. this.uas.send(SIP.makeResponse(request, 200, 'OK', { headers: { date: this.getNowTimeParse(), expires: (expires || this.expires) } }));
  199. }
  200. //获取当前时间
  201. getNowTimeParse() {
  202. const time = new Date();
  203. const YYYY = time.getFullYear();
  204. const MM = time.getMonth() < 9 ? '0' + (time.getMonth() + 1) : (time.getMonth() + 1);
  205. const DD = time.getDate() < 10 ? '0' + time.getDate() : time.getDate();
  206. const hh = time.getHours() < 10 ? '0' + time.getHours() : time.getHours();
  207. const mm = time.getMinutes() < 10 ? '0' + time.getMinutes() : time.getMinutes();
  208. const ss = time.getSeconds() < 10 ? '0' + time.getSeconds() : time.getSeconds();
  209. const ms = time.getMilliseconds()
  210. return `${YYYY}-${MM}-${DD}T${hh}:${mm}:${ss}.${ms}`;
  211. }
  212. }
  213. module.exports = NodeSIPServer