SipUtils.java 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286
  1. package com.genersoft.iot.vmp.gb28181.utils;
  2. import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel;
  3. import com.genersoft.iot.vmp.gb28181.bean.Gb28181Sdp;
  4. import com.genersoft.iot.vmp.gb28181.bean.RemoteAddressInfo;
  5. import com.genersoft.iot.vmp.utils.DateUtil;
  6. import com.genersoft.iot.vmp.utils.GitUtil;
  7. import gov.nist.javax.sip.address.AddressImpl;
  8. import gov.nist.javax.sip.address.SipUri;
  9. import gov.nist.javax.sip.header.Subject;
  10. import gov.nist.javax.sip.message.SIPRequest;
  11. import org.apache.commons.lang3.RandomStringUtils;
  12. import org.slf4j.Logger;
  13. import org.slf4j.LoggerFactory;
  14. import org.springframework.util.ObjectUtils;
  15. import javax.sdp.SdpFactory;
  16. import javax.sdp.SdpParseException;
  17. import javax.sdp.SessionDescription;
  18. import javax.sip.PeerUnavailableException;
  19. import javax.sip.SipFactory;
  20. import javax.sip.header.FromHeader;
  21. import javax.sip.header.Header;
  22. import javax.sip.header.UserAgentHeader;
  23. import javax.sip.message.Request;
  24. import java.text.ParseException;
  25. import java.time.LocalDateTime;
  26. import java.time.format.DateTimeParseException;
  27. import java.util.ArrayList;
  28. import java.util.List;
  29. import java.util.UUID;
  30. /**
  31. * @author panlinlin
  32. * @version 1.0.0
  33. * @description JAIN SIP的工具类
  34. * @createTime 2021年09月27日 15:12:00
  35. */
  36. public class SipUtils {
  37. private final static Logger logger = LoggerFactory.getLogger(SipUtils.class);
  38. public static String getUserIdFromFromHeader(Request request) {
  39. FromHeader fromHeader = (FromHeader)request.getHeader(FromHeader.NAME);
  40. return getUserIdFromFromHeader(fromHeader);
  41. }
  42. /**
  43. * 从subject读取channelId
  44. * */
  45. public static String getChannelIdFromRequest(Request request) {
  46. Header subject = request.getHeader("subject");
  47. if (subject == null) {
  48. // 如果缺失subject
  49. return null;
  50. }
  51. return ((Subject) subject).getSubject().split(":")[0];
  52. }
  53. public static String getUserIdFromFromHeader(FromHeader fromHeader) {
  54. AddressImpl address = (AddressImpl)fromHeader.getAddress();
  55. SipUri uri = (SipUri) address.getURI();
  56. return uri.getUser();
  57. }
  58. public static String getNewViaTag() {
  59. return "z9hG4bK" + RandomStringUtils.randomNumeric(10);
  60. }
  61. public static UserAgentHeader createUserAgentHeader(GitUtil gitUtil) throws PeerUnavailableException, ParseException {
  62. List<String> agentParam = new ArrayList<>();
  63. agentParam.add("WVP-Pro ");
  64. if (gitUtil != null ) {
  65. if (!ObjectUtils.isEmpty(gitUtil.getBuildVersion())) {
  66. agentParam.add("v");
  67. agentParam.add(gitUtil.getBuildVersion() + ".");
  68. }
  69. if (!ObjectUtils.isEmpty(gitUtil.getCommitTime())) {
  70. agentParam.add(gitUtil.getCommitTime());
  71. }
  72. }
  73. return SipFactory.getInstance().createHeaderFactory().createUserAgentHeader(agentParam);
  74. }
  75. public static String getNewFromTag(){
  76. return UUID.randomUUID().toString().replace("-", "");
  77. // return getNewTag();
  78. }
  79. public static String getNewTag(){
  80. return String.valueOf(System.currentTimeMillis());
  81. }
  82. /**
  83. * 云台指令码计算
  84. *
  85. * @param leftRight 镜头左移右移 0:停止 1:左移 2:右移
  86. * @param upDown 镜头上移下移 0:停止 1:上移 2:下移
  87. * @param inOut 镜头放大缩小 0:停止 1:缩小 2:放大
  88. * @param moveSpeed 镜头移动速度 默认 0XFF (0-255)
  89. * @param zoomSpeed 镜头缩放速度 默认 0X1 (0-255)
  90. */
  91. public static String cmdString(int leftRight, int upDown, int inOut, int moveSpeed, int zoomSpeed) {
  92. int cmdCode = 0;
  93. if (leftRight == 2) {
  94. cmdCode|=0x01; // 右移
  95. } else if(leftRight == 1) {
  96. cmdCode|=0x02; // 左移
  97. }
  98. if (upDown == 2) {
  99. cmdCode|=0x04; // 下移
  100. } else if(upDown == 1) {
  101. cmdCode|=0x08; // 上移
  102. }
  103. if (inOut == 2) {
  104. cmdCode |= 0x10; // 放大
  105. } else if(inOut == 1) {
  106. cmdCode |= 0x20; // 缩小
  107. }
  108. StringBuilder builder = new StringBuilder("A50F01");
  109. String strTmp;
  110. strTmp = String.format("%02X", cmdCode);
  111. builder.append(strTmp, 0, 2);
  112. strTmp = String.format("%02X", moveSpeed);
  113. builder.append(strTmp, 0, 2);
  114. builder.append(strTmp, 0, 2);
  115. //优化zoom低倍速下的变倍速率
  116. if ((zoomSpeed > 0) && (zoomSpeed <16))
  117. {
  118. zoomSpeed = 16;
  119. }
  120. strTmp = String.format("%X", zoomSpeed);
  121. builder.append(strTmp, 0, 1).append("0");
  122. //计算校验码
  123. int checkCode = (0XA5 + 0X0F + 0X01 + cmdCode + moveSpeed + moveSpeed + (zoomSpeed /*<< 4*/ & 0XF0)) % 0X100;
  124. strTmp = String.format("%02X", checkCode);
  125. builder.append(strTmp, 0, 2);
  126. return builder.toString();
  127. }
  128. public static String getNewCallId() {
  129. return (int) Math.floor(Math.random() * 1000000000) + "";
  130. }
  131. public static int getTypeCodeFromGbCode(String deviceId) {
  132. if (ObjectUtils.isEmpty(deviceId)) {
  133. return 0;
  134. }
  135. return Integer.parseInt(deviceId.substring(10, 13));
  136. }
  137. /**
  138. * 判断是否是前端外围设备
  139. * @param deviceId
  140. * @return
  141. */
  142. public static boolean isFrontEnd(String deviceId) {
  143. int typeCodeFromGbCode = getTypeCodeFromGbCode(deviceId);
  144. return typeCodeFromGbCode > 130 && typeCodeFromGbCode < 199;
  145. }
  146. /**
  147. * 从请求中获取设备ip地址和端口号
  148. * @param request 请求
  149. * @param sipUseSourceIpAsRemoteAddress false 从via中获取地址, true 直接获取远程地址
  150. * @return 地址信息
  151. */
  152. public static RemoteAddressInfo getRemoteAddressFromRequest(SIPRequest request, boolean sipUseSourceIpAsRemoteAddress) {
  153. String remoteAddress;
  154. int remotePort;
  155. if (sipUseSourceIpAsRemoteAddress) {
  156. remoteAddress = request.getPeerPacketSourceAddress().getHostAddress();
  157. remotePort = request.getPeerPacketSourcePort();
  158. }else {
  159. // 判断RPort是否改变,改变则说明路由nat信息变化,修改设备信息
  160. // 获取到通信地址等信息
  161. remoteAddress = request.getTopmostViaHeader().getReceived();
  162. remotePort = request.getTopmostViaHeader().getRPort();
  163. // 解析本地地址替代
  164. if (ObjectUtils.isEmpty(remoteAddress) || remotePort == -1) {
  165. remoteAddress = request.getPeerPacketSourceAddress().getHostAddress();
  166. remotePort = request.getPeerPacketSourcePort();
  167. }
  168. }
  169. return new RemoteAddressInfo(remoteAddress, remotePort);
  170. }
  171. public static DeviceChannel updateGps(DeviceChannel deviceChannel, String geoCoordSys) {
  172. if (deviceChannel.getLongitude()*deviceChannel.getLatitude() > 0) {
  173. if (geoCoordSys == null) {
  174. geoCoordSys = "WGS84";
  175. }
  176. if ("WGS84".equals(geoCoordSys)) {
  177. deviceChannel.setLongitudeWgs84(deviceChannel.getLongitude());
  178. deviceChannel.setLatitudeWgs84(deviceChannel.getLatitude());
  179. Double[] position = Coordtransform.WGS84ToGCJ02(deviceChannel.getLongitude(), deviceChannel.getLatitude());
  180. deviceChannel.setLongitudeGcj02(position[0]);
  181. deviceChannel.setLatitudeGcj02(position[1]);
  182. }else if ("GCJ02".equals(geoCoordSys)) {
  183. deviceChannel.setLongitudeGcj02(deviceChannel.getLongitude());
  184. deviceChannel.setLatitudeGcj02(deviceChannel.getLatitude());
  185. Double[] position = Coordtransform.GCJ02ToWGS84(deviceChannel.getLongitude(), deviceChannel.getLatitude());
  186. deviceChannel.setLongitudeWgs84(position[0]);
  187. deviceChannel.setLatitudeWgs84(position[1]);
  188. }else {
  189. deviceChannel.setLongitudeGcj02(0.00);
  190. deviceChannel.setLatitudeGcj02(0.00);
  191. deviceChannel.setLongitudeWgs84(0.00);
  192. deviceChannel.setLatitudeWgs84(0.00);
  193. }
  194. }else {
  195. deviceChannel.setLongitudeGcj02(deviceChannel.getLongitude());
  196. deviceChannel.setLatitudeGcj02(deviceChannel.getLatitude());
  197. deviceChannel.setLongitudeWgs84(deviceChannel.getLongitude());
  198. deviceChannel.setLatitudeWgs84(deviceChannel.getLatitude());
  199. }
  200. return deviceChannel;
  201. }
  202. public static Gb28181Sdp parseSDP(String sdpStr) throws SdpParseException {
  203. // jainSip不支持y= f=字段, 移除以解析。
  204. int ssrcIndex = sdpStr.indexOf("y=");
  205. int mediaDescriptionIndex = sdpStr.indexOf("f=");
  206. // 检查是否有y字段
  207. SessionDescription sdp;
  208. String ssrc = null;
  209. String mediaDescription = null;
  210. if (mediaDescriptionIndex == 0 && ssrcIndex == 0) {
  211. sdp = SdpFactory.getInstance().createSessionDescription(sdpStr);
  212. }else {
  213. String lines[] = sdpStr.split("\\r?\\n");
  214. StringBuilder sdpBuffer = new StringBuilder();
  215. for (String line : lines) {
  216. if (line.trim().startsWith("y=")) {
  217. ssrc = line.substring(2);
  218. }else if (line.trim().startsWith("f=")) {
  219. mediaDescription = line.substring(2);
  220. }else {
  221. sdpBuffer.append(line.trim()).append("\r\n");
  222. }
  223. }
  224. sdp = SdpFactory.getInstance().createSessionDescription(sdpBuffer.toString());
  225. }
  226. return Gb28181Sdp.getInstance(sdp, ssrc, mediaDescription);
  227. }
  228. public static String getSsrcFromSdp(String sdpStr) {
  229. // jainSip不支持y= f=字段, 移除以解析。
  230. int ssrcIndex = sdpStr.indexOf("y=");
  231. if (ssrcIndex == 0) {
  232. return null;
  233. }
  234. String lines[] = sdpStr.split("\\r?\\n");
  235. for (String line : lines) {
  236. if (line.trim().startsWith("y=")) {
  237. return line.substring(2);
  238. }
  239. }
  240. return null;
  241. }
  242. public static String parseTime(String timeStr) {
  243. if (ObjectUtils.isEmpty(timeStr)){
  244. return null;
  245. }
  246. LocalDateTime localDateTime;
  247. try {
  248. localDateTime = LocalDateTime.parse(timeStr);
  249. }catch (DateTimeParseException e) {
  250. try {
  251. localDateTime = LocalDateTime.parse(timeStr, DateUtil.formatterISO8601);
  252. }catch (DateTimeParseException e2) {
  253. logger.error("[格式化时间] 无法格式化时间: {}", timeStr);
  254. return null;
  255. }
  256. }
  257. return localDateTime.format(DateUtil.formatterISO8601);
  258. }
  259. }