Geen omschrijving
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

GB28181Server.js 7.5KB

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