Commit 1fcdf5a8f369e020e78d524db2fe3cc7ffc86293
Merge branch 'wvp-28181-2.0' into main-dev
# Conflicts: # src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java # src/main/java/com/genersoft/iot/vmp/service/impl/PlatformServiceImpl.java
Showing
6 changed files
with
81 additions
and
16 deletions
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java
| ... | ... | @@ -35,8 +35,10 @@ import com.genersoft.iot.vmp.storager.IVideoManagerStorage; |
| 35 | 35 | import com.genersoft.iot.vmp.utils.DateUtil; |
| 36 | 36 | import gov.nist.javax.sdp.TimeDescriptionImpl; |
| 37 | 37 | import gov.nist.javax.sdp.fields.TimeField; |
| 38 | +import gov.nist.javax.sdp.fields.URIField; | |
| 38 | 39 | import gov.nist.javax.sip.message.SIPRequest; |
| 39 | 40 | import gov.nist.javax.sip.message.SIPResponse; |
| 41 | +import org.apache.commons.lang3.StringUtils; | |
| 40 | 42 | import org.slf4j.Logger; |
| 41 | 43 | import org.slf4j.LoggerFactory; |
| 42 | 44 | import org.springframework.beans.factory.InitializingBean; |
| ... | ... | @@ -147,8 +149,21 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements |
| 147 | 149 | public void process(RequestEvent evt) { |
| 148 | 150 | // Invite Request消息实现,此消息一般为级联消息,上级给下级发送请求视频指令 |
| 149 | 151 | try { |
| 150 | - SIPRequest request = (SIPRequest) evt.getRequest(); | |
| 151 | - String channelId = SipUtils.getChannelIdFromRequest(request); | |
| 152 | + SIPRequest request = (SIPRequest)evt.getRequest(); | |
| 153 | + String channelIdFromSub = SipUtils.getChannelIdFromRequest(request); | |
| 154 | + | |
| 155 | + // 解析sdp消息, 使用jainsip 自带的sdp解析方式 | |
| 156 | + String contentString = new String(request.getRawContent()); | |
| 157 | + Gb28181Sdp gb28181Sdp = SipUtils.parseSDP(contentString); | |
| 158 | + SessionDescription sdp = gb28181Sdp.getBaseSdb(); | |
| 159 | + String sessionName = sdp.getSessionName().getValue(); | |
| 160 | + String channelIdFromSdp = null; | |
| 161 | + if(StringUtils.equalsIgnoreCase("Playback", sessionName)){ | |
| 162 | + URIField uriField = (URIField)sdp.getURI(); | |
| 163 | + channelIdFromSdp = uriField.getURI().split(":")[0]; | |
| 164 | + } | |
| 165 | + final String channelId = StringUtils.isNotBlank(channelIdFromSdp) ? channelIdFromSdp : channelIdFromSub; | |
| 166 | + | |
| 152 | 167 | String requesterId = SipUtils.getUserIdFromFromHeader(request); |
| 153 | 168 | CallIdHeader callIdHeader = (CallIdHeader) request.getHeader(CallIdHeader.NAME); |
| 154 | 169 | if (requesterId == null || channelId == null) { |
| ... | ... | @@ -257,12 +272,6 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements |
| 257 | 272 | } |
| 258 | 273 | return; |
| 259 | 274 | } |
| 260 | - // 解析sdp消息, 使用jainsip 自带的sdp解析方式 | |
| 261 | - String contentString = new String(request.getRawContent()); | |
| 262 | - | |
| 263 | - Gb28181Sdp gb28181Sdp = SipUtils.parseSDP(contentString); | |
| 264 | - SessionDescription sdp = gb28181Sdp.getBaseSdb(); | |
| 265 | - String sessionName = sdp.getSessionName().getValue(); | |
| 266 | 275 | |
| 267 | 276 | Long startTime = null; |
| 268 | 277 | Long stopTime = null; | ... | ... |
src/main/java/com/genersoft/iot/vmp/gb28181/utils/XmlUtil.java
| ... | ... | @@ -78,6 +78,50 @@ public class XmlUtil { |
| 78 | 78 | } |
| 79 | 79 | |
| 80 | 80 | /** |
| 81 | + * 获取element对象的text的值 | |
| 82 | + * | |
| 83 | + * @param em 节点的对象 | |
| 84 | + * @param tag 节点的tag | |
| 85 | + * @return 节点 | |
| 86 | + */ | |
| 87 | + public static Double getDouble(Element em, String tag) { | |
| 88 | + if (null == em) { | |
| 89 | + return null; | |
| 90 | + } | |
| 91 | + Element e = em.element(tag); | |
| 92 | + if (null == e) { | |
| 93 | + return null; | |
| 94 | + } | |
| 95 | + String text = e.getText().trim(); | |
| 96 | + if (ObjectUtils.isEmpty(text) || !NumberUtils.isParsable(text)) { | |
| 97 | + return null; | |
| 98 | + } | |
| 99 | + return Double.parseDouble(text); | |
| 100 | + } | |
| 101 | + | |
| 102 | + /** | |
| 103 | + * 获取element对象的text的值 | |
| 104 | + * | |
| 105 | + * @param em 节点的对象 | |
| 106 | + * @param tag 节点的tag | |
| 107 | + * @return 节点 | |
| 108 | + */ | |
| 109 | + public static Integer getInteger(Element em, String tag) { | |
| 110 | + if (null == em) { | |
| 111 | + return null; | |
| 112 | + } | |
| 113 | + Element e = em.element(tag); | |
| 114 | + if (null == e) { | |
| 115 | + return null; | |
| 116 | + } | |
| 117 | + String text = e.getText().trim(); | |
| 118 | + if (ObjectUtils.isEmpty(text) || !NumberUtils.isParsable(text)) { | |
| 119 | + return null; | |
| 120 | + } | |
| 121 | + return Integer.parseInt(text); | |
| 122 | + } | |
| 123 | + | |
| 124 | + /** | |
| 81 | 125 | * 递归解析xml节点,适用于 多节点数据 |
| 82 | 126 | * |
| 83 | 127 | * @param node node | ... | ... |
src/main/java/com/genersoft/iot/vmp/service/impl/PlatformChannelServiceImpl.java
| ... | ... | @@ -136,7 +136,7 @@ public class PlatformChannelServiceImpl implements IPlatformChannelService { |
| 136 | 136 | deviceChannelList.add(deviceChannel); |
| 137 | 137 | } |
| 138 | 138 | return deviceChannelList; |
| 139 | - } else if (catalog == null || !catalogId.equals(platform.getDeviceGBId())) { | |
| 139 | + } else if (catalog == null && !catalogId.equals(platform.getDeviceGBId())) { | |
| 140 | 140 | logger.warn("未查询到目录{}的信息", catalogId); |
| 141 | 141 | return null; |
| 142 | 142 | } | ... | ... |
src/main/java/com/genersoft/iot/vmp/service/impl/PlatformServiceImpl.java
| ... | ... | @@ -43,16 +43,15 @@ import javax.sip.InvalidArgumentException; |
| 43 | 43 | import javax.sip.ResponseEvent; |
| 44 | 44 | import javax.sip.PeerUnavailableException; |
| 45 | 45 | import javax.sip.SipException; |
| 46 | -import javax.sip.SipFactory; | |
| 47 | -import javax.sip.address.Address; | |
| 48 | -import javax.sip.address.SipURI; | |
| 49 | -import javax.sip.header.*; | |
| 50 | -import javax.sip.message.Request; | |
| 51 | 46 | import java.text.ParseException; |
| 52 | 47 | import java.util.HashMap; |
| 53 | 48 | import java.util.List; |
| 54 | 49 | import java.util.Map; |
| 55 | 50 | import java.util.UUID; |
| 51 | +import java.util.HashMap; | |
| 52 | +import java.util.List; | |
| 53 | +import java.util.Map; | |
| 54 | +import java.util.UUID; | |
| 56 | 55 | import java.util.*; |
| 57 | 56 | |
| 58 | 57 | /** |
| ... | ... | @@ -392,7 +391,6 @@ public class PlatformServiceImpl implements IPlatformService { |
| 392 | 391 | ()-> registerTask(platform, null), |
| 393 | 392 | userSetting.getRegisterAgainAfterTime() * 1000); |
| 394 | 393 | } |
| 395 | - | |
| 396 | 394 | } |
| 397 | 395 | } |
| 398 | 396 | ... | ... |
src/main/java/com/genersoft/iot/vmp/utils/DateUtil.java
| ... | ... | @@ -31,6 +31,11 @@ public class DateUtil { |
| 31 | 31 | private static final String ISO8601_PATTERN = "yyyy-MM-dd'T'HH:mm:ss"; |
| 32 | 32 | |
| 33 | 33 | /** |
| 34 | + * iso8601时间格式带时区,例如:2024-02-21T11:10:36+08:00 | |
| 35 | + */ | |
| 36 | + private static final String ISO8601_ZONE_PATTERN = "yyyy-MM-dd'T'HH:mm:ssXXX"; | |
| 37 | + | |
| 38 | + /** | |
| 34 | 39 | * wvp内部统一时间格式 |
| 35 | 40 | */ |
| 36 | 41 | public static final String PATTERN = "yyyy-MM-dd HH:mm:ss"; |
| ... | ... | @@ -49,6 +54,7 @@ public class DateUtil { |
| 49 | 54 | |
| 50 | 55 | public static final DateTimeFormatter formatterCompatibleISO8601 = DateTimeFormatter.ofPattern(ISO8601_COMPATIBLE_PATTERN, Locale.getDefault()).withZone(ZoneId.of(zoneStr)); |
| 51 | 56 | public static final DateTimeFormatter formatterISO8601 = DateTimeFormatter.ofPattern(ISO8601_PATTERN, Locale.getDefault()).withZone(ZoneId.of(zoneStr)); |
| 57 | + public static final DateTimeFormatter formatterZoneISO8601 = DateTimeFormatter.ofPattern(ISO8601_ZONE_PATTERN, Locale.getDefault()).withZone(ZoneId.of(zoneStr)); | |
| 52 | 58 | public static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern(PATTERN, Locale.getDefault()).withZone(ZoneId.of(zoneStr)); |
| 53 | 59 | public static final DateTimeFormatter DateFormatter = DateTimeFormatter.ofPattern(date_PATTERN, Locale.getDefault()).withZone(ZoneId.of(zoneStr)); |
| 54 | 60 | public static final DateTimeFormatter urlFormatter = DateTimeFormatter.ofPattern(URL_PATTERN, Locale.getDefault()).withZone(ZoneId.of(zoneStr)); |
| ... | ... | @@ -59,7 +65,13 @@ public class DateUtil { |
| 59 | 65 | } |
| 60 | 66 | |
| 61 | 67 | public static String ISO8601Toyyyy_MM_dd_HH_mm_ss(String formatTime) { |
| 62 | - return formatter.format(formatterCompatibleISO8601.parse(formatTime)); | |
| 68 | + // 三种日期格式都尝试,为了兼容不同厂家的日期格式 | |
| 69 | + if (verification(formatTime, formatterCompatibleISO8601)) { | |
| 70 | + return formatter.format(formatterCompatibleISO8601.parse(formatTime)); | |
| 71 | + } else if (verification(formatTime, formatterZoneISO8601)) { | |
| 72 | + return formatter.format(formatterZoneISO8601.parse(formatTime)); | |
| 73 | + } | |
| 74 | + return formatter.format(formatterISO8601.parse(formatTime)); | |
| 63 | 75 | } |
| 64 | 76 | |
| 65 | 77 | public static String urlToyyyy_MM_dd_HH_mm_ss(String formatTime) { | ... | ... |
src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/platform/PlatformController.java
| ... | ... | @@ -239,6 +239,8 @@ public class PlatformController { |
| 239 | 239 | if (parentPlatformCatch == null) { |
| 240 | 240 | throw new ControllerException(ErrorCode.ERROR100.getCode(), "平台不存在"); |
| 241 | 241 | } |
| 242 | + parentPlatform.setEnable(false); | |
| 243 | + storager.updateParentPlatform(parentPlatform); | |
| 242 | 244 | // 发送离线消息,无论是否成功都删除缓存 |
| 243 | 245 | try { |
| 244 | 246 | commanderForPlatform.unregister(parentPlatform, parentPlatformCatch.getSipTransactionInfo(), (event -> { | ... | ... |