Commit 85b24ea06b0579dd13551fbf92a0fe243adb9792
Merge branch 'master_dev_msa0311' into 'master_dev'
refactor: GBT28181结构调整 See merge request yunteng/thingskit!368
Showing
41 changed files
with
1576 additions
and
1651 deletions
Too many changes to show.
To preserve performance only 41 of 57 files are displayed.
@@ -36,7 +36,6 @@ public class TkVideoControlController extends BaseController { | @@ -36,7 +36,6 @@ public class TkVideoControlController extends BaseController { | ||
36 | 36 | ||
37 | @GetMapping("/start/{deviceId}/{channelId}") | 37 | @GetMapping("/start/{deviceId}/{channelId}") |
38 | @ApiOperation(value = "视频点播/预览") | 38 | @ApiOperation(value = "视频点播/预览") |
39 | -// @PreAuthorize("@check.checkPermissions({'SYS_ADMIN','PLATFORM_ADMIN','TENANT_ADMIN','CUSTOMER_USER'},{'api:yt:video:control:play'})") | ||
40 | @PreAuthorize("hasAnyAuthority('SYS_ADMIN','PLATFORM_ADMIN','TENANT_ADMIN','CUSTOMER_USER')") | 39 | @PreAuthorize("hasAnyAuthority('SYS_ADMIN','PLATFORM_ADMIN','TENANT_ADMIN','CUSTOMER_USER')") |
41 | public DeferredResult<ResponseResult<StreamContentDTO>> startPlay( | 40 | public DeferredResult<ResponseResult<StreamContentDTO>> startPlay( |
42 | @PathVariable("deviceId") String tbDeviceId, @PathVariable("channelId") String channelId) | 41 | @PathVariable("deviceId") String tbDeviceId, @PathVariable("channelId") String channelId) |
@@ -3,16 +3,17 @@ package org.thingsboard.server.controller.yunteng.media; | @@ -3,16 +3,17 @@ package org.thingsboard.server.controller.yunteng.media; | ||
3 | import com.fasterxml.jackson.databind.JsonNode; | 3 | import com.fasterxml.jackson.databind.JsonNode; |
4 | import io.swagger.annotations.Api; | 4 | import io.swagger.annotations.Api; |
5 | import io.swagger.annotations.ApiOperation; | 5 | import io.swagger.annotations.ApiOperation; |
6 | +import javax.servlet.http.HttpServletRequest; | ||
6 | import lombok.RequiredArgsConstructor; | 7 | import lombok.RequiredArgsConstructor; |
7 | import lombok.extern.slf4j.Slf4j; | 8 | import lombok.extern.slf4j.Slf4j; |
9 | +import org.json.JSONObject; | ||
8 | import org.springframework.web.bind.annotation.*; | 10 | import org.springframework.web.bind.annotation.*; |
11 | +import org.springframework.web.context.request.async.DeferredResult; | ||
9 | import org.thingsboard.server.common.data.exception.ThingsboardException; | 12 | import org.thingsboard.server.common.data.exception.ThingsboardException; |
10 | import org.thingsboard.server.common.data.yunteng.constant.FastIotConstants; | 13 | import org.thingsboard.server.common.data.yunteng.constant.FastIotConstants; |
11 | -import org.thingsboard.server.common.data.yunteng.dto.DeviceDTO; | ||
12 | import org.thingsboard.server.common.data.yunteng.dto.sip.VideoChanelDTO; | 14 | import org.thingsboard.server.common.data.yunteng.dto.sip.VideoChanelDTO; |
13 | import org.thingsboard.server.common.data.yunteng.dto.sip.hook.param.*; | 15 | import org.thingsboard.server.common.data.yunteng.dto.sip.hook.param.*; |
14 | import org.thingsboard.server.controller.BaseController; | 16 | import org.thingsboard.server.controller.BaseController; |
15 | -import org.thingsboard.server.dao.yunteng.service.TkDeviceService; | ||
16 | import org.thingsboard.server.dao.yunteng.service.media.TkMediaServerService; | 17 | import org.thingsboard.server.dao.yunteng.service.media.TkMediaServerService; |
17 | import org.thingsboard.server.dao.yunteng.service.media.TkVideoChannelService; | 18 | import org.thingsboard.server.dao.yunteng.service.media.TkVideoChannelService; |
18 | import org.thingsboard.server.service.yunteng.media.TkVideoControlService; | 19 | import org.thingsboard.server.service.yunteng.media.TkVideoControlService; |
@@ -57,21 +58,140 @@ public class ZLMediaKitHookController extends BaseController { | @@ -57,21 +58,140 @@ public class ZLMediaKitHookController extends BaseController { | ||
57 | @ResponseBody | 58 | @ResponseBody |
58 | @PostMapping(value = "/on_stream_none_reader", produces = "application/json;charset=UTF-8") | 59 | @PostMapping(value = "/on_stream_none_reader", produces = "application/json;charset=UTF-8") |
59 | @ApiOperation(value = "流无人观看时事件,用户可以通过此事件选择是否关闭无人看的流") | 60 | @ApiOperation(value = "流无人观看时事件,用户可以通过此事件选择是否关闭无人看的流") |
60 | - public JsonNode onStreamNoneReader(@RequestBody OnStreamNoneReaderHookParam param) throws ThingsboardException { | 61 | + public JsonNode onStreamNoneReader(@RequestBody OnStreamNoneReaderHookParam param) |
62 | + throws ThingsboardException { | ||
61 | JsonNode result = tkMediaServerService.zlmOnStreamNoneReader(param); | 63 | JsonNode result = tkMediaServerService.zlmOnStreamNoneReader(param); |
62 | - if(result.has(FastIotConstants.ZLMediaBody.CHANNEL_ID) &&result.has(FastIotConstants.ZLMediaBody.CAMERA_CODE)){ | 64 | + if (result.has(FastIotConstants.ZLMediaBody.CHANNEL_ID) |
65 | + && result.has(FastIotConstants.ZLMediaBody.CAMERA_CODE)) { | ||
63 | String channelId = result.get(FastIotConstants.ZLMediaBody.CHANNEL_ID).asText(); | 66 | String channelId = result.get(FastIotConstants.ZLMediaBody.CHANNEL_ID).asText(); |
64 | String cameraCode = result.get(FastIotConstants.ZLMediaBody.CAMERA_CODE).asText(); | 67 | String cameraCode = result.get(FastIotConstants.ZLMediaBody.CAMERA_CODE).asText(); |
65 | - VideoChanelDTO chanelDTO = tkVideoChannelService.findVideoChannelById(cameraCode,channelId, null); | ||
66 | - controlService.byeCmdInSsrcTransaction(chanelDTO.getTenantId(), | ||
67 | - false, | ||
68 | - chanelDTO.getDeviceId(), | ||
69 | - cameraCode,channelId,result.get(FastIotConstants.ZLMediaBody.SSRCINFO_STREAM).asText(), | ||
70 | - fromDeviceRpcResponse->{ | ||
71 | - | ||
72 | - }); | ||
73 | - tkVideoChannelService.updateVideoChannelStreamId(null, cameraCode, channelId);//storager.stopPlay(streamInfo.getDeviceID(), streamInfo.getChannelId()); | 68 | + VideoChanelDTO chanelDTO = |
69 | + tkVideoChannelService.findVideoChannelById(cameraCode, channelId, null); | ||
70 | + controlService.byeCmdInSsrcTransaction( | ||
71 | + chanelDTO.getTenantId(), | ||
72 | + false, | ||
73 | + chanelDTO.getDeviceId(), | ||
74 | + cameraCode, | ||
75 | + channelId, | ||
76 | + result.get(FastIotConstants.ZLMediaBody.SSRCINFO_STREAM).asText(), | ||
77 | + fromDeviceRpcResponse -> {}); | ||
78 | + tkVideoChannelService.updateVideoChannelStreamId( | ||
79 | + null, | ||
80 | + cameraCode, | ||
81 | + channelId); // storager.stopPlay(streamInfo.getDeviceID(), streamInfo.getChannelId()); | ||
74 | } | 82 | } |
75 | return result; | 83 | return result; |
76 | } | 84 | } |
85 | + | ||
86 | + /** 流未找到事件,用户可以在此事件触发时,立即去拉流,这样可以实现按需拉流;此事件对回复不敏感。 */ | ||
87 | + @ResponseBody | ||
88 | + @PostMapping(value = "/on_stream_not_found", produces = "application/json;charset=UTF-8") | ||
89 | + public DeferredResult<HookResult> onStreamNotFound(@RequestBody OnStreamNotFoundHookParam param) { | ||
90 | + // log.error("WEBHOOK流未找到【on_stream_not_found】,API参数【{}】",JSONObject.toJSONString(param)); | ||
91 | + | ||
92 | + DeferredResult<HookResult> defaultResult = new DeferredResult<>(); | ||
93 | + | ||
94 | + // MediaServerItem mediaInfo = mediaServerService.getOne(param.getMediaServerId()); | ||
95 | + // if (!userSetting.isAutoApplyPlay() || mediaInfo == null) { | ||
96 | + // defaultResult.setResult(new HookResult(ErrorCode.ERROR404.getCode(), | ||
97 | + // ErrorCode.ERROR404.getMsg())); | ||
98 | + // return defaultResult; | ||
99 | + // } | ||
100 | + // | ||
101 | + // if ("rtp".equals(param.getApp())) { | ||
102 | + // String[] s = param.getStream().split("_"); | ||
103 | + // if (!mediaInfo.isRtpEnable() || s.length != 2) { | ||
104 | + // defaultResult.setResult(HookResult.SUCCESS()); | ||
105 | + // return defaultResult; | ||
106 | + // } | ||
107 | + // String deviceId = s[0]; | ||
108 | + // String channelId = s[1]; | ||
109 | + // Device device = redisCatchStorage.getDevice(deviceId); | ||
110 | + // if (device == null) { | ||
111 | + // defaultResult.setResult(new HookResult(ErrorCode.ERROR404.getCode(), | ||
112 | + // ErrorCode.ERROR404.getMsg())); | ||
113 | + // return defaultResult; | ||
114 | + // } | ||
115 | + // DeviceChannel deviceChannel = storager.queryChannel(deviceId, channelId); | ||
116 | + // if (deviceChannel == null) { | ||
117 | + // defaultResult.setResult(new HookResult(ErrorCode.ERROR404.getCode(), | ||
118 | + // ErrorCode.ERROR404.getMsg())); | ||
119 | + // return defaultResult; | ||
120 | + // } | ||
121 | + // logger.info("[ZLM HOOK] 流未找到, 发起自动点播:{}->{}->{}/{}", param.getMediaServerId(), | ||
122 | + // param.getSchema(), param.getApp(), param.getStream()); | ||
123 | + // RequestMessage msg = new RequestMessage(); | ||
124 | + // String key = DeferredResultHolder.CALLBACK_CMD_PLAY + deviceId + channelId; | ||
125 | + // boolean exist = resultHolder.exist(key, null); | ||
126 | + // msg.setKey(key); | ||
127 | + // String uuid = UUID.randomUUID().toString(); | ||
128 | + // msg.setId(uuid); | ||
129 | + // DeferredResult<HookResult> result = new | ||
130 | + // DeferredResult<>(userSetting.getPlayTimeout().longValue()); | ||
131 | + // DeferredResultEx<HookResult> deferredResultEx = new DeferredResultEx<>(result); | ||
132 | + // | ||
133 | + // result.onTimeout(() -> { | ||
134 | + // logger.info("点播接口等待超时"); | ||
135 | + // // 释放rtpserver | ||
136 | + // msg.setData(new HookResult(ErrorCode.ERROR100.getCode(), "点播超时")); | ||
137 | + // resultHolder.invokeResult(msg); | ||
138 | + // }); | ||
139 | + // // TODO 在点播未成功的情况下在此调用接口点播会导致返回的流地址ip错误 | ||
140 | + // deferredResultEx.setFilter(result1 -> { | ||
141 | + // WVPResult<StreamInfo> wvpResult1 = (WVPResult<StreamInfo>) result1; | ||
142 | + // HookResult resultForEnd = new HookResult(); | ||
143 | + // resultForEnd.setCode(wvpResult1.getCode()); | ||
144 | + // resultForEnd.setMsg(wvpResult1.getMsg()); | ||
145 | + // return resultForEnd; | ||
146 | + // }); | ||
147 | + // | ||
148 | + // // 录像查询以channelId作为deviceId查询 | ||
149 | + // resultHolder.put(key, uuid, deferredResultEx); | ||
150 | + // | ||
151 | + // if (!exist) { | ||
152 | + // playService.play(mediaInfo, deviceId, channelId, null, eventResult -> { | ||
153 | + // msg.setData(new HookResult(eventResult.statusCode, eventResult.msg)); | ||
154 | + // resultHolder.invokeResult(msg); | ||
155 | + // }, null); | ||
156 | + // } | ||
157 | + // return result; | ||
158 | + // } else { | ||
159 | + // // 拉流代理 | ||
160 | + // StreamProxyItem streamProxyByAppAndStream = | ||
161 | + // streamProxyService.getStreamProxyByAppAndStream(param.getApp(), param.getStream()); | ||
162 | + // if (streamProxyByAppAndStream != null && | ||
163 | + // streamProxyByAppAndStream.isEnable_disable_none_reader()) { | ||
164 | + // streamProxyService.start(param.getApp(), param.getStream()); | ||
165 | + // } | ||
166 | + // DeferredResult<HookResult> result = new DeferredResult<>(); | ||
167 | + // result.setResult(HookResult.SUCCESS()); | ||
168 | + // return result; | ||
169 | + // } | ||
170 | + return defaultResult; | ||
171 | + } | ||
172 | + | ||
173 | + /** 服务器启动事件,可以用于监听服务器崩溃重启;此事件对回复不敏感。 */ | ||
174 | + @ResponseBody | ||
175 | + @PostMapping(value = "/on_server_started", produces = "application/json;charset=UTF-8") | ||
176 | + public HookResult onServerStarted( | ||
177 | + HttpServletRequest request, @RequestBody JSONObject jsonObject) { | ||
178 | + // | ||
179 | + // log.error("WEBHOOK服务器已启动【on_server_started】,请求对象【{}】,API参数【{}】",JSONObject.toJSONString(request),jsonObject); | ||
180 | + // jsonObject.put("ip", request.getRemoteAddr()); | ||
181 | + // ZLMServerConfig zlmServerConfig = JSON.to(ZLMServerConfig.class, jsonObject); | ||
182 | + // zlmServerConfig.setIp(request.getRemoteAddr()); | ||
183 | + // logger.info("[ZLM HOOK] zlm 启动 " + zlmServerConfig.getGeneralMediaServerId()); | ||
184 | + // taskExecutor.execute(() -> { | ||
185 | + // List<ZlmHttpHookSubscribe.Event> subscribes = | ||
186 | + // this.subscribe.getSubscribes(HookType.on_server_started); | ||
187 | + // if (subscribes != null && subscribes.size() > 0) { | ||
188 | + // for (ZlmHttpHookSubscribe.Event subscribe : subscribes) { | ||
189 | + // subscribe.response(null, jsonObject); | ||
190 | + // } | ||
191 | + // } | ||
192 | + // mediaServerService.zlmServerOnline(zlmServerConfig); | ||
193 | + // }); | ||
194 | + | ||
195 | + return HookResult.SUCCESS(); | ||
196 | + } | ||
77 | } | 197 | } |
1 | /** | 1 | /** |
2 | * Copyright © 2016-2022 The Thingsboard Authors | 2 | * Copyright © 2016-2022 The Thingsboard Authors |
3 | * | 3 | * |
4 | - * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | - * you may not use this file except in compliance with the License. | ||
6 | - * You may obtain a copy of the License at | 4 | + * <p>Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file |
5 | + * except in compliance with the License. You may obtain a copy of the License at | ||
7 | * | 6 | * |
8 | - * http://www.apache.org/licenses/LICENSE-2.0 | 7 | + * <p>http://www.apache.org/licenses/LICENSE-2.0 |
9 | * | 8 | * |
10 | - * Unless required by applicable law or agreed to in writing, software | ||
11 | - * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | - * See the License for the specific language governing permissions and | 9 | + * <p>Unless required by applicable law or agreed to in writing, software distributed under the |
10 | + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either | ||
11 | + * express or implied. See the License for the specific language governing permissions and | ||
14 | * limitations under the License. | 12 | * limitations under the License. |
15 | */ | 13 | */ |
16 | package org.thingsboard.server.service.transport; | 14 | package org.thingsboard.server.service.transport; |
@@ -37,7 +35,6 @@ import java.util.concurrent.locks.ReentrantLock; | @@ -37,7 +35,6 @@ import java.util.concurrent.locks.ReentrantLock; | ||
37 | import java.util.stream.Collectors; | 35 | import java.util.stream.Collectors; |
38 | import lombok.RequiredArgsConstructor; | 36 | import lombok.RequiredArgsConstructor; |
39 | import lombok.extern.slf4j.Slf4j; | 37 | import lombok.extern.slf4j.Slf4j; |
40 | -import org.apache.zookeeper.Op; | ||
41 | import org.springframework.stereotype.Service; | 38 | import org.springframework.stereotype.Service; |
42 | import org.thingsboard.common.util.JacksonUtil; | 39 | import org.thingsboard.common.util.JacksonUtil; |
43 | import org.thingsboard.server.cache.ota.OtaPackageDataCache; | 40 | import org.thingsboard.server.cache.ota.OtaPackageDataCache; |
@@ -74,13 +71,15 @@ import org.thingsboard.server.common.data.relation.EntityRelation; | @@ -74,13 +71,15 @@ import org.thingsboard.server.common.data.relation.EntityRelation; | ||
74 | import org.thingsboard.server.common.data.security.DeviceCredentials; | 71 | import org.thingsboard.server.common.data.security.DeviceCredentials; |
75 | import org.thingsboard.server.common.data.security.DeviceCredentialsType; | 72 | import org.thingsboard.server.common.data.security.DeviceCredentialsType; |
76 | import org.thingsboard.server.common.data.yunteng.common.media.VideoStreamSessionManager; | 73 | import org.thingsboard.server.common.data.yunteng.common.media.VideoStreamSessionManager; |
74 | +import org.thingsboard.server.common.data.yunteng.config.media.ZLMediaKitServerConfig; | ||
77 | import org.thingsboard.server.common.data.yunteng.constant.FastIotConstants; | 75 | import org.thingsboard.server.common.data.yunteng.constant.FastIotConstants; |
78 | import org.thingsboard.server.common.data.yunteng.dto.DeviceDTO; | 76 | import org.thingsboard.server.common.data.yunteng.dto.DeviceDTO; |
79 | import org.thingsboard.server.common.data.yunteng.dto.TkDeviceScriptDTO; | 77 | import org.thingsboard.server.common.data.yunteng.dto.TkDeviceScriptDTO; |
78 | +import org.thingsboard.server.common.data.yunteng.dto.sip.MediaServerDTO; | ||
80 | import org.thingsboard.server.common.data.yunteng.dto.sip.SipDeviceDTO; | 79 | import org.thingsboard.server.common.data.yunteng.dto.sip.SipDeviceDTO; |
81 | -import org.thingsboard.server.common.data.yunteng.dto.sip.SsrcTransactionDTO; | ||
82 | import org.thingsboard.server.common.data.yunteng.dto.sip.VideoChanelDTO; | 80 | import org.thingsboard.server.common.data.yunteng.dto.sip.VideoChanelDTO; |
83 | import org.thingsboard.server.common.data.yunteng.enums.VideoCmdEnum; | 81 | import org.thingsboard.server.common.data.yunteng.enums.VideoCmdEnum; |
82 | +import org.thingsboard.server.common.data.yunteng.utils.ZLMediaKitRestFulUtils; | ||
84 | import org.thingsboard.server.common.msg.EncryptionUtil; | 83 | import org.thingsboard.server.common.msg.EncryptionUtil; |
85 | import org.thingsboard.server.common.msg.TbMsg; | 84 | import org.thingsboard.server.common.msg.TbMsg; |
86 | import org.thingsboard.server.common.msg.TbMsgDataType; | 85 | import org.thingsboard.server.common.msg.TbMsgDataType; |
@@ -99,6 +98,7 @@ import org.thingsboard.server.dao.yunteng.entities.TkVideoChannelEntity; | @@ -99,6 +98,7 @@ import org.thingsboard.server.dao.yunteng.entities.TkVideoChannelEntity; | ||
99 | import org.thingsboard.server.dao.yunteng.service.TkDeviceScriptService; | 98 | import org.thingsboard.server.dao.yunteng.service.TkDeviceScriptService; |
100 | import org.thingsboard.server.dao.yunteng.service.TkDeviceService; | 99 | import org.thingsboard.server.dao.yunteng.service.TkDeviceService; |
101 | import org.thingsboard.server.dao.yunteng.service.media.TkMediaServerNodeService; | 100 | import org.thingsboard.server.dao.yunteng.service.media.TkMediaServerNodeService; |
101 | +import org.thingsboard.server.dao.yunteng.service.media.TkMediaServerService; | ||
102 | import org.thingsboard.server.dao.yunteng.service.media.TkVideoChannelService; | 102 | import org.thingsboard.server.dao.yunteng.service.media.TkVideoChannelService; |
103 | import org.thingsboard.server.gen.transport.TransportProtos; | 103 | import org.thingsboard.server.gen.transport.TransportProtos; |
104 | import org.thingsboard.server.gen.transport.TransportProtos.DeviceInfoProto; | 104 | import org.thingsboard.server.gen.transport.TransportProtos.DeviceInfoProto; |
@@ -126,650 +126,891 @@ import org.thingsboard.server.service.install.DefaultSystemDataLoaderService; | @@ -126,650 +126,891 @@ import org.thingsboard.server.service.install.DefaultSystemDataLoaderService; | ||
126 | import org.thingsboard.server.service.profile.TbDeviceProfileCache; | 126 | import org.thingsboard.server.service.profile.TbDeviceProfileCache; |
127 | import org.thingsboard.server.service.resource.TbResourceService; | 127 | import org.thingsboard.server.service.resource.TbResourceService; |
128 | 128 | ||
129 | -/** | ||
130 | - * Created by ashvayka on 05.10.18. | ||
131 | - */ | 129 | +/** Created by ashvayka on 05.10.18. */ |
132 | @Slf4j | 130 | @Slf4j |
133 | @Service | 131 | @Service |
134 | @TbCoreComponent | 132 | @TbCoreComponent |
135 | @RequiredArgsConstructor | 133 | @RequiredArgsConstructor |
136 | public class DefaultTransportApiService implements TransportApiService { | 134 | public class DefaultTransportApiService implements TransportApiService { |
137 | 135 | ||
138 | - private static final ObjectMapper mapper = new ObjectMapper(); | ||
139 | - | ||
140 | - private final TbDeviceProfileCache deviceProfileCache; | ||
141 | - private final TbTenantProfileCache tenantProfileCache; | ||
142 | - private final TbApiUsageStateService apiUsageStateService; | ||
143 | - private final DeviceService deviceService; | ||
144 | - private final TkDeviceService ytDeviceService; | ||
145 | - private final TkDeviceScriptService scriptService; | ||
146 | - private final TkVideoChannelService channelService; | ||
147 | - private final TkMediaServerNodeService mediaServerNodeService; | ||
148 | - private final VideoStreamSessionManager videoStreamSessionManager; | ||
149 | - | ||
150 | - private final RelationService relationService; | ||
151 | - private final DeviceCredentialsService deviceCredentialsService; | ||
152 | - private final DbCallbackExecutorService dbCallbackExecutorService; | ||
153 | - private final TbClusterService tbClusterService; | ||
154 | - private final DataDecodingEncodingService dataDecodingEncodingService; | ||
155 | - private final DeviceProvisionService deviceProvisionService; | ||
156 | - private final TbResourceService resourceService; | ||
157 | - private final OtaPackageService otaPackageService; | ||
158 | - private final OtaPackageDataCache otaPackageDataCache; | ||
159 | - | ||
160 | - private final ConcurrentMap<String, ReentrantLock> deviceCreationLocks = new ConcurrentHashMap<>(); | ||
161 | - | ||
162 | - private static boolean checkIsMqttCredentials(DeviceCredentials credentials) { | ||
163 | - return credentials != null && DeviceCredentialsType.MQTT_BASIC.equals(credentials.getCredentialsType()); | 136 | + private static final ObjectMapper mapper = new ObjectMapper(); |
137 | + | ||
138 | + private final TbDeviceProfileCache deviceProfileCache; | ||
139 | + private final TbTenantProfileCache tenantProfileCache; | ||
140 | + private final TbApiUsageStateService apiUsageStateService; | ||
141 | + private final DeviceService deviceService; | ||
142 | + private final TkDeviceService ytDeviceService; | ||
143 | + private final TkDeviceScriptService scriptService; | ||
144 | + private final TkVideoChannelService channelService; | ||
145 | + private final TkMediaServerNodeService mediaServerNodeService; | ||
146 | + private final VideoStreamSessionManager videoStreamSessionManager; | ||
147 | + private final TkMediaServerService mediaServerService; | ||
148 | + private final ZLMediaKitRestFulUtils zlMediaKitRestFulUtils; | ||
149 | + | ||
150 | + private final RelationService relationService; | ||
151 | + private final DeviceCredentialsService deviceCredentialsService; | ||
152 | + private final DbCallbackExecutorService dbCallbackExecutorService; | ||
153 | + private final TbClusterService tbClusterService; | ||
154 | + private final DataDecodingEncodingService dataDecodingEncodingService; | ||
155 | + private final DeviceProvisionService deviceProvisionService; | ||
156 | + private final TbResourceService resourceService; | ||
157 | + private final OtaPackageService otaPackageService; | ||
158 | + private final OtaPackageDataCache otaPackageDataCache; | ||
159 | + | ||
160 | + private final ConcurrentMap<String, ReentrantLock> deviceCreationLocks = | ||
161 | + new ConcurrentHashMap<>(); | ||
162 | + | ||
163 | + private static boolean checkIsMqttCredentials(DeviceCredentials credentials) { | ||
164 | + return credentials != null | ||
165 | + && DeviceCredentialsType.MQTT_BASIC.equals(credentials.getCredentialsType()); | ||
166 | + } | ||
167 | + | ||
168 | + @Override | ||
169 | + public ListenableFuture<TbProtoQueueMsg<TransportApiResponseMsg>> handle( | ||
170 | + TbProtoQueueMsg<TransportApiRequestMsg> tbProtoQueueMsg) { | ||
171 | + TransportApiRequestMsg transportApiRequestMsg = tbProtoQueueMsg.getValue(); | ||
172 | + ListenableFuture<TransportApiResponseMsg> result = null; | ||
173 | + | ||
174 | + if (transportApiRequestMsg.hasValidateTokenRequestMsg()) { | ||
175 | + ValidateDeviceTokenRequestMsg msg = transportApiRequestMsg.getValidateTokenRequestMsg(); | ||
176 | + result = validateCredentials(msg.getToken(), DeviceCredentialsType.ACCESS_TOKEN); | ||
177 | + } else if (transportApiRequestMsg.hasValidateBasicMqttCredRequestMsg()) { | ||
178 | + TransportProtos.ValidateBasicMqttCredRequestMsg msg = | ||
179 | + transportApiRequestMsg.getValidateBasicMqttCredRequestMsg(); | ||
180 | + result = validateCredentials(msg); | ||
181 | + } else if (transportApiRequestMsg.hasValidateX509CertRequestMsg()) { | ||
182 | + ValidateDeviceX509CertRequestMsg msg = transportApiRequestMsg.getValidateX509CertRequestMsg(); | ||
183 | + result = validateCredentials(msg.getHash(), DeviceCredentialsType.X509_CERTIFICATE); | ||
184 | + } else if (transportApiRequestMsg.hasGetOrCreateDeviceRequestMsg()) { | ||
185 | + result = handle(transportApiRequestMsg.getGetOrCreateDeviceRequestMsg()); | ||
186 | + } else if (transportApiRequestMsg.hasEntityProfileRequestMsg()) { | ||
187 | + result = handle(transportApiRequestMsg.getEntityProfileRequestMsg()); | ||
188 | + } else if (transportApiRequestMsg.hasLwM2MRequestMsg()) { | ||
189 | + result = handle(transportApiRequestMsg.getLwM2MRequestMsg()); | ||
190 | + } else if (transportApiRequestMsg.hasValidateDeviceLwM2MCredentialsRequestMsg()) { | ||
191 | + ValidateDeviceLwM2MCredentialsRequestMsg msg = | ||
192 | + transportApiRequestMsg.getValidateDeviceLwM2MCredentialsRequestMsg(); | ||
193 | + result = validateCredentials(msg.getCredentialsId(), DeviceCredentialsType.LWM2M_CREDENTIALS); | ||
194 | + } else if (transportApiRequestMsg.hasProvisionDeviceRequestMsg()) { | ||
195 | + result = handle(transportApiRequestMsg.getProvisionDeviceRequestMsg()); | ||
196 | + } else if (transportApiRequestMsg.hasResourceRequestMsg()) { | ||
197 | + result = handle(transportApiRequestMsg.getResourceRequestMsg()); | ||
198 | + } else if (transportApiRequestMsg.hasSnmpDevicesRequestMsg()) { | ||
199 | + result = handle(transportApiRequestMsg.getSnmpDevicesRequestMsg()); | ||
200 | + } else if (transportApiRequestMsg.hasDeviceRequestMsg()) { | ||
201 | + result = handle(transportApiRequestMsg.getDeviceRequestMsg()); | ||
202 | + } else if (transportApiRequestMsg.hasDeviceCredentialsRequestMsg()) { | ||
203 | + result = handle(transportApiRequestMsg.getDeviceCredentialsRequestMsg()); | ||
204 | + } else if (transportApiRequestMsg.hasOtaPackageRequestMsg()) { | ||
205 | + result = handle(transportApiRequestMsg.getOtaPackageRequestMsg()); | ||
164 | } | 206 | } |
165 | 207 | ||
166 | - @Override | ||
167 | - public ListenableFuture<TbProtoQueueMsg<TransportApiResponseMsg>> handle(TbProtoQueueMsg<TransportApiRequestMsg> tbProtoQueueMsg) { | ||
168 | - TransportApiRequestMsg transportApiRequestMsg = tbProtoQueueMsg.getValue(); | ||
169 | - ListenableFuture<TransportApiResponseMsg> result = null; | ||
170 | - | ||
171 | - if (transportApiRequestMsg.hasValidateTokenRequestMsg()) { | ||
172 | - ValidateDeviceTokenRequestMsg msg = transportApiRequestMsg.getValidateTokenRequestMsg(); | ||
173 | - result = validateCredentials(msg.getToken(), DeviceCredentialsType.ACCESS_TOKEN); | ||
174 | - } else if (transportApiRequestMsg.hasValidateBasicMqttCredRequestMsg()) { | ||
175 | - TransportProtos.ValidateBasicMqttCredRequestMsg msg = transportApiRequestMsg.getValidateBasicMqttCredRequestMsg(); | ||
176 | - result = validateCredentials(msg); | ||
177 | - } else if (transportApiRequestMsg.hasValidateX509CertRequestMsg()) { | ||
178 | - ValidateDeviceX509CertRequestMsg msg = transportApiRequestMsg.getValidateX509CertRequestMsg(); | ||
179 | - result = validateCredentials(msg.getHash(), DeviceCredentialsType.X509_CERTIFICATE); | ||
180 | - } else if (transportApiRequestMsg.hasGetOrCreateDeviceRequestMsg()) { | ||
181 | - result = handle(transportApiRequestMsg.getGetOrCreateDeviceRequestMsg()); | ||
182 | - } else if (transportApiRequestMsg.hasEntityProfileRequestMsg()) { | ||
183 | - result = handle(transportApiRequestMsg.getEntityProfileRequestMsg()); | ||
184 | - } else if (transportApiRequestMsg.hasLwM2MRequestMsg()) { | ||
185 | - result = handle(transportApiRequestMsg.getLwM2MRequestMsg()); | ||
186 | - } else if (transportApiRequestMsg.hasValidateDeviceLwM2MCredentialsRequestMsg()) { | ||
187 | - ValidateDeviceLwM2MCredentialsRequestMsg msg = transportApiRequestMsg.getValidateDeviceLwM2MCredentialsRequestMsg(); | ||
188 | - result = validateCredentials(msg.getCredentialsId(), DeviceCredentialsType.LWM2M_CREDENTIALS); | ||
189 | - } else if (transportApiRequestMsg.hasProvisionDeviceRequestMsg()) { | ||
190 | - result = handle(transportApiRequestMsg.getProvisionDeviceRequestMsg()); | ||
191 | - } else if (transportApiRequestMsg.hasResourceRequestMsg()) { | ||
192 | - result = handle(transportApiRequestMsg.getResourceRequestMsg()); | ||
193 | - } else if (transportApiRequestMsg.hasSnmpDevicesRequestMsg()) { | ||
194 | - result = handle(transportApiRequestMsg.getSnmpDevicesRequestMsg()); | ||
195 | - } else if (transportApiRequestMsg.hasDeviceRequestMsg()) { | ||
196 | - result = handle(transportApiRequestMsg.getDeviceRequestMsg()); | ||
197 | - } else if (transportApiRequestMsg.hasDeviceCredentialsRequestMsg()) { | ||
198 | - result = handle(transportApiRequestMsg.getDeviceCredentialsRequestMsg()); | ||
199 | - } else if (transportApiRequestMsg.hasOtaPackageRequestMsg()) { | ||
200 | - result = handle(transportApiRequestMsg.getOtaPackageRequestMsg()); | ||
201 | - } | ||
202 | - | ||
203 | - //Thingskit function | ||
204 | - else if (transportApiRequestMsg.hasScript()) { | ||
205 | - result = handle(transportApiRequestMsg.getScript()); | ||
206 | - } | ||
207 | - else if (transportApiRequestMsg.hasGbt28181RequestMsg()) { | ||
208 | - result = handleGbt(transportApiRequestMsg.getGbt28181RequestMsg()); | ||
209 | - } | ||
210 | - | ||
211 | - | ||
212 | - return Futures.transform(Optional.ofNullable(result).orElseGet(this::getEmptyTransportApiResponseFuture), | ||
213 | - value -> new TbProtoQueueMsg<>(tbProtoQueueMsg.getKey(), value, tbProtoQueueMsg.getHeaders()), | ||
214 | - MoreExecutors.directExecutor()); | 208 | + // Thingskit function |
209 | + else if (transportApiRequestMsg.hasScript()) { | ||
210 | + result = handle(transportApiRequestMsg.getScript()); | ||
211 | + } else if (transportApiRequestMsg.hasGbt28181RequestMsg()) { | ||
212 | + result = handleGbt(transportApiRequestMsg.getGbt28181RequestMsg()); | ||
213 | + } else if (transportApiRequestMsg.hasGbt28181MediaServerMsg()) { | ||
214 | + result = handleGbtMedia(transportApiRequestMsg.getGbt28181MediaServerMsg()); | ||
215 | } | 215 | } |
216 | 216 | ||
217 | - private ListenableFuture<TransportApiResponseMsg> validateCredentials(String credentialsId, DeviceCredentialsType credentialsType) { | ||
218 | - //TODO: Make async and enable caching | ||
219 | - DeviceCredentials credentials = deviceCredentialsService.findDeviceCredentialsByCredentialsId(credentialsId); | ||
220 | - if (credentials != null && credentials.getCredentialsType() == credentialsType) { | ||
221 | - return getDeviceInfo(credentials); | ||
222 | - } else { | ||
223 | - return getEmptyTransportApiResponseFuture(); | ||
224 | - } | 217 | + return Futures.transform( |
218 | + Optional.ofNullable(result).orElseGet(this::getEmptyTransportApiResponseFuture), | ||
219 | + value -> | ||
220 | + new TbProtoQueueMsg<>(tbProtoQueueMsg.getKey(), value, tbProtoQueueMsg.getHeaders()), | ||
221 | + MoreExecutors.directExecutor()); | ||
222 | + } | ||
223 | + | ||
224 | + private ListenableFuture<TransportApiResponseMsg> validateCredentials( | ||
225 | + String credentialsId, DeviceCredentialsType credentialsType) { | ||
226 | + // TODO: Make async and enable caching | ||
227 | + DeviceCredentials credentials = | ||
228 | + deviceCredentialsService.findDeviceCredentialsByCredentialsId(credentialsId); | ||
229 | + if (credentials != null && credentials.getCredentialsType() == credentialsType) { | ||
230 | + return getDeviceInfo(credentials); | ||
231 | + } else { | ||
232 | + return getEmptyTransportApiResponseFuture(); | ||
225 | } | 233 | } |
226 | - | ||
227 | - private ListenableFuture<TransportApiResponseMsg> validateCredentials(TransportProtos.ValidateBasicMqttCredRequestMsg mqtt) { | ||
228 | - DeviceCredentials credentials; | ||
229 | - if (StringUtils.isEmpty(mqtt.getUserName())) { | ||
230 | - credentials = checkMqttCredentials(mqtt, EncryptionUtil.getSha3Hash(mqtt.getClientId())); | ||
231 | - if (credentials != null) { | ||
232 | - return getDeviceInfo(credentials); | ||
233 | - } else { | ||
234 | - return getEmptyTransportApiResponseFuture(); | ||
235 | - } | 234 | + } |
235 | + | ||
236 | + private ListenableFuture<TransportApiResponseMsg> validateCredentials( | ||
237 | + TransportProtos.ValidateBasicMqttCredRequestMsg mqtt) { | ||
238 | + DeviceCredentials credentials; | ||
239 | + if (StringUtils.isEmpty(mqtt.getUserName())) { | ||
240 | + credentials = checkMqttCredentials(mqtt, EncryptionUtil.getSha3Hash(mqtt.getClientId())); | ||
241 | + if (credentials != null) { | ||
242 | + return getDeviceInfo(credentials); | ||
243 | + } else { | ||
244 | + return getEmptyTransportApiResponseFuture(); | ||
245 | + } | ||
246 | + } else { | ||
247 | + credentials = | ||
248 | + deviceCredentialsService.findDeviceCredentialsByCredentialsId( | ||
249 | + EncryptionUtil.getSha3Hash("|", mqtt.getClientId(), mqtt.getUserName())); | ||
250 | + if (checkIsMqttCredentials(credentials)) { | ||
251 | + var validationResult = validateMqttCredentials(mqtt, credentials); | ||
252 | + if (VALID.equals(validationResult)) { | ||
253 | + return getDeviceInfo(credentials); | ||
254 | + } else if (PASSWORD_MISMATCH.equals(validationResult)) { | ||
255 | + return getEmptyTransportApiResponseFuture(); | ||
236 | } else { | 256 | } else { |
237 | - credentials = deviceCredentialsService.findDeviceCredentialsByCredentialsId( | ||
238 | - EncryptionUtil.getSha3Hash("|", mqtt.getClientId(), mqtt.getUserName())); | ||
239 | - if (checkIsMqttCredentials(credentials)) { | ||
240 | - var validationResult = validateMqttCredentials(mqtt, credentials); | ||
241 | - if (VALID.equals(validationResult)) { | ||
242 | - return getDeviceInfo(credentials); | ||
243 | - } else if (PASSWORD_MISMATCH.equals(validationResult)) { | ||
244 | - return getEmptyTransportApiResponseFuture(); | ||
245 | - } else { | ||
246 | - return validateUserNameCredentials(mqtt); | ||
247 | - } | ||
248 | - } else { | ||
249 | - return validateUserNameCredentials(mqtt); | ||
250 | - } | 257 | + return validateUserNameCredentials(mqtt); |
251 | } | 258 | } |
259 | + } else { | ||
260 | + return validateUserNameCredentials(mqtt); | ||
261 | + } | ||
252 | } | 262 | } |
253 | - | ||
254 | - private ListenableFuture<TransportApiResponseMsg> validateUserNameCredentials(TransportProtos.ValidateBasicMqttCredRequestMsg mqtt) { | ||
255 | - DeviceCredentials credentials = deviceCredentialsService.findDeviceCredentialsByCredentialsId(mqtt.getUserName()); | ||
256 | - if (credentials != null) { | ||
257 | - switch (credentials.getCredentialsType()) { | ||
258 | - case ACCESS_TOKEN: | ||
259 | - return getDeviceInfo(credentials); | ||
260 | - case MQTT_BASIC: | ||
261 | - if (VALID.equals(validateMqttCredentials(mqtt, credentials))) { | ||
262 | - return getDeviceInfo(credentials); | ||
263 | - } else { | ||
264 | - return getEmptyTransportApiResponseFuture(); | ||
265 | - } | ||
266 | - } | ||
267 | - } | ||
268 | - return getEmptyTransportApiResponseFuture(); | 263 | + } |
264 | + | ||
265 | + private ListenableFuture<TransportApiResponseMsg> validateUserNameCredentials( | ||
266 | + TransportProtos.ValidateBasicMqttCredRequestMsg mqtt) { | ||
267 | + DeviceCredentials credentials = | ||
268 | + deviceCredentialsService.findDeviceCredentialsByCredentialsId(mqtt.getUserName()); | ||
269 | + if (credentials != null) { | ||
270 | + switch (credentials.getCredentialsType()) { | ||
271 | + case ACCESS_TOKEN: | ||
272 | + return getDeviceInfo(credentials); | ||
273 | + case MQTT_BASIC: | ||
274 | + if (VALID.equals(validateMqttCredentials(mqtt, credentials))) { | ||
275 | + return getDeviceInfo(credentials); | ||
276 | + } else { | ||
277 | + return getEmptyTransportApiResponseFuture(); | ||
278 | + } | ||
279 | + } | ||
269 | } | 280 | } |
270 | - | ||
271 | - private DeviceCredentials checkMqttCredentials(TransportProtos.ValidateBasicMqttCredRequestMsg clientCred, String credId) { | ||
272 | - return checkMqttCredentials(clientCred, deviceCredentialsService.findDeviceCredentialsByCredentialsId(credId)); | 281 | + return getEmptyTransportApiResponseFuture(); |
282 | + } | ||
283 | + | ||
284 | + private DeviceCredentials checkMqttCredentials( | ||
285 | + TransportProtos.ValidateBasicMqttCredRequestMsg clientCred, String credId) { | ||
286 | + return checkMqttCredentials( | ||
287 | + clientCred, deviceCredentialsService.findDeviceCredentialsByCredentialsId(credId)); | ||
288 | + } | ||
289 | + | ||
290 | + private DeviceCredentials checkMqttCredentials( | ||
291 | + TransportProtos.ValidateBasicMqttCredRequestMsg clientCred, | ||
292 | + DeviceCredentials deviceCredentials) { | ||
293 | + if (deviceCredentials != null | ||
294 | + && deviceCredentials.getCredentialsType() == DeviceCredentialsType.MQTT_BASIC) { | ||
295 | + if (VALID.equals(validateMqttCredentials(clientCred, deviceCredentials))) { | ||
296 | + return deviceCredentials; | ||
297 | + } | ||
273 | } | 298 | } |
274 | - | ||
275 | - private DeviceCredentials checkMqttCredentials(TransportProtos.ValidateBasicMqttCredRequestMsg clientCred, DeviceCredentials deviceCredentials) { | ||
276 | - if (deviceCredentials != null && deviceCredentials.getCredentialsType() == DeviceCredentialsType.MQTT_BASIC) { | ||
277 | - if (VALID.equals(validateMqttCredentials(clientCred, deviceCredentials))) { | ||
278 | - return deviceCredentials; | ||
279 | - } | ||
280 | - } | ||
281 | - return null; | 299 | + return null; |
300 | + } | ||
301 | + | ||
302 | + private BasicCredentialsValidationResult validateMqttCredentials( | ||
303 | + TransportProtos.ValidateBasicMqttCredRequestMsg clientCred, | ||
304 | + DeviceCredentials deviceCredentials) { | ||
305 | + BasicMqttCredentials dbCred = | ||
306 | + JacksonUtil.fromString(deviceCredentials.getCredentialsValue(), BasicMqttCredentials.class); | ||
307 | + if (!StringUtils.isEmpty(dbCred.getClientId()) | ||
308 | + && !dbCred.getClientId().equals(clientCred.getClientId())) { | ||
309 | + return BasicCredentialsValidationResult.HASH_MISMATCH; | ||
282 | } | 310 | } |
283 | - | ||
284 | - private BasicCredentialsValidationResult validateMqttCredentials(TransportProtos.ValidateBasicMqttCredRequestMsg clientCred, DeviceCredentials deviceCredentials) { | ||
285 | - BasicMqttCredentials dbCred = JacksonUtil.fromString(deviceCredentials.getCredentialsValue(), BasicMqttCredentials.class); | ||
286 | - if (!StringUtils.isEmpty(dbCred.getClientId()) && !dbCred.getClientId().equals(clientCred.getClientId())) { | ||
287 | - return BasicCredentialsValidationResult.HASH_MISMATCH; | ||
288 | - } | ||
289 | - if (!StringUtils.isEmpty(dbCred.getUserName()) && !dbCred.getUserName().equals(clientCred.getUserName())) { | ||
290 | - return BasicCredentialsValidationResult.HASH_MISMATCH; | ||
291 | - } | ||
292 | - if (!StringUtils.isEmpty(dbCred.getPassword())) { | ||
293 | - if (StringUtils.isEmpty(clientCred.getPassword())) { | ||
294 | - return BasicCredentialsValidationResult.PASSWORD_MISMATCH; | ||
295 | - } else { | ||
296 | - return dbCred.getPassword().equals(clientCred.getPassword()) ? VALID : BasicCredentialsValidationResult.PASSWORD_MISMATCH; | ||
297 | - } | ||
298 | - } | ||
299 | - return VALID; | 311 | + if (!StringUtils.isEmpty(dbCred.getUserName()) |
312 | + && !dbCred.getUserName().equals(clientCred.getUserName())) { | ||
313 | + return BasicCredentialsValidationResult.HASH_MISMATCH; | ||
300 | } | 314 | } |
301 | - | ||
302 | - private ListenableFuture<TransportApiResponseMsg> handle(GetOrCreateDeviceFromGatewayRequestMsg requestMsg) { | ||
303 | - DeviceId gatewayId = new DeviceId(new UUID(requestMsg.getGatewayIdMSB(), requestMsg.getGatewayIdLSB())); | ||
304 | - ListenableFuture<Device> gatewayFuture = deviceService.findDeviceByIdAsync(TenantId.SYS_TENANT_ID, gatewayId); | ||
305 | - return Futures.transform(gatewayFuture, gateway -> { | ||
306 | - Lock deviceCreationLock = deviceCreationLocks.computeIfAbsent(requestMsg.getDeviceName(), id -> new ReentrantLock()); | ||
307 | - deviceCreationLock.lock(); | ||
308 | - try { | ||
309 | - | ||
310 | - //Thingskit function | ||
311 | - String slaveName = requestMsg.getDeviceName(); | ||
312 | - if(gateway.getDeviceData().getTransportConfiguration().getType() == DeviceTransportType.TCP) { | ||
313 | - DeviceDTO iotDev = ytDeviceService.findSlaveDevice(gateway.getTenantId().getId().toString() | ||
314 | - , gateway.getId().getId().toString() | ||
315 | - ,slaveName); | ||
316 | - if(iotDev == null ){ | ||
317 | - GetOrCreateDeviceFromGatewayResponseMsg.Builder builder = GetOrCreateDeviceFromGatewayResponseMsg.newBuilder(); | ||
318 | - return TransportApiResponseMsg.newBuilder() | ||
319 | - .setGetOrCreateDeviceResponseMsg(builder.build()) | ||
320 | - .build(); | ||
321 | - } | ||
322 | - slaveName = iotDev.getName(); | ||
323 | - } | ||
324 | - | ||
325 | - Device device = deviceService.findDeviceByTenantIdAndName(gateway.getTenantId(), slaveName); | ||
326 | - | ||
327 | - if (device == null) { | ||
328 | - TenantId tenantId = gateway.getTenantId(); | ||
329 | - device = new Device(); | ||
330 | - device.setTenantId(tenantId); | ||
331 | - device.setName(requestMsg.getDeviceName()); | ||
332 | - device.setType(requestMsg.getDeviceType()); | ||
333 | - device.setCustomerId(gateway.getCustomerId()); | ||
334 | - DeviceProfile deviceProfile = deviceProfileCache.findOrCreateDeviceProfile(gateway.getTenantId(), DefaultSystemDataLoaderService.DEFAULT_DEVICE_TYPE); | ||
335 | - device.setDeviceProfileId(deviceProfile.getId()); | ||
336 | - ObjectNode additionalInfo = JacksonUtil.newObjectNode(); | ||
337 | - additionalInfo.put(DataConstants.LAST_CONNECTED_GATEWAY, gatewayId.toString()); | ||
338 | - device.setAdditionalInfo(additionalInfo); | ||
339 | - Device savedDevice = deviceService.saveDevice(device); | ||
340 | - | ||
341 | - | ||
342 | - //Thingskit function | ||
343 | - ytDeviceService.saveSlaveDevice(savedDevice.getId().getId().toString(), savedDevice.getName(),deviceProfile.getId().getId().toString(), gateway.getId().getId().toString(),gateway.getCreatedTime()); | ||
344 | - | ||
345 | - | ||
346 | - tbClusterService.onDeviceUpdated(savedDevice, null); | ||
347 | - device = savedDevice; | ||
348 | - | ||
349 | - relationService.saveRelationAsync(TenantId.SYS_TENANT_ID, new EntityRelation(gateway.getId(), device.getId(), "Created")); | ||
350 | - | ||
351 | - TbMsgMetaData metaData = new TbMsgMetaData(); | ||
352 | - CustomerId customerId = gateway.getCustomerId(); | ||
353 | - if (customerId != null && !customerId.isNullUid()) { | ||
354 | - metaData.putValue("customerId", customerId.toString()); | ||
355 | - } | ||
356 | - metaData.putValue("gatewayId", gatewayId.toString()); | ||
357 | - | ||
358 | - DeviceId deviceId = device.getId(); | ||
359 | - ObjectNode entityNode = mapper.valueToTree(device); | ||
360 | - TbMsg tbMsg = TbMsg.newMsg(DataConstants.ENTITY_CREATED, deviceId, customerId, metaData, TbMsgDataType.JSON, mapper.writeValueAsString(entityNode)); | ||
361 | - tbClusterService.pushMsgToRuleEngine(tenantId, deviceId, tbMsg, null); | ||
362 | - } else { | ||
363 | - JsonNode deviceAdditionalInfo = device.getAdditionalInfo(); | ||
364 | - if (deviceAdditionalInfo == null) { | ||
365 | - deviceAdditionalInfo = JacksonUtil.newObjectNode(); | ||
366 | - } | ||
367 | - if (deviceAdditionalInfo.isObject() && | ||
368 | - (!deviceAdditionalInfo.has(DataConstants.LAST_CONNECTED_GATEWAY) | ||
369 | - || !gatewayId.toString().equals(deviceAdditionalInfo.get(DataConstants.LAST_CONNECTED_GATEWAY).asText()))) { | ||
370 | - ObjectNode newDeviceAdditionalInfo = (ObjectNode) deviceAdditionalInfo; | ||
371 | - newDeviceAdditionalInfo.put(DataConstants.LAST_CONNECTED_GATEWAY, gatewayId.toString()); | ||
372 | - Device savedDevice = deviceService.saveDevice(device); | ||
373 | - tbClusterService.onDeviceUpdated(savedDevice, device); | ||
374 | - } | ||
375 | - } | ||
376 | - GetOrCreateDeviceFromGatewayResponseMsg.Builder builder = GetOrCreateDeviceFromGatewayResponseMsg.newBuilder() | ||
377 | - .setDeviceInfo(getDeviceInfoProto(device)); | ||
378 | - DeviceProfile deviceProfile = deviceProfileCache.get(device.getTenantId(), device.getDeviceProfileId()); | ||
379 | - if (deviceProfile != null) { | ||
380 | - builder.setProfileBody(ByteString.copyFrom(dataDecodingEncodingService.encode(deviceProfile))); | ||
381 | - } else { | ||
382 | - log.warn("[{}] Failed to find device profile [{}] for device. ", device.getId(), device.getDeviceProfileId()); | ||
383 | - } | 315 | + if (!StringUtils.isEmpty(dbCred.getPassword())) { |
316 | + if (StringUtils.isEmpty(clientCred.getPassword())) { | ||
317 | + return BasicCredentialsValidationResult.PASSWORD_MISMATCH; | ||
318 | + } else { | ||
319 | + return dbCred.getPassword().equals(clientCred.getPassword()) | ||
320 | + ? VALID | ||
321 | + : BasicCredentialsValidationResult.PASSWORD_MISMATCH; | ||
322 | + } | ||
323 | + } | ||
324 | + return VALID; | ||
325 | + } | ||
326 | + | ||
327 | + private ListenableFuture<TransportApiResponseMsg> handle( | ||
328 | + GetOrCreateDeviceFromGatewayRequestMsg requestMsg) { | ||
329 | + DeviceId gatewayId = | ||
330 | + new DeviceId(new UUID(requestMsg.getGatewayIdMSB(), requestMsg.getGatewayIdLSB())); | ||
331 | + ListenableFuture<Device> gatewayFuture = | ||
332 | + deviceService.findDeviceByIdAsync(TenantId.SYS_TENANT_ID, gatewayId); | ||
333 | + return Futures.transform( | ||
334 | + gatewayFuture, | ||
335 | + gateway -> { | ||
336 | + Lock deviceCreationLock = | ||
337 | + deviceCreationLocks.computeIfAbsent( | ||
338 | + requestMsg.getDeviceName(), id -> new ReentrantLock()); | ||
339 | + deviceCreationLock.lock(); | ||
340 | + try { | ||
341 | + | ||
342 | + // Thingskit function | ||
343 | + String slaveName = requestMsg.getDeviceName(); | ||
344 | + if (gateway.getDeviceData().getTransportConfiguration().getType() | ||
345 | + == DeviceTransportType.TCP) { | ||
346 | + DeviceDTO iotDev = | ||
347 | + ytDeviceService.findSlaveDevice( | ||
348 | + gateway.getTenantId().getId().toString(), | ||
349 | + gateway.getId().getId().toString(), | ||
350 | + slaveName); | ||
351 | + if (iotDev == null) { | ||
352 | + GetOrCreateDeviceFromGatewayResponseMsg.Builder builder = | ||
353 | + GetOrCreateDeviceFromGatewayResponseMsg.newBuilder(); | ||
384 | return TransportApiResponseMsg.newBuilder() | 354 | return TransportApiResponseMsg.newBuilder() |
385 | - .setGetOrCreateDeviceResponseMsg(builder.build()) | ||
386 | - .build(); | ||
387 | - } catch (JsonProcessingException e) { | ||
388 | - log.warn("[{}] Failed to lookup device by gateway id and name: [{}]", gatewayId, requestMsg.getDeviceName(), e); | ||
389 | - throw new RuntimeException(e); | ||
390 | - } finally { | ||
391 | - deviceCreationLock.unlock(); | 355 | + .setGetOrCreateDeviceResponseMsg(builder.build()) |
356 | + .build(); | ||
357 | + } | ||
358 | + slaveName = iotDev.getName(); | ||
392 | } | 359 | } |
393 | - }, dbCallbackExecutorService); | ||
394 | - } | ||
395 | 360 | ||
396 | - private ListenableFuture<TransportApiResponseMsg> handle(ProvisionDeviceRequestMsg requestMsg) { | ||
397 | - ListenableFuture<ProvisionResponse> provisionResponseFuture = null; | ||
398 | - try { | ||
399 | - provisionResponseFuture = Futures.immediateFuture(deviceProvisionService.provisionDevice( | ||
400 | - new ProvisionRequest( | ||
401 | - requestMsg.getDeviceName(), | ||
402 | - requestMsg.getCredentialsType() != null ? DeviceCredentialsType.valueOf(requestMsg.getCredentialsType().name()) : null, | ||
403 | - new ProvisionDeviceCredentialsData(requestMsg.getCredentialsDataProto().getValidateDeviceTokenRequestMsg().getToken(), | ||
404 | - requestMsg.getCredentialsDataProto().getValidateBasicMqttCredRequestMsg().getClientId(), | ||
405 | - requestMsg.getCredentialsDataProto().getValidateBasicMqttCredRequestMsg().getUserName(), | ||
406 | - requestMsg.getCredentialsDataProto().getValidateBasicMqttCredRequestMsg().getPassword(), | ||
407 | - requestMsg.getCredentialsDataProto().getValidateDeviceX509CertRequestMsg().getHash()), | ||
408 | - new ProvisionDeviceProfileCredentials( | ||
409 | - requestMsg.getProvisionDeviceCredentialsMsg().getProvisionDeviceKey(), | ||
410 | - requestMsg.getProvisionDeviceCredentialsMsg().getProvisionDeviceSecret())))); | ||
411 | - } catch (ProvisionFailedException e) { | ||
412 | - return Futures.immediateFuture(getTransportApiResponseMsg( | ||
413 | - new DeviceCredentials(), | ||
414 | - TransportProtos.ResponseStatus.valueOf(e.getMessage()))); | ||
415 | - } | ||
416 | - return Futures.transform(provisionResponseFuture, provisionResponse -> getTransportApiResponseMsg(provisionResponse.getDeviceCredentials(), TransportProtos.ResponseStatus.SUCCESS), | ||
417 | - dbCallbackExecutorService); | ||
418 | - } | 361 | + Device device = |
362 | + deviceService.findDeviceByTenantIdAndName(gateway.getTenantId(), slaveName); | ||
419 | 363 | ||
420 | - private TransportApiResponseMsg getTransportApiResponseMsg(DeviceCredentials | ||
421 | - deviceCredentials, TransportProtos.ResponseStatus status) { | ||
422 | - if (!status.equals(TransportProtos.ResponseStatus.SUCCESS)) { | ||
423 | - return TransportApiResponseMsg.newBuilder().setProvisionDeviceResponseMsg(TransportProtos.ProvisionDeviceResponseMsg.newBuilder().setStatus(status).build()).build(); | ||
424 | - } | ||
425 | - TransportProtos.ProvisionDeviceResponseMsg.Builder provisionResponse = TransportProtos.ProvisionDeviceResponseMsg.newBuilder() | ||
426 | - .setCredentialsType(TransportProtos.CredentialsType.valueOf(deviceCredentials.getCredentialsType().name())) | ||
427 | - .setStatus(status); | ||
428 | - switch (deviceCredentials.getCredentialsType()) { | ||
429 | - case ACCESS_TOKEN: | ||
430 | - provisionResponse.setCredentialsValue(deviceCredentials.getCredentialsId()); | ||
431 | - break; | ||
432 | - case MQTT_BASIC: | ||
433 | - case X509_CERTIFICATE: | ||
434 | - case LWM2M_CREDENTIALS: | ||
435 | - provisionResponse.setCredentialsValue(deviceCredentials.getCredentialsValue()); | ||
436 | - break; | ||
437 | - } | ||
438 | - | ||
439 | - return TransportApiResponseMsg.newBuilder() | ||
440 | - .setProvisionDeviceResponseMsg(provisionResponse.build()) | 364 | + if (device == null) { |
365 | + TenantId tenantId = gateway.getTenantId(); | ||
366 | + device = new Device(); | ||
367 | + device.setTenantId(tenantId); | ||
368 | + device.setName(requestMsg.getDeviceName()); | ||
369 | + device.setType(requestMsg.getDeviceType()); | ||
370 | + device.setCustomerId(gateway.getCustomerId()); | ||
371 | + DeviceProfile deviceProfile = | ||
372 | + deviceProfileCache.findOrCreateDeviceProfile( | ||
373 | + gateway.getTenantId(), DefaultSystemDataLoaderService.DEFAULT_DEVICE_TYPE); | ||
374 | + device.setDeviceProfileId(deviceProfile.getId()); | ||
375 | + ObjectNode additionalInfo = JacksonUtil.newObjectNode(); | ||
376 | + additionalInfo.put(DataConstants.LAST_CONNECTED_GATEWAY, gatewayId.toString()); | ||
377 | + device.setAdditionalInfo(additionalInfo); | ||
378 | + Device savedDevice = deviceService.saveDevice(device); | ||
379 | + | ||
380 | + // Thingskit function | ||
381 | + ytDeviceService.saveSlaveDevice( | ||
382 | + savedDevice.getId().getId().toString(), | ||
383 | + savedDevice.getName(), | ||
384 | + deviceProfile.getId().getId().toString(), | ||
385 | + gateway.getId().getId().toString(), | ||
386 | + gateway.getCreatedTime()); | ||
387 | + | ||
388 | + tbClusterService.onDeviceUpdated(savedDevice, null); | ||
389 | + device = savedDevice; | ||
390 | + | ||
391 | + relationService.saveRelationAsync( | ||
392 | + TenantId.SYS_TENANT_ID, | ||
393 | + new EntityRelation(gateway.getId(), device.getId(), "Created")); | ||
394 | + | ||
395 | + TbMsgMetaData metaData = new TbMsgMetaData(); | ||
396 | + CustomerId customerId = gateway.getCustomerId(); | ||
397 | + if (customerId != null && !customerId.isNullUid()) { | ||
398 | + metaData.putValue("customerId", customerId.toString()); | ||
399 | + } | ||
400 | + metaData.putValue("gatewayId", gatewayId.toString()); | ||
401 | + | ||
402 | + DeviceId deviceId = device.getId(); | ||
403 | + ObjectNode entityNode = mapper.valueToTree(device); | ||
404 | + TbMsg tbMsg = | ||
405 | + TbMsg.newMsg( | ||
406 | + DataConstants.ENTITY_CREATED, | ||
407 | + deviceId, | ||
408 | + customerId, | ||
409 | + metaData, | ||
410 | + TbMsgDataType.JSON, | ||
411 | + mapper.writeValueAsString(entityNode)); | ||
412 | + tbClusterService.pushMsgToRuleEngine(tenantId, deviceId, tbMsg, null); | ||
413 | + } else { | ||
414 | + JsonNode deviceAdditionalInfo = device.getAdditionalInfo(); | ||
415 | + if (deviceAdditionalInfo == null) { | ||
416 | + deviceAdditionalInfo = JacksonUtil.newObjectNode(); | ||
417 | + } | ||
418 | + if (deviceAdditionalInfo.isObject() | ||
419 | + && (!deviceAdditionalInfo.has(DataConstants.LAST_CONNECTED_GATEWAY) | ||
420 | + || !gatewayId | ||
421 | + .toString() | ||
422 | + .equals( | ||
423 | + deviceAdditionalInfo | ||
424 | + .get(DataConstants.LAST_CONNECTED_GATEWAY) | ||
425 | + .asText()))) { | ||
426 | + ObjectNode newDeviceAdditionalInfo = (ObjectNode) deviceAdditionalInfo; | ||
427 | + newDeviceAdditionalInfo.put( | ||
428 | + DataConstants.LAST_CONNECTED_GATEWAY, gatewayId.toString()); | ||
429 | + Device savedDevice = deviceService.saveDevice(device); | ||
430 | + tbClusterService.onDeviceUpdated(savedDevice, device); | ||
431 | + } | ||
432 | + } | ||
433 | + GetOrCreateDeviceFromGatewayResponseMsg.Builder builder = | ||
434 | + GetOrCreateDeviceFromGatewayResponseMsg.newBuilder() | ||
435 | + .setDeviceInfo(getDeviceInfoProto(device)); | ||
436 | + DeviceProfile deviceProfile = | ||
437 | + deviceProfileCache.get(device.getTenantId(), device.getDeviceProfileId()); | ||
438 | + if (deviceProfile != null) { | ||
439 | + builder.setProfileBody( | ||
440 | + ByteString.copyFrom(dataDecodingEncodingService.encode(deviceProfile))); | ||
441 | + } else { | ||
442 | + log.warn( | ||
443 | + "[{}] Failed to find device profile [{}] for device. ", | ||
444 | + device.getId(), | ||
445 | + device.getDeviceProfileId()); | ||
446 | + } | ||
447 | + return TransportApiResponseMsg.newBuilder() | ||
448 | + .setGetOrCreateDeviceResponseMsg(builder.build()) | ||
441 | .build(); | 449 | .build(); |
450 | + } catch (JsonProcessingException e) { | ||
451 | + log.warn( | ||
452 | + "[{}] Failed to lookup device by gateway id and name: [{}]", | ||
453 | + gatewayId, | ||
454 | + requestMsg.getDeviceName(), | ||
455 | + e); | ||
456 | + throw new RuntimeException(e); | ||
457 | + } finally { | ||
458 | + deviceCreationLock.unlock(); | ||
459 | + } | ||
460 | + }, | ||
461 | + dbCallbackExecutorService); | ||
462 | + } | ||
463 | + | ||
464 | + private ListenableFuture<TransportApiResponseMsg> handle(ProvisionDeviceRequestMsg requestMsg) { | ||
465 | + ListenableFuture<ProvisionResponse> provisionResponseFuture = null; | ||
466 | + try { | ||
467 | + provisionResponseFuture = | ||
468 | + Futures.immediateFuture( | ||
469 | + deviceProvisionService.provisionDevice( | ||
470 | + new ProvisionRequest( | ||
471 | + requestMsg.getDeviceName(), | ||
472 | + requestMsg.getCredentialsType() != null | ||
473 | + ? DeviceCredentialsType.valueOf(requestMsg.getCredentialsType().name()) | ||
474 | + : null, | ||
475 | + new ProvisionDeviceCredentialsData( | ||
476 | + requestMsg | ||
477 | + .getCredentialsDataProto() | ||
478 | + .getValidateDeviceTokenRequestMsg() | ||
479 | + .getToken(), | ||
480 | + requestMsg | ||
481 | + .getCredentialsDataProto() | ||
482 | + .getValidateBasicMqttCredRequestMsg() | ||
483 | + .getClientId(), | ||
484 | + requestMsg | ||
485 | + .getCredentialsDataProto() | ||
486 | + .getValidateBasicMqttCredRequestMsg() | ||
487 | + .getUserName(), | ||
488 | + requestMsg | ||
489 | + .getCredentialsDataProto() | ||
490 | + .getValidateBasicMqttCredRequestMsg() | ||
491 | + .getPassword(), | ||
492 | + requestMsg | ||
493 | + .getCredentialsDataProto() | ||
494 | + .getValidateDeviceX509CertRequestMsg() | ||
495 | + .getHash()), | ||
496 | + new ProvisionDeviceProfileCredentials( | ||
497 | + requestMsg.getProvisionDeviceCredentialsMsg().getProvisionDeviceKey(), | ||
498 | + requestMsg | ||
499 | + .getProvisionDeviceCredentialsMsg() | ||
500 | + .getProvisionDeviceSecret())))); | ||
501 | + } catch (ProvisionFailedException e) { | ||
502 | + return Futures.immediateFuture( | ||
503 | + getTransportApiResponseMsg( | ||
504 | + new DeviceCredentials(), TransportProtos.ResponseStatus.valueOf(e.getMessage()))); | ||
442 | } | 505 | } |
443 | - | ||
444 | - private ListenableFuture<TransportApiResponseMsg> handle(GetEntityProfileRequestMsg requestMsg) { | ||
445 | - EntityType entityType = EntityType.valueOf(requestMsg.getEntityType()); | ||
446 | - UUID entityUuid = new UUID(requestMsg.getEntityIdMSB(), requestMsg.getEntityIdLSB()); | ||
447 | - GetEntityProfileResponseMsg.Builder builder = GetEntityProfileResponseMsg.newBuilder(); | ||
448 | - if (entityType.equals(EntityType.DEVICE_PROFILE)) { | ||
449 | - DeviceProfileId deviceProfileId = new DeviceProfileId(entityUuid); | ||
450 | - DeviceProfile deviceProfile = deviceProfileCache.find(deviceProfileId); | ||
451 | - builder.setData(ByteString.copyFrom(dataDecodingEncodingService.encode(deviceProfile))); | ||
452 | - } else if (entityType.equals(EntityType.TENANT)) { | ||
453 | - TenantId tenantId = TenantId.fromUUID(entityUuid); | ||
454 | - TenantProfile tenantProfile = tenantProfileCache.get(tenantId); | ||
455 | - ApiUsageState state = apiUsageStateService.getApiUsageState(tenantId); | ||
456 | - builder.setData(ByteString.copyFrom(dataDecodingEncodingService.encode(tenantProfile))); | ||
457 | - builder.setApiState(ByteString.copyFrom(dataDecodingEncodingService.encode(state))); | ||
458 | - } else { | ||
459 | - throw new RuntimeException("Invalid entity profile request: " + entityType); | ||
460 | - } | ||
461 | - return Futures.immediateFuture(TransportApiResponseMsg.newBuilder().setEntityProfileResponseMsg(builder).build()); | 506 | + return Futures.transform( |
507 | + provisionResponseFuture, | ||
508 | + provisionResponse -> | ||
509 | + getTransportApiResponseMsg( | ||
510 | + provisionResponse.getDeviceCredentials(), TransportProtos.ResponseStatus.SUCCESS), | ||
511 | + dbCallbackExecutorService); | ||
512 | + } | ||
513 | + | ||
514 | + private TransportApiResponseMsg getTransportApiResponseMsg( | ||
515 | + DeviceCredentials deviceCredentials, TransportProtos.ResponseStatus status) { | ||
516 | + if (!status.equals(TransportProtos.ResponseStatus.SUCCESS)) { | ||
517 | + return TransportApiResponseMsg.newBuilder() | ||
518 | + .setProvisionDeviceResponseMsg( | ||
519 | + TransportProtos.ProvisionDeviceResponseMsg.newBuilder().setStatus(status).build()) | ||
520 | + .build(); | ||
462 | } | 521 | } |
463 | - | ||
464 | - private ListenableFuture<TransportApiResponseMsg> handle(GetDeviceRequestMsg requestMsg) { | ||
465 | - DeviceId deviceId = new DeviceId(new UUID(requestMsg.getDeviceIdMSB(), requestMsg.getDeviceIdLSB())); | ||
466 | - Device device = deviceService.findDeviceById(TenantId.SYS_TENANT_ID, deviceId); | ||
467 | - | ||
468 | - TransportApiResponseMsg responseMsg; | ||
469 | - if (device != null) { | ||
470 | - UUID deviceProfileId = device.getDeviceProfileId().getId(); | ||
471 | - responseMsg = TransportApiResponseMsg.newBuilder() | ||
472 | - .setDeviceResponseMsg(TransportProtos.GetDeviceResponseMsg.newBuilder() | ||
473 | - .setDeviceProfileIdMSB(deviceProfileId.getMostSignificantBits()) | ||
474 | - .setDeviceProfileIdLSB(deviceProfileId.getLeastSignificantBits()) | ||
475 | - .setDeviceTransportConfiguration(ByteString.copyFrom( | ||
476 | - dataDecodingEncodingService.encode(device.getDeviceData().getTransportConfiguration()) | ||
477 | - ))) | ||
478 | - .build(); | ||
479 | - } else { | ||
480 | - responseMsg = TransportApiResponseMsg.getDefaultInstance(); | ||
481 | - } | ||
482 | - | ||
483 | - return Futures.immediateFuture(responseMsg); | 522 | + TransportProtos.ProvisionDeviceResponseMsg.Builder provisionResponse = |
523 | + TransportProtos.ProvisionDeviceResponseMsg.newBuilder() | ||
524 | + .setCredentialsType( | ||
525 | + TransportProtos.CredentialsType.valueOf( | ||
526 | + deviceCredentials.getCredentialsType().name())) | ||
527 | + .setStatus(status); | ||
528 | + switch (deviceCredentials.getCredentialsType()) { | ||
529 | + case ACCESS_TOKEN: | ||
530 | + provisionResponse.setCredentialsValue(deviceCredentials.getCredentialsId()); | ||
531 | + break; | ||
532 | + case MQTT_BASIC: | ||
533 | + case X509_CERTIFICATE: | ||
534 | + case LWM2M_CREDENTIALS: | ||
535 | + provisionResponse.setCredentialsValue(deviceCredentials.getCredentialsValue()); | ||
536 | + break; | ||
484 | } | 537 | } |
485 | 538 | ||
486 | - private ListenableFuture<TransportApiResponseMsg> handle(GetDeviceCredentialsRequestMsg requestMsg) { | ||
487 | - DeviceId deviceId = new DeviceId(new UUID(requestMsg.getDeviceIdMSB(), requestMsg.getDeviceIdLSB())); | ||
488 | - DeviceCredentials deviceCredentials = deviceCredentialsService.findDeviceCredentialsByDeviceId(TenantId.SYS_TENANT_ID, deviceId); | ||
489 | - | ||
490 | - return Futures.immediateFuture(TransportApiResponseMsg.newBuilder() | ||
491 | - .setDeviceCredentialsResponseMsg(TransportProtos.GetDeviceCredentialsResponseMsg.newBuilder() | ||
492 | - .setDeviceCredentialsData(ByteString.copyFrom(dataDecodingEncodingService.encode(deviceCredentials)))) | ||
493 | - .build()); | 539 | + return TransportApiResponseMsg.newBuilder() |
540 | + .setProvisionDeviceResponseMsg(provisionResponse.build()) | ||
541 | + .build(); | ||
542 | + } | ||
543 | + | ||
544 | + private ListenableFuture<TransportApiResponseMsg> handle(GetEntityProfileRequestMsg requestMsg) { | ||
545 | + EntityType entityType = EntityType.valueOf(requestMsg.getEntityType()); | ||
546 | + UUID entityUuid = new UUID(requestMsg.getEntityIdMSB(), requestMsg.getEntityIdLSB()); | ||
547 | + GetEntityProfileResponseMsg.Builder builder = GetEntityProfileResponseMsg.newBuilder(); | ||
548 | + if (entityType.equals(EntityType.DEVICE_PROFILE)) { | ||
549 | + DeviceProfileId deviceProfileId = new DeviceProfileId(entityUuid); | ||
550 | + DeviceProfile deviceProfile = deviceProfileCache.find(deviceProfileId); | ||
551 | + builder.setData(ByteString.copyFrom(dataDecodingEncodingService.encode(deviceProfile))); | ||
552 | + } else if (entityType.equals(EntityType.TENANT)) { | ||
553 | + TenantId tenantId = TenantId.fromUUID(entityUuid); | ||
554 | + TenantProfile tenantProfile = tenantProfileCache.get(tenantId); | ||
555 | + ApiUsageState state = apiUsageStateService.getApiUsageState(tenantId); | ||
556 | + builder.setData(ByteString.copyFrom(dataDecodingEncodingService.encode(tenantProfile))); | ||
557 | + builder.setApiState(ByteString.copyFrom(dataDecodingEncodingService.encode(state))); | ||
558 | + } else { | ||
559 | + throw new RuntimeException("Invalid entity profile request: " + entityType); | ||
494 | } | 560 | } |
495 | - | ||
496 | - | ||
497 | - private ListenableFuture<TransportApiResponseMsg> handle(GetResourceRequestMsg requestMsg) { | ||
498 | - TenantId tenantId = TenantId.fromUUID(new UUID(requestMsg.getTenantIdMSB(), requestMsg.getTenantIdLSB())); | ||
499 | - ResourceType resourceType = ResourceType.valueOf(requestMsg.getResourceType()); | ||
500 | - String resourceKey = requestMsg.getResourceKey(); | ||
501 | - TransportProtos.GetResourceResponseMsg.Builder builder = TransportProtos.GetResourceResponseMsg.newBuilder(); | ||
502 | - TbResource resource = resourceService.getResource(tenantId, resourceType, resourceKey); | ||
503 | - | ||
504 | - if (resource == null && !tenantId.equals(TenantId.SYS_TENANT_ID)) { | ||
505 | - resource = resourceService.getResource(TenantId.SYS_TENANT_ID, resourceType, resourceKey); | ||
506 | - } | ||
507 | - | ||
508 | - if (resource != null) { | ||
509 | - builder.setResource(ByteString.copyFrom(dataDecodingEncodingService.encode(resource))); | ||
510 | - } | ||
511 | - | ||
512 | - return Futures.immediateFuture(TransportApiResponseMsg.newBuilder().setResourceResponseMsg(builder).build()); | 561 | + return Futures.immediateFuture( |
562 | + TransportApiResponseMsg.newBuilder().setEntityProfileResponseMsg(builder).build()); | ||
563 | + } | ||
564 | + | ||
565 | + private ListenableFuture<TransportApiResponseMsg> handle(GetDeviceRequestMsg requestMsg) { | ||
566 | + DeviceId deviceId = | ||
567 | + new DeviceId(new UUID(requestMsg.getDeviceIdMSB(), requestMsg.getDeviceIdLSB())); | ||
568 | + Device device = deviceService.findDeviceById(TenantId.SYS_TENANT_ID, deviceId); | ||
569 | + | ||
570 | + TransportApiResponseMsg responseMsg; | ||
571 | + if (device != null) { | ||
572 | + UUID deviceProfileId = device.getDeviceProfileId().getId(); | ||
573 | + responseMsg = | ||
574 | + TransportApiResponseMsg.newBuilder() | ||
575 | + .setDeviceResponseMsg( | ||
576 | + TransportProtos.GetDeviceResponseMsg.newBuilder() | ||
577 | + .setDeviceProfileIdMSB(deviceProfileId.getMostSignificantBits()) | ||
578 | + .setDeviceProfileIdLSB(deviceProfileId.getLeastSignificantBits()) | ||
579 | + .setDeviceTransportConfiguration( | ||
580 | + ByteString.copyFrom( | ||
581 | + dataDecodingEncodingService.encode( | ||
582 | + device.getDeviceData().getTransportConfiguration())))) | ||
583 | + .build(); | ||
584 | + } else { | ||
585 | + responseMsg = TransportApiResponseMsg.getDefaultInstance(); | ||
513 | } | 586 | } |
514 | 587 | ||
515 | - private ListenableFuture<TransportApiResponseMsg> handle(GetSnmpDevicesRequestMsg requestMsg) { | ||
516 | - PageLink pageLink = new PageLink(requestMsg.getPageSize(), requestMsg.getPage()); | ||
517 | - PageData<UUID> result = deviceService.findDevicesIdsByDeviceProfileTransportType(DeviceTransportType.SNMP, pageLink); | ||
518 | - | ||
519 | - GetSnmpDevicesResponseMsg responseMsg = GetSnmpDevicesResponseMsg.newBuilder() | ||
520 | - .addAllIds(result.getData().stream() | ||
521 | - .map(UUID::toString) | ||
522 | - .collect(Collectors.toList())) | ||
523 | - .setHasNextPage(result.hasNext()) | ||
524 | - .build(); | 588 | + return Futures.immediateFuture(responseMsg); |
589 | + } | ||
590 | + | ||
591 | + private ListenableFuture<TransportApiResponseMsg> handle( | ||
592 | + GetDeviceCredentialsRequestMsg requestMsg) { | ||
593 | + DeviceId deviceId = | ||
594 | + new DeviceId(new UUID(requestMsg.getDeviceIdMSB(), requestMsg.getDeviceIdLSB())); | ||
595 | + DeviceCredentials deviceCredentials = | ||
596 | + deviceCredentialsService.findDeviceCredentialsByDeviceId(TenantId.SYS_TENANT_ID, deviceId); | ||
597 | + | ||
598 | + return Futures.immediateFuture( | ||
599 | + TransportApiResponseMsg.newBuilder() | ||
600 | + .setDeviceCredentialsResponseMsg( | ||
601 | + TransportProtos.GetDeviceCredentialsResponseMsg.newBuilder() | ||
602 | + .setDeviceCredentialsData( | ||
603 | + ByteString.copyFrom(dataDecodingEncodingService.encode(deviceCredentials)))) | ||
604 | + .build()); | ||
605 | + } | ||
606 | + | ||
607 | + private ListenableFuture<TransportApiResponseMsg> handle(GetResourceRequestMsg requestMsg) { | ||
608 | + TenantId tenantId = | ||
609 | + TenantId.fromUUID(new UUID(requestMsg.getTenantIdMSB(), requestMsg.getTenantIdLSB())); | ||
610 | + ResourceType resourceType = ResourceType.valueOf(requestMsg.getResourceType()); | ||
611 | + String resourceKey = requestMsg.getResourceKey(); | ||
612 | + TransportProtos.GetResourceResponseMsg.Builder builder = | ||
613 | + TransportProtos.GetResourceResponseMsg.newBuilder(); | ||
614 | + TbResource resource = resourceService.getResource(tenantId, resourceType, resourceKey); | ||
615 | + | ||
616 | + if (resource == null && !tenantId.equals(TenantId.SYS_TENANT_ID)) { | ||
617 | + resource = resourceService.getResource(TenantId.SYS_TENANT_ID, resourceType, resourceKey); | ||
618 | + } | ||
525 | 619 | ||
526 | - return Futures.immediateFuture(TransportApiResponseMsg.newBuilder() | ||
527 | - .setSnmpDevicesResponseMsg(responseMsg) | ||
528 | - .build()); | 620 | + if (resource != null) { |
621 | + builder.setResource(ByteString.copyFrom(dataDecodingEncodingService.encode(resource))); | ||
529 | } | 622 | } |
530 | 623 | ||
531 | - private ListenableFuture<TransportApiResponseMsg> getDeviceInfo(DeviceCredentials credentials) { | ||
532 | - return Futures.transform(deviceService.findDeviceByIdAsync(TenantId.SYS_TENANT_ID, credentials.getDeviceId()), device -> { | ||
533 | - if (device == null) { | ||
534 | - log.trace("[{}] Failed to lookup device by id", credentials.getDeviceId()); | ||
535 | - return getEmptyTransportApiResponse(); | 624 | + return Futures.immediateFuture( |
625 | + TransportApiResponseMsg.newBuilder().setResourceResponseMsg(builder).build()); | ||
626 | + } | ||
627 | + | ||
628 | + private ListenableFuture<TransportApiResponseMsg> handle(GetSnmpDevicesRequestMsg requestMsg) { | ||
629 | + PageLink pageLink = new PageLink(requestMsg.getPageSize(), requestMsg.getPage()); | ||
630 | + PageData<UUID> result = | ||
631 | + deviceService.findDevicesIdsByDeviceProfileTransportType( | ||
632 | + DeviceTransportType.SNMP, pageLink); | ||
633 | + | ||
634 | + GetSnmpDevicesResponseMsg responseMsg = | ||
635 | + GetSnmpDevicesResponseMsg.newBuilder() | ||
636 | + .addAllIds(result.getData().stream().map(UUID::toString).collect(Collectors.toList())) | ||
637 | + .setHasNextPage(result.hasNext()) | ||
638 | + .build(); | ||
639 | + | ||
640 | + return Futures.immediateFuture( | ||
641 | + TransportApiResponseMsg.newBuilder().setSnmpDevicesResponseMsg(responseMsg).build()); | ||
642 | + } | ||
643 | + | ||
644 | + private ListenableFuture<TransportApiResponseMsg> getDeviceInfo(DeviceCredentials credentials) { | ||
645 | + return Futures.transform( | ||
646 | + deviceService.findDeviceByIdAsync(TenantId.SYS_TENANT_ID, credentials.getDeviceId()), | ||
647 | + device -> { | ||
648 | + if (device == null) { | ||
649 | + log.trace("[{}] Failed to lookup device by id", credentials.getDeviceId()); | ||
650 | + return getEmptyTransportApiResponse(); | ||
651 | + } | ||
652 | + try { | ||
653 | + ValidateDeviceCredentialsResponseMsg.Builder builder = | ||
654 | + ValidateDeviceCredentialsResponseMsg.newBuilder(); | ||
655 | + builder.setDeviceInfo(getDeviceInfoProto(device)); | ||
656 | + DeviceProfile deviceProfile = | ||
657 | + deviceProfileCache.get(device.getTenantId(), device.getDeviceProfileId()); | ||
658 | + if (deviceProfile != null) { | ||
659 | + builder.setProfileBody( | ||
660 | + ByteString.copyFrom(dataDecodingEncodingService.encode(deviceProfile))); | ||
661 | + } else { | ||
662 | + log.warn( | ||
663 | + "[{}] Failed to find device profile [{}] for device. ", | ||
664 | + device.getId(), | ||
665 | + device.getDeviceProfileId()); | ||
536 | } | 666 | } |
537 | - try { | ||
538 | - ValidateDeviceCredentialsResponseMsg.Builder builder = ValidateDeviceCredentialsResponseMsg.newBuilder(); | ||
539 | - builder.setDeviceInfo(getDeviceInfoProto(device)); | ||
540 | - DeviceProfile deviceProfile = deviceProfileCache.get(device.getTenantId(), device.getDeviceProfileId()); | ||
541 | - if (deviceProfile != null) { | ||
542 | - builder.setProfileBody(ByteString.copyFrom(dataDecodingEncodingService.encode(deviceProfile))); | ||
543 | - } else { | ||
544 | - log.warn("[{}] Failed to find device profile [{}] for device. ", device.getId(), device.getDeviceProfileId()); | ||
545 | - } | ||
546 | - if (!StringUtils.isEmpty(credentials.getCredentialsValue())) { | ||
547 | - builder.setCredentialsBody(credentials.getCredentialsValue()); | ||
548 | - } | ||
549 | - return TransportApiResponseMsg.newBuilder() | ||
550 | - .setValidateCredResponseMsg(builder.build()).build(); | ||
551 | - } catch (JsonProcessingException e) { | ||
552 | - log.warn("[{}] Failed to lookup device by id", credentials.getDeviceId(), e); | ||
553 | - return getEmptyTransportApiResponse(); | 667 | + if (!StringUtils.isEmpty(credentials.getCredentialsValue())) { |
668 | + builder.setCredentialsBody(credentials.getCredentialsValue()); | ||
554 | } | 669 | } |
555 | - }, MoreExecutors.directExecutor()); | 670 | + return TransportApiResponseMsg.newBuilder() |
671 | + .setValidateCredResponseMsg(builder.build()) | ||
672 | + .build(); | ||
673 | + } catch (JsonProcessingException e) { | ||
674 | + log.warn("[{}] Failed to lookup device by id", credentials.getDeviceId(), e); | ||
675 | + return getEmptyTransportApiResponse(); | ||
676 | + } | ||
677 | + }, | ||
678 | + MoreExecutors.directExecutor()); | ||
679 | + } | ||
680 | + | ||
681 | + private DeviceInfoProto getDeviceInfoProto(Device device) throws JsonProcessingException { | ||
682 | + DeviceInfoProto.Builder builder = | ||
683 | + DeviceInfoProto.newBuilder() | ||
684 | + .setTenantIdMSB(device.getTenantId().getId().getMostSignificantBits()) | ||
685 | + .setTenantIdLSB(device.getTenantId().getId().getLeastSignificantBits()) | ||
686 | + .setCustomerIdMSB( | ||
687 | + Optional.ofNullable(device.getCustomerId()) | ||
688 | + .map(customerId -> customerId.getId().getMostSignificantBits()) | ||
689 | + .orElse(0L)) | ||
690 | + .setCustomerIdLSB( | ||
691 | + Optional.ofNullable(device.getCustomerId()) | ||
692 | + .map(customerId -> customerId.getId().getLeastSignificantBits()) | ||
693 | + .orElse(0L)) | ||
694 | + .setDeviceIdMSB(device.getId().getId().getMostSignificantBits()) | ||
695 | + .setDeviceIdLSB(device.getId().getId().getLeastSignificantBits()) | ||
696 | + .setDeviceName(device.getName()) | ||
697 | + .setDeviceType(device.getType()) | ||
698 | + .setDeviceProfileIdMSB(device.getDeviceProfileId().getId().getMostSignificantBits()) | ||
699 | + .setDeviceProfileIdLSB(device.getDeviceProfileId().getId().getLeastSignificantBits()) | ||
700 | + .setAdditionalInfo(mapper.writeValueAsString(device.getAdditionalInfo())); | ||
701 | + | ||
702 | + PowerSavingConfiguration psmConfiguration = null; | ||
703 | + switch (device.getDeviceData().getTransportConfiguration().getType()) { | ||
704 | + case LWM2M: | ||
705 | + psmConfiguration = | ||
706 | + (Lwm2mDeviceTransportConfiguration) device.getDeviceData().getTransportConfiguration(); | ||
707 | + break; | ||
708 | + case COAP: | ||
709 | + psmConfiguration = | ||
710 | + (CoapDeviceTransportConfiguration) device.getDeviceData().getTransportConfiguration(); | ||
711 | + break; | ||
556 | } | 712 | } |
557 | 713 | ||
558 | - private DeviceInfoProto getDeviceInfoProto(Device device) throws JsonProcessingException { | ||
559 | - DeviceInfoProto.Builder builder = DeviceInfoProto.newBuilder() | ||
560 | - .setTenantIdMSB(device.getTenantId().getId().getMostSignificantBits()) | ||
561 | - .setTenantIdLSB(device.getTenantId().getId().getLeastSignificantBits()) | ||
562 | - .setCustomerIdMSB(Optional.ofNullable(device.getCustomerId()).map(customerId -> customerId.getId().getMostSignificantBits()).orElse(0L)) | ||
563 | - .setCustomerIdLSB(Optional.ofNullable(device.getCustomerId()).map(customerId -> customerId.getId().getLeastSignificantBits()).orElse(0L)) | ||
564 | - .setDeviceIdMSB(device.getId().getId().getMostSignificantBits()) | ||
565 | - .setDeviceIdLSB(device.getId().getId().getLeastSignificantBits()) | ||
566 | - .setDeviceName(device.getName()) | ||
567 | - .setDeviceType(device.getType()) | ||
568 | - .setDeviceProfileIdMSB(device.getDeviceProfileId().getId().getMostSignificantBits()) | ||
569 | - .setDeviceProfileIdLSB(device.getDeviceProfileId().getId().getLeastSignificantBits()) | ||
570 | - .setAdditionalInfo(mapper.writeValueAsString(device.getAdditionalInfo())); | ||
571 | - | ||
572 | - PowerSavingConfiguration psmConfiguration = null; | ||
573 | - switch (device.getDeviceData().getTransportConfiguration().getType()) { | ||
574 | - case LWM2M: | ||
575 | - psmConfiguration = (Lwm2mDeviceTransportConfiguration) device.getDeviceData().getTransportConfiguration(); | ||
576 | - break; | ||
577 | - case COAP: | ||
578 | - psmConfiguration = (CoapDeviceTransportConfiguration) device.getDeviceData().getTransportConfiguration(); | ||
579 | - break; | ||
580 | - } | ||
581 | - | ||
582 | - if (psmConfiguration != null) { | ||
583 | - PowerMode powerMode = psmConfiguration.getPowerMode(); | ||
584 | - if (powerMode != null) { | ||
585 | - builder.setPowerMode(powerMode.name()); | ||
586 | - if (powerMode.equals(PowerMode.PSM)) { | ||
587 | - builder.setPsmActivityTimer(checkLong(psmConfiguration.getPsmActivityTimer())); | ||
588 | - } else if (powerMode.equals(PowerMode.E_DRX)) { | ||
589 | - builder.setEdrxCycle(checkLong(psmConfiguration.getEdrxCycle())); | ||
590 | - builder.setPagingTransmissionWindow(checkLong(psmConfiguration.getPagingTransmissionWindow())); | ||
591 | - } | ||
592 | - } | 714 | + if (psmConfiguration != null) { |
715 | + PowerMode powerMode = psmConfiguration.getPowerMode(); | ||
716 | + if (powerMode != null) { | ||
717 | + builder.setPowerMode(powerMode.name()); | ||
718 | + if (powerMode.equals(PowerMode.PSM)) { | ||
719 | + builder.setPsmActivityTimer(checkLong(psmConfiguration.getPsmActivityTimer())); | ||
720 | + } else if (powerMode.equals(PowerMode.E_DRX)) { | ||
721 | + builder.setEdrxCycle(checkLong(psmConfiguration.getEdrxCycle())); | ||
722 | + builder.setPagingTransmissionWindow( | ||
723 | + checkLong(psmConfiguration.getPagingTransmissionWindow())); | ||
593 | } | 724 | } |
594 | - return builder.build(); | 725 | + } |
595 | } | 726 | } |
596 | - | ||
597 | - private ListenableFuture<TransportApiResponseMsg> getEmptyTransportApiResponseFuture() { | ||
598 | - return Futures.immediateFuture(getEmptyTransportApiResponse()); | 727 | + return builder.build(); |
728 | + } | ||
729 | + | ||
730 | + private ListenableFuture<TransportApiResponseMsg> getEmptyTransportApiResponseFuture() { | ||
731 | + return Futures.immediateFuture(getEmptyTransportApiResponse()); | ||
732 | + } | ||
733 | + | ||
734 | + private TransportApiResponseMsg getEmptyTransportApiResponse() { | ||
735 | + return TransportApiResponseMsg.newBuilder() | ||
736 | + .setValidateCredResponseMsg(ValidateDeviceCredentialsResponseMsg.getDefaultInstance()) | ||
737 | + .build(); | ||
738 | + } | ||
739 | + | ||
740 | + private ListenableFuture<TransportApiResponseMsg> handle( | ||
741 | + TransportProtos.LwM2MRequestMsg requestMsg) { | ||
742 | + if (requestMsg.hasRegistrationMsg()) { | ||
743 | + return handleRegistration(requestMsg.getRegistrationMsg()); | ||
744 | + } else { | ||
745 | + return Futures.immediateFailedFuture(new RuntimeException("Not supported!")); | ||
599 | } | 746 | } |
600 | - | ||
601 | - private TransportApiResponseMsg getEmptyTransportApiResponse() { | ||
602 | - return TransportApiResponseMsg.newBuilder() | ||
603 | - .setValidateCredResponseMsg(ValidateDeviceCredentialsResponseMsg.getDefaultInstance()).build(); | 747 | + } |
748 | + | ||
749 | + private ListenableFuture<TransportApiResponseMsg> handle( | ||
750 | + TransportProtos.GetOtaPackageRequestMsg requestMsg) { | ||
751 | + TenantId tenantId = | ||
752 | + TenantId.fromUUID(new UUID(requestMsg.getTenantIdMSB(), requestMsg.getTenantIdLSB())); | ||
753 | + DeviceId deviceId = | ||
754 | + new DeviceId(new UUID(requestMsg.getDeviceIdMSB(), requestMsg.getDeviceIdLSB())); | ||
755 | + OtaPackageType otaPackageType = OtaPackageType.valueOf(requestMsg.getType()); | ||
756 | + Device device = deviceService.findDeviceById(tenantId, deviceId); | ||
757 | + | ||
758 | + if (device == null) { | ||
759 | + return getEmptyTransportApiResponseFuture(); | ||
604 | } | 760 | } |
605 | 761 | ||
606 | - private ListenableFuture<TransportApiResponseMsg> handle(TransportProtos.LwM2MRequestMsg requestMsg) { | ||
607 | - if (requestMsg.hasRegistrationMsg()) { | ||
608 | - return handleRegistration(requestMsg.getRegistrationMsg()); | ||
609 | - } else { | ||
610 | - return Futures.immediateFailedFuture(new RuntimeException("Not supported!")); | ||
611 | - } | ||
612 | - } | ||
613 | - | ||
614 | - private ListenableFuture<TransportApiResponseMsg> handle(TransportProtos.GetOtaPackageRequestMsg requestMsg) { | ||
615 | - TenantId tenantId = TenantId.fromUUID(new UUID(requestMsg.getTenantIdMSB(), requestMsg.getTenantIdLSB())); | ||
616 | - DeviceId deviceId = new DeviceId(new UUID(requestMsg.getDeviceIdMSB(), requestMsg.getDeviceIdLSB())); | ||
617 | - OtaPackageType otaPackageType = OtaPackageType.valueOf(requestMsg.getType()); | ||
618 | - Device device = deviceService.findDeviceById(tenantId, deviceId); | ||
619 | - | ||
620 | - if (device == null) { | ||
621 | - return getEmptyTransportApiResponseFuture(); | ||
622 | - } | ||
623 | - | ||
624 | - OtaPackageId otaPackageId = OtaPackageUtil.getOtaPackageId(device, otaPackageType); | ||
625 | - if (otaPackageId == null) { | ||
626 | - DeviceProfile deviceProfile = deviceProfileCache.find(device.getDeviceProfileId()); | ||
627 | - otaPackageId = OtaPackageUtil.getOtaPackageId(deviceProfile, otaPackageType); | ||
628 | - } | ||
629 | - | ||
630 | - TransportProtos.GetOtaPackageResponseMsg.Builder builder = TransportProtos.GetOtaPackageResponseMsg.newBuilder(); | ||
631 | - | ||
632 | - if (otaPackageId == null) { | ||
633 | - builder.setResponseStatus(TransportProtos.ResponseStatus.NOT_FOUND); | ||
634 | - } else { | ||
635 | - OtaPackageInfo otaPackageInfo = otaPackageService.findOtaPackageInfoById(tenantId, otaPackageId); | ||
636 | - | ||
637 | - if (otaPackageInfo == null) { | ||
638 | - builder.setResponseStatus(TransportProtos.ResponseStatus.NOT_FOUND); | ||
639 | - } else if (otaPackageInfo.hasUrl()) { | ||
640 | - builder.setResponseStatus(TransportProtos.ResponseStatus.FAILURE); | ||
641 | - log.trace("[{}] Can`t send OtaPackage with URL data!", otaPackageInfo.getId()); | ||
642 | - } else { | ||
643 | - builder.setResponseStatus(TransportProtos.ResponseStatus.SUCCESS); | ||
644 | - builder.setOtaPackageIdMSB(otaPackageId.getId().getMostSignificantBits()); | ||
645 | - builder.setOtaPackageIdLSB(otaPackageId.getId().getLeastSignificantBits()); | ||
646 | - builder.setType(otaPackageInfo.getType().name()); | ||
647 | - builder.setTitle(otaPackageInfo.getTitle()); | ||
648 | - builder.setVersion(otaPackageInfo.getVersion()); | ||
649 | - builder.setFileName(otaPackageInfo.getFileName()); | ||
650 | - builder.setContentType(otaPackageInfo.getContentType()); | ||
651 | - if (!otaPackageDataCache.has(otaPackageId.toString())) { | ||
652 | - OtaPackage otaPackage = otaPackageService.findOtaPackageById(tenantId, otaPackageId); | ||
653 | - otaPackageDataCache.put(otaPackageId.toString(), otaPackage.getData().array()); | ||
654 | - } | ||
655 | - } | ||
656 | - } | ||
657 | - | ||
658 | - return Futures.immediateFuture( | ||
659 | - TransportApiResponseMsg.newBuilder() | ||
660 | - .setOtaPackageResponseMsg(builder.build()) | ||
661 | - .build()); | 762 | + OtaPackageId otaPackageId = OtaPackageUtil.getOtaPackageId(device, otaPackageType); |
763 | + if (otaPackageId == null) { | ||
764 | + DeviceProfile deviceProfile = deviceProfileCache.find(device.getDeviceProfileId()); | ||
765 | + otaPackageId = OtaPackageUtil.getOtaPackageId(deviceProfile, otaPackageType); | ||
662 | } | 766 | } |
663 | 767 | ||
664 | - private ListenableFuture<TransportApiResponseMsg> handleRegistration | ||
665 | - (TransportProtos.LwM2MRegistrationRequestMsg msg) { | ||
666 | - TenantId tenantId = TenantId.fromUUID(UUID.fromString(msg.getTenantId())); | ||
667 | - String deviceName = msg.getEndpoint(); | ||
668 | - Lock deviceCreationLock = deviceCreationLocks.computeIfAbsent(deviceName, id -> new ReentrantLock()); | ||
669 | - deviceCreationLock.lock(); | ||
670 | - try { | ||
671 | - Device device = deviceService.findDeviceByTenantIdAndName(tenantId, deviceName); | ||
672 | - if (device == null) { | ||
673 | - device = new Device(); | ||
674 | - device.setTenantId(tenantId); | ||
675 | - device.setName(deviceName); | ||
676 | - device.setType("LwM2M"); | ||
677 | - device = deviceService.saveDevice(device); | ||
678 | - tbClusterService.onDeviceUpdated(device, null); | ||
679 | - } | ||
680 | - TransportProtos.LwM2MRegistrationResponseMsg registrationResponseMsg = | ||
681 | - TransportProtos.LwM2MRegistrationResponseMsg.newBuilder() | ||
682 | - .setDeviceInfo(getDeviceInfoProto(device)).build(); | ||
683 | - TransportProtos.LwM2MResponseMsg responseMsg = TransportProtos.LwM2MResponseMsg.newBuilder().setRegistrationMsg(registrationResponseMsg).build(); | ||
684 | - return Futures.immediateFuture(TransportApiResponseMsg.newBuilder().setLwM2MResponseMsg(responseMsg).build()); | ||
685 | - } catch (JsonProcessingException e) { | ||
686 | - log.warn("[{}][{}] Failed to lookup device by gateway id and name", tenantId, deviceName, e); | ||
687 | - throw new RuntimeException(e); | ||
688 | - } finally { | ||
689 | - deviceCreationLock.unlock(); | 768 | + TransportProtos.GetOtaPackageResponseMsg.Builder builder = |
769 | + TransportProtos.GetOtaPackageResponseMsg.newBuilder(); | ||
770 | + | ||
771 | + if (otaPackageId == null) { | ||
772 | + builder.setResponseStatus(TransportProtos.ResponseStatus.NOT_FOUND); | ||
773 | + } else { | ||
774 | + OtaPackageInfo otaPackageInfo = | ||
775 | + otaPackageService.findOtaPackageInfoById(tenantId, otaPackageId); | ||
776 | + | ||
777 | + if (otaPackageInfo == null) { | ||
778 | + builder.setResponseStatus(TransportProtos.ResponseStatus.NOT_FOUND); | ||
779 | + } else if (otaPackageInfo.hasUrl()) { | ||
780 | + builder.setResponseStatus(TransportProtos.ResponseStatus.FAILURE); | ||
781 | + log.trace("[{}] Can`t send OtaPackage with URL data!", otaPackageInfo.getId()); | ||
782 | + } else { | ||
783 | + builder.setResponseStatus(TransportProtos.ResponseStatus.SUCCESS); | ||
784 | + builder.setOtaPackageIdMSB(otaPackageId.getId().getMostSignificantBits()); | ||
785 | + builder.setOtaPackageIdLSB(otaPackageId.getId().getLeastSignificantBits()); | ||
786 | + builder.setType(otaPackageInfo.getType().name()); | ||
787 | + builder.setTitle(otaPackageInfo.getTitle()); | ||
788 | + builder.setVersion(otaPackageInfo.getVersion()); | ||
789 | + builder.setFileName(otaPackageInfo.getFileName()); | ||
790 | + builder.setContentType(otaPackageInfo.getContentType()); | ||
791 | + if (!otaPackageDataCache.has(otaPackageId.toString())) { | ||
792 | + OtaPackage otaPackage = otaPackageService.findOtaPackageById(tenantId, otaPackageId); | ||
793 | + otaPackageDataCache.put(otaPackageId.toString(), otaPackage.getData().array()); | ||
690 | } | 794 | } |
795 | + } | ||
691 | } | 796 | } |
692 | 797 | ||
693 | - private Long checkLong(Long l) { | ||
694 | - return l != null ? l : 0; | 798 | + return Futures.immediateFuture( |
799 | + TransportApiResponseMsg.newBuilder().setOtaPackageResponseMsg(builder.build()).build()); | ||
800 | + } | ||
801 | + | ||
802 | + private ListenableFuture<TransportApiResponseMsg> handleRegistration( | ||
803 | + TransportProtos.LwM2MRegistrationRequestMsg msg) { | ||
804 | + TenantId tenantId = TenantId.fromUUID(UUID.fromString(msg.getTenantId())); | ||
805 | + String deviceName = msg.getEndpoint(); | ||
806 | + Lock deviceCreationLock = | ||
807 | + deviceCreationLocks.computeIfAbsent(deviceName, id -> new ReentrantLock()); | ||
808 | + deviceCreationLock.lock(); | ||
809 | + try { | ||
810 | + Device device = deviceService.findDeviceByTenantIdAndName(tenantId, deviceName); | ||
811 | + if (device == null) { | ||
812 | + device = new Device(); | ||
813 | + device.setTenantId(tenantId); | ||
814 | + device.setName(deviceName); | ||
815 | + device.setType("LwM2M"); | ||
816 | + device = deviceService.saveDevice(device); | ||
817 | + tbClusterService.onDeviceUpdated(device, null); | ||
818 | + } | ||
819 | + TransportProtos.LwM2MRegistrationResponseMsg registrationResponseMsg = | ||
820 | + TransportProtos.LwM2MRegistrationResponseMsg.newBuilder() | ||
821 | + .setDeviceInfo(getDeviceInfoProto(device)) | ||
822 | + .build(); | ||
823 | + TransportProtos.LwM2MResponseMsg responseMsg = | ||
824 | + TransportProtos.LwM2MResponseMsg.newBuilder() | ||
825 | + .setRegistrationMsg(registrationResponseMsg) | ||
826 | + .build(); | ||
827 | + return Futures.immediateFuture( | ||
828 | + TransportApiResponseMsg.newBuilder().setLwM2MResponseMsg(responseMsg).build()); | ||
829 | + } catch (JsonProcessingException e) { | ||
830 | + log.warn("[{}][{}] Failed to lookup device by gateway id and name", tenantId, deviceName, e); | ||
831 | + throw new RuntimeException(e); | ||
832 | + } finally { | ||
833 | + deviceCreationLock.unlock(); | ||
695 | } | 834 | } |
696 | - | ||
697 | - | ||
698 | - | ||
699 | - //Thingskit function | ||
700 | - private ListenableFuture<TransportApiResponseMsg> handle(TransportProtos.ScriptProto requestMsg) { | ||
701 | - List<TkDeviceScriptDTO> allScriptes = scriptService.getScriptes(); | ||
702 | - TransportApiResponseMsg.Builder responseBuilder = TransportApiResponseMsg.newBuilder(); | ||
703 | - allScriptes.forEach( | ||
704 | - item -> { | ||
705 | - UUID tenantId = UUID.fromString(item.getTenantId()); | ||
706 | - UUID id = UUID.fromString(item.getId()); | ||
707 | - responseBuilder.addScriptsResponseMsg( | ||
708 | - TransportProtos.ScriptProto.newBuilder() | ||
709 | - .setConvertJs(item.getConvertJs()) | ||
710 | - .setTenantIdLSB(tenantId.getLeastSignificantBits()) | ||
711 | - .setTenantIdMSB(tenantId.getMostSignificantBits()) | ||
712 | - .setScriptIdLSB(id.getLeastSignificantBits()) | ||
713 | - .setScriptIdMSB(id.getMostSignificantBits()) | ||
714 | - .setFunctionType(item.getScriptType().name()) | ||
715 | - .setStatus(item.getStatus())); | ||
716 | - }); | ||
717 | - return Futures.immediateFuture(responseBuilder.build()); | ||
718 | - } | ||
719 | - private ListenableFuture<TransportApiResponseMsg> handleGbt(TransportProtos.Gbt28181RequestMsg requestMsg) { | ||
720 | - TransportProtos.Gbt28181ResponseMsg.Builder responseMsgBuilder =TransportProtos.Gbt28181ResponseMsg.newBuilder(); | ||
721 | - String tenantId = new UUID(requestMsg.getTenantIdMSB(), requestMsg.getTenantIdLSB()).toString(); | ||
722 | - String tbDeviceId = new UUID(requestMsg.getEntityIdMSB(), requestMsg.getEntityIdLSB()).toString(); | ||
723 | - String type = requestMsg.getContextType(); | ||
724 | - switch (VideoCmdEnum.valueOf(type)){ | ||
725 | - case DeviceInfo: | ||
726 | - Optional<SipDeviceDTO> camera = dataDecodingEncodingService.decode(requestMsg.getContext().toByteArray()); | ||
727 | - camera.ifPresent(sip ->{ | ||
728 | - ytDeviceService.updateDeviceInfo(tenantId,tbDeviceId, FastIotConstants.DeviceAdditional.SIP,JacksonUtil.valueToTree(sip)); | ||
729 | - }); | ||
730 | - | ||
731 | - break; | ||
732 | - case Catalog: | ||
733 | - Optional<List<VideoChanelDTO>> allChannel = dataDecodingEncodingService.decode(requestMsg.getContext().toByteArray()); | ||
734 | - allChannel.ifPresent(d->{ | ||
735 | - channelService.clearDeviceChannel(d.get(0).getCameraCode()); | ||
736 | - List<TkVideoChannelEntity> chanel= d.stream().map(item -> item.getEntity(TkVideoChannelEntity.class)).collect(Collectors.toList()); | ||
737 | - channelService.insertBatch(chanel,chanel.size()); | ||
738 | - }); | ||
739 | - break; | ||
740 | - default: | ||
741 | - release(tenantId,tbDeviceId); | ||
742 | - | ||
743 | - } | ||
744 | -// byte[] channaelMsgBytes = dataDecodingEncodingService.encode(channelDTO); | ||
745 | -// responseMsgBuilder.setContext(ByteString.copyFrom(channaelMsgBytes)); | ||
746 | - return Futures.immediateFuture(TransportApiResponseMsg.newBuilder().setGbt28181ResponseMsg(responseMsgBuilder.build()).build()); | 835 | + } |
836 | + | ||
837 | + private Long checkLong(Long l) { | ||
838 | + return l != null ? l : 0; | ||
839 | + } | ||
840 | + | ||
841 | + // Thingskit function | ||
842 | + private ListenableFuture<TransportApiResponseMsg> handle(TransportProtos.ScriptProto requestMsg) { | ||
843 | + List<TkDeviceScriptDTO> allScriptes = scriptService.getScriptes(); | ||
844 | + TransportApiResponseMsg.Builder responseBuilder = TransportApiResponseMsg.newBuilder(); | ||
845 | + allScriptes.forEach( | ||
846 | + item -> { | ||
847 | + UUID tenantId = UUID.fromString(item.getTenantId()); | ||
848 | + UUID id = UUID.fromString(item.getId()); | ||
849 | + responseBuilder.addScriptsResponseMsg( | ||
850 | + TransportProtos.ScriptProto.newBuilder() | ||
851 | + .setConvertJs(item.getConvertJs()) | ||
852 | + .setTenantIdLSB(tenantId.getLeastSignificantBits()) | ||
853 | + .setTenantIdMSB(tenantId.getMostSignificantBits()) | ||
854 | + .setScriptIdLSB(id.getLeastSignificantBits()) | ||
855 | + .setScriptIdMSB(id.getMostSignificantBits()) | ||
856 | + .setFunctionType(item.getScriptType().name()) | ||
857 | + .setStatus(item.getStatus())); | ||
858 | + }); | ||
859 | + return Futures.immediateFuture(responseBuilder.build()); | ||
860 | + } | ||
861 | + | ||
862 | + private ListenableFuture<TransportApiResponseMsg> handleGbt( | ||
863 | + TransportProtos.Gbt28181RequestMsg requestMsg) { | ||
864 | + TransportProtos.Gbt28181ResponseMsg.Builder responseMsgBuilder = | ||
865 | + TransportProtos.Gbt28181ResponseMsg.newBuilder(); | ||
866 | + String tenantId = new UUID(requestMsg.getTenantIdMSB(), requestMsg.getTenantIdLSB()).toString(); | ||
867 | + String tbDeviceId = | ||
868 | + new UUID(requestMsg.getEntityIdMSB(), requestMsg.getEntityIdLSB()).toString(); | ||
869 | + String type = requestMsg.getContextType(); | ||
870 | + switch (VideoCmdEnum.valueOf(type)) { | ||
871 | + case DeviceInfo: | ||
872 | + Optional<SipDeviceDTO> camera = | ||
873 | + dataDecodingEncodingService.decode(requestMsg.getContext().toByteArray()); | ||
874 | + camera.ifPresent( | ||
875 | + sip -> { | ||
876 | + ytDeviceService.updateDeviceInfo( | ||
877 | + tenantId, | ||
878 | + tbDeviceId, | ||
879 | + FastIotConstants.DeviceAdditional.SIP, | ||
880 | + JacksonUtil.valueToTree(sip)); | ||
881 | + }); | ||
882 | + | ||
883 | + break; | ||
884 | + case Catalog: | ||
885 | + Optional<List<VideoChanelDTO>> allChannel = | ||
886 | + dataDecodingEncodingService.decode(requestMsg.getContext().toByteArray()); | ||
887 | + allChannel.ifPresent( | ||
888 | + d -> { | ||
889 | + channelService.clearDeviceChannel(d.get(0).getCameraCode()); | ||
890 | + List<TkVideoChannelEntity> chanel = | ||
891 | + d.stream() | ||
892 | + .map(item -> item.getEntity(TkVideoChannelEntity.class)) | ||
893 | + .collect(Collectors.toList()); | ||
894 | + channelService.insertBatch(chanel, chanel.size()); | ||
895 | + }); | ||
896 | + break; | ||
897 | + default: | ||
898 | + release(tenantId, tbDeviceId); | ||
747 | } | 899 | } |
748 | - private void release(String tenantId,String tbDeviceId){ | ||
749 | - DeviceDTO device = ytDeviceService.findDeviceInfoByTbDeviceId(tenantId,tbDeviceId); | ||
750 | - Optional.ofNullable(device).ifPresent(dev->{ | ||
751 | - JsonNode sip = dev.getDeviceInfo().get(FastIotConstants.DeviceAdditional.SIP); | ||
752 | - if(!sip.isEmpty() && sip.has(FastIotConstants.ZLMediaBody.CAMERA_CODE)){ | 900 | + // byte[] channaelMsgBytes = dataDecodingEncodingService.encode(channelDTO); |
901 | + // responseMsgBuilder.setContext(ByteString.copyFrom(channaelMsgBytes)); | ||
902 | + return Futures.immediateFuture( | ||
903 | + TransportApiResponseMsg.newBuilder() | ||
904 | + .setGbt28181ResponseMsg(responseMsgBuilder.build()) | ||
905 | + .build()); | ||
906 | + } | ||
907 | + | ||
908 | + private void release(String tenantId, String tbDeviceId) { | ||
909 | + DeviceDTO device = ytDeviceService.findDeviceInfoByTbDeviceId(tenantId, tbDeviceId); | ||
910 | + Optional.ofNullable(device) | ||
911 | + .ifPresent( | ||
912 | + dev -> { | ||
913 | + JsonNode sip = dev.getDeviceInfo().get(FastIotConstants.DeviceAdditional.SIP); | ||
914 | + if (!sip.isEmpty() && sip.has(FastIotConstants.ZLMediaBody.CAMERA_CODE)) { | ||
753 | String cameraCode = sip.get(FastIotConstants.ZLMediaBody.CAMERA_CODE).asText(); | 915 | String cameraCode = sip.get(FastIotConstants.ZLMediaBody.CAMERA_CODE).asText(); |
754 | Optional<Set<String>> ssrcKeys = | 916 | Optional<Set<String>> ssrcKeys = |
755 | - videoStreamSessionManager.getSsrcTransactionCamaraKey(cameraCode); | ||
756 | - ssrcKeys.ifPresent(all ->{ | ||
757 | - all.forEach(fullKey->{ | ||
758 | - videoStreamSessionManager.getSsrcTransaction(fullKey).ifPresent(ssrcTransaction -> { | ||
759 | - mediaServerNodeService.releaseSsrc( | ||
760 | - ssrcTransaction.getMediaServerId(), ssrcTransaction.getSsrc()); | ||
761 | - mediaServerNodeService.closeRTPServer( | ||
762 | - ssrcTransaction.getMediaServerId(), ssrcTransaction.getStream()); | ||
763 | - videoStreamSessionManager.remove( | ||
764 | - cameraCode, ssrcTransaction.getChannelId(), | ||
765 | - ssrcTransaction.getStream()); | ||
766 | - }); | ||
767 | - | 917 | + videoStreamSessionManager.getSsrcTransactionCamaraKey(cameraCode); |
918 | + ssrcKeys.ifPresent( | ||
919 | + all -> { | ||
920 | + all.forEach( | ||
921 | + fullKey -> { | ||
922 | + videoStreamSessionManager | ||
923 | + .getSsrcTransaction(fullKey) | ||
924 | + .ifPresent( | ||
925 | + ssrcTransaction -> { | ||
926 | + mediaServerNodeService.releaseSsrc( | ||
927 | + ssrcTransaction.getMediaServerId(), | ||
928 | + ssrcTransaction.getSsrc()); | ||
929 | + mediaServerNodeService.closeRTPServer( | ||
930 | + ssrcTransaction.getMediaServerId(), | ||
931 | + ssrcTransaction.getStream()); | ||
932 | + videoStreamSessionManager.remove( | ||
933 | + cameraCode, | ||
934 | + ssrcTransaction.getChannelId(), | ||
935 | + ssrcTransaction.getStream()); | ||
936 | + }); | ||
937 | + }); | ||
768 | }); | 938 | }); |
769 | - }); | ||
770 | - } | 939 | + } |
940 | + }); | ||
941 | + } | ||
942 | + | ||
943 | + private ListenableFuture<TransportApiResponseMsg> handleGbtMedia( | ||
944 | + TransportProtos.Gbt28181MediaServerMsg requestMsg) { | ||
945 | + Optional<JsonNode> newMediaOpt = | ||
946 | + dataDecodingEncodingService.decode(requestMsg.getProfile().toByteArray()); | ||
947 | + newMediaOpt.ifPresent( | ||
948 | + json -> { | ||
949 | + MediaServerDTO entity = JacksonUtil.treeToValue(json, MediaServerDTO.class); | ||
950 | + MediaServerDTO queryEntity = | ||
951 | + mediaServerService.findMediaServerInfoById(null, entity.getMediaServerId()); | ||
952 | + if (null == queryEntity) { | ||
953 | + mediaServerService.saveMediaServer(entity); | ||
954 | + } else { | ||
955 | + entity.setId(queryEntity.getId()); | ||
956 | + mediaServerService.updateMediaServer(entity); | ||
957 | + } | ||
771 | }); | 958 | }); |
772 | 959 | ||
773 | - | 960 | + List<MediaServerDTO> allMediaKit = mediaServerService.getAllMediaKit(); |
961 | + Optional.ofNullable(allMediaKit) | ||
962 | + .ifPresent( | ||
963 | + all -> { | ||
964 | + all.forEach( | ||
965 | + dto -> { | ||
966 | + String key = dto.getMediaServerId(); | ||
967 | + ZLMediaKitServerConfig zlMediaKitServerConfig = connectZlmServer(dto); | ||
968 | + if (null != zlMediaKitServerConfig) { | ||
969 | + zlMediaKitServerConfig.setIp(dto.getIp()); | ||
970 | + zlMediaKitServerConfig.setHttpPort(dto.getHttpPort()); | ||
971 | + zlMediaKitServerConfig.setTenantId(dto.getTenantId()); | ||
972 | + // 进行上线操作 | ||
973 | + mediaServerNodeService.zlmServerOnline(zlMediaKitServerConfig); | ||
974 | + } else { | ||
975 | + mediaServerNodeService.zlmServerOffline(key); | ||
976 | + } | ||
977 | + }); | ||
978 | + }); | ||
979 | + TransportApiResponseMsg.Builder responseBuilder = TransportApiResponseMsg.newBuilder(); | ||
980 | + responseBuilder.addGbt28181MediaServerMsg(TransportProtos.Gbt28181MediaServerMsg.newBuilder()); | ||
981 | + return Futures.immediateFuture(responseBuilder.build()); | ||
982 | + } | ||
983 | + | ||
984 | + /** | ||
985 | + * 调用流媒体API接口获取流媒体配置 | ||
986 | + * | ||
987 | + * @param mediaServerItem | ||
988 | + * @return | ||
989 | + */ | ||
990 | + private ZLMediaKitServerConfig connectZlmServer(MediaServerDTO mediaServerItem) { | ||
991 | + log.info("启动流媒体【ZLMedia】验证,流媒体编号【{}】", mediaServerItem.getMediaServerId()); | ||
992 | + JsonNode responseJson = zlMediaKitRestFulUtils.getMediaServerConfig(mediaServerItem); | ||
993 | + if (responseJson == null) { | ||
994 | + log.error( | ||
995 | + "流媒体【{}】服务地址【{}:{}】无法访问", | ||
996 | + mediaServerItem.getMediaServerId(), | ||
997 | + mediaServerItem.getIp(), | ||
998 | + mediaServerItem.getHttpPort()); | ||
999 | + return null; | ||
1000 | + } | ||
1001 | + JsonNode data = responseJson.get(FastIotConstants.ZLMediaBody.DATA); | ||
1002 | + if (data != null && !data.isEmpty()) { | ||
1003 | + log.info( | ||
1004 | + "流媒体【{}:{}】调用成功,响应内容【{}】", mediaServerItem.getIp(), mediaServerItem.getHttpPort(), data); | ||
1005 | + return org.thingsboard.server.common.data.yunteng.utils.JacksonUtil.convertValue( | ||
1006 | + data.get(0), ZLMediaKitServerConfig.class); | ||
1007 | + } else { | ||
1008 | + log.error( | ||
1009 | + "流媒体【{}:{}】调用失败,失败原因【{}】", | ||
1010 | + mediaServerItem.getIp(), | ||
1011 | + mediaServerItem.getHttpPort(), | ||
1012 | + responseJson.get(FastIotConstants.ZLMediaBody.MSG)); | ||
774 | } | 1013 | } |
1014 | + return null; | ||
1015 | + } | ||
775 | } | 1016 | } |
application/src/main/java/org/thingsboard/server/service/yunteng/media/ZLMediaKitStateRunner.java
deleted
100644 → 0
1 | -package org.thingsboard.server.service.yunteng.media; | ||
2 | - | ||
3 | -import com.fasterxml.jackson.databind.JsonNode; | ||
4 | -import lombok.Getter; | ||
5 | -import lombok.extern.slf4j.Slf4j; | ||
6 | -import org.springframework.beans.factory.annotation.Value; | ||
7 | -import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; | ||
8 | -import org.springframework.stereotype.Component; | ||
9 | -import org.thingsboard.server.common.data.id.EntityId; | ||
10 | -import org.thingsboard.server.common.data.yunteng.config.media.ZLMediaKitServerConfig; | ||
11 | -import org.thingsboard.server.common.data.yunteng.constant.FastIotConstants; | ||
12 | -import org.thingsboard.server.common.data.yunteng.dto.sip.MediaServerDTO; | ||
13 | -import org.thingsboard.server.common.data.yunteng.utils.JacksonUtil; | ||
14 | -import org.thingsboard.server.common.data.yunteng.utils.ZLMediaKitRestFulUtils; | ||
15 | -import org.thingsboard.server.dao.util.yunteng.ZLMediaKitTaskUtils; | ||
16 | -import org.thingsboard.server.dao.yunteng.service.media.TkMediaServerNodeService; | ||
17 | -import org.thingsboard.server.dao.yunteng.service.media.TkMediaServerService; | ||
18 | -import org.thingsboard.server.common.data.yunteng.config.media.MediaConfig; | ||
19 | -import org.thingsboard.server.queue.util.TbCoreComponent; | ||
20 | - | ||
21 | -import javax.annotation.PostConstruct; | ||
22 | -import java.util.List; | ||
23 | -import java.util.Map; | ||
24 | -import java.util.Optional; | ||
25 | - | ||
26 | -@Component("ZLMediaKitState") | ||
27 | -@TbCoreComponent | ||
28 | -@ConditionalOnExpression( | ||
29 | - "'${service.type:null}'=='tb-transport' || ('${service.type:null}'=='monolith' && '${transport.api_enabled:true}'=='true' && '${transport.gbt28181.enabled}'=='true')") | ||
30 | -@Slf4j | ||
31 | -public class ZLMediaKitStateRunner { | ||
32 | - private final ZLMediaKitRestFulUtils zlMediaKitRestFulUtils; | ||
33 | - private final TkMediaServerNodeService tkMediaServerNodeService; | ||
34 | - private final TkMediaServerService tkMediaServerService; | ||
35 | - private final MediaConfig mediaConfig; | ||
36 | - private final ZLMediaKitTaskUtils zlMediaKitTaskUtils; | ||
37 | - private final Map<String, Boolean> startGetMedia; | ||
38 | - | ||
39 | - @Value("${media.defaultStateCheckIntervalInSec}") | ||
40 | - @Getter | ||
41 | - private int defaultStateCheckIntervalInSec; | ||
42 | - | ||
43 | - public ZLMediaKitStateRunner( | ||
44 | - ZLMediaKitRestFulUtils zlMediaKitRestFulUtils, | ||
45 | - TkMediaServerNodeService tkMediaServerNodeService, | ||
46 | - TkMediaServerService tkMediaServerService, | ||
47 | - MediaConfig mediaConfig, | ||
48 | - ZLMediaKitTaskUtils zlMediaKitTaskUtils, | ||
49 | - Map<String, Boolean> startGetMedia) { | ||
50 | - this.zlMediaKitRestFulUtils = zlMediaKitRestFulUtils; | ||
51 | - this.tkMediaServerNodeService = tkMediaServerNodeService; | ||
52 | - this.tkMediaServerService = tkMediaServerService; | ||
53 | - this.mediaConfig = mediaConfig; | ||
54 | - this.zlMediaKitTaskUtils = zlMediaKitTaskUtils; | ||
55 | - this.startGetMedia = startGetMedia; | ||
56 | - } | ||
57 | - | ||
58 | - @PostConstruct | ||
59 | - public void init() { | ||
60 | - updateDefaultMediaServer(); | ||
61 | - // 从数据库获取所有的流媒体信息 | ||
62 | - List<MediaServerDTO> dtoList = tkMediaServerService.getAllMediaKit(); | ||
63 | - | ||
64 | - Optional.ofNullable(dtoList).ifPresent( all ->{ | ||
65 | - all.forEach(dto ->{ | ||
66 | - String key = dto.getMediaServerId(); | ||
67 | - startGetMedia.put(key, true); | ||
68 | - zlMediaKitTaskUtils.startCronTask( | ||
69 | - key, | ||
70 | - () -> { | ||
71 | - ZLMediaKitServerConfig zlMediaKitServerConfig = getMediaServerConfig(dto); | ||
72 | - if (null != zlMediaKitServerConfig) { | ||
73 | - startGetMedia.remove(dto.getMediaServerId()); | ||
74 | - zlMediaKitTaskUtils.stop(key); | ||
75 | - zlMediaKitServerConfig.setIp(dto.getIp()); | ||
76 | - zlMediaKitServerConfig.setHttpPort(dto.getHttpPort()); | ||
77 | - zlMediaKitServerConfig.setTenantId(dto.getTenantId()); | ||
78 | - // 进行上线操作 | ||
79 | - tkMediaServerNodeService.zlmServerOnline(zlMediaKitServerConfig); | ||
80 | - } | ||
81 | - }, | ||
82 | - defaultStateCheckIntervalInSec); | ||
83 | - }); | ||
84 | - }); | ||
85 | - } | ||
86 | - | ||
87 | - private void updateDefaultMediaServer() { | ||
88 | - // 默认流媒体服务器 | ||
89 | - MediaServerDTO oldMediaServer = tkMediaServerService.findDefaultMediaServer(); | ||
90 | - MediaServerDTO defaultConfig = mediaConfig.getMediaSerItem(); | ||
91 | - if (oldMediaServer == null) { | ||
92 | - defaultConfig.setTenantId(EntityId.NULL_UUID.toString()); | ||
93 | - }else{ | ||
94 | - defaultConfig.setId(oldMediaServer.getId()); | ||
95 | - defaultConfig.setTenantId(oldMediaServer.getTenantId()); | ||
96 | - } | ||
97 | - tkMediaServerService.saveOrUpdateMediaServer(defaultConfig); | ||
98 | - } | ||
99 | - | ||
100 | - /** | ||
101 | - * 调用流媒体API接口获取流媒体配置 | ||
102 | - * @param mediaServerItem | ||
103 | - * @return | ||
104 | - */ | ||
105 | - private ZLMediaKitServerConfig getMediaServerConfig(MediaServerDTO mediaServerItem) { | ||
106 | - log.error("启动流媒体【ZLMedia】验证,流媒体编号【{}】",mediaServerItem.getMediaServerId()); | ||
107 | - if (startGetMedia == null) { | ||
108 | - return null; | ||
109 | - } | ||
110 | - if (!mediaServerItem.isDefaultServer() | ||
111 | - && tkMediaServerNodeService.getOne(mediaServerItem.getMediaServerId()).isEmpty()) { | ||
112 | - return null; | ||
113 | - } | ||
114 | - if (startGetMedia.get(mediaServerItem.getMediaServerId()) == null | ||
115 | - || !startGetMedia.get(mediaServerItem.getMediaServerId())) { | ||
116 | - return null; | ||
117 | - } | ||
118 | - JsonNode responseJson = zlMediaKitRestFulUtils.getMediaServerConfig(mediaServerItem); | ||
119 | - if(responseJson == null){ | ||
120 | - log.error("流媒体【{}】服务地址【{}:{}】无法访问",mediaServerItem.getMediaServerId(),mediaServerItem.getIp(),mediaServerItem.getHttpPort()); | ||
121 | - return null; | ||
122 | - } | ||
123 | - JsonNode data = responseJson.get(FastIotConstants.ZLMediaBody.DATA); | ||
124 | - if (data != null && !data.isEmpty()) { | ||
125 | - log.error("流媒体【{}:{}】调用成功,响应内容【{}】",mediaServerItem.getIp(),mediaServerItem.getHttpPort(),data); | ||
126 | - return JacksonUtil.convertValue(data.get(0), ZLMediaKitServerConfig.class); | ||
127 | - } | ||
128 | - log.error("流媒体【{}:{}】调用失败,失败原因【{}】",mediaServerItem.getIp(),mediaServerItem.getHttpPort(),responseJson.get(FastIotConstants.ZLMediaBody.MSG)); | ||
129 | - return null; | ||
130 | - } | ||
131 | -} |
@@ -721,6 +721,45 @@ transport: | @@ -721,6 +721,45 @@ transport: | ||
721 | gbt28181: | 721 | gbt28181: |
722 | # Enable/disable gbt28181 transport protocol. | 722 | # Enable/disable gbt28181 transport protocol. |
723 | enabled: "${GBT28181_ENABLED:false}" | 723 | enabled: "${GBT28181_ENABLED:false}" |
724 | + sip: | ||
725 | + # [必须修改] 本机的IP,对应你的网卡,监听什么ip就是使用什么网卡, | ||
726 | + # 如果要监听多张网卡,可以使用逗号分隔多个IP, 例如: 192.168.1.4,10.0.0.4 | ||
727 | + # 如果不明白,就使用0.0.0.0,大部分情况都是可以的 | ||
728 | + # 请不要使用127.0.0.1,任何包括localhost在内的域名都是不可以的。 | ||
729 | + ip: ${GBT28181_SIP_IP:127.0.0.1} | ||
730 | + # [可选] 28181服务监听的端口 | ||
731 | + port: ${GBT28181_SIP_PORT:5060} | ||
732 | + #[可选] | ||
733 | + id: ${GBT28181_SIP_ID:51010700599000000001} | ||
734 | + # 根据国标6.1.2中规定,domain宜采用ID统一编码的前十位编码。国标附录D中定义前8位为中心编码(由省级、市级、区级、基层编号组成,参照GB/T 2260-2007) | ||
735 | + # 后两位为行业编码,定义参照附录D.3 | ||
736 | + # 3701020049标识山东济南历下区 信息行业接入 | ||
737 | + # [可选] | ||
738 | + domain: ${GBT28181_SIP_DOMAIN:5101070059} | ||
739 | + #[可选] | ||
740 | + password: ${GBT28181_SIP_PASSWORD:61332286} | ||
741 | + #zlm 默认服务器配置 | ||
742 | + media: | ||
743 | + id: ${GBT28181_MEDIA_GENERAL_ID:D2okJWKKaQ5bX7Va} | ||
744 | + # [必须修改] zlm服务器的内网IP | ||
745 | + ip: ${GBT28181_MEDIA_IP:127.0.0.1} | ||
746 | + # [必须修改] zlm服务器的http.port | ||
747 | + http-port: ${GBT28181_MEDIA_HTTP_PORT:28080} | ||
748 | + hook-ip: ${GBT28181_MEDIA_HOOK_IP:} | ||
749 | + stream-ip: ${GBT28181_MEDIA_STREAM_IP:} | ||
750 | + # [可选] zlm服务器的hook.admin_params=secret | ||
751 | + secret: ${GBT28181_MEDIA_API_SECRET:QhrTN7k6HcDnt0YyeolwHwiVYDgIHPMZ} | ||
752 | + # 启用多端口模式, 多端口模式使用端口区分每路流,兼容性更好。 单端口使用流的ssrc区分, 点播超时建议使用多端口测试 | ||
753 | + rtp: | ||
754 | + # [可选] 是否启用多端口模式, 开启后会在portRange范围内选择端口用于媒体流传输 | ||
755 | + enable: true | ||
756 | + # [可选] 在此范围内选择端口用于媒体流传输, 必须提前在zlm上配置该属性,不然自动配置此属性可能不成功 | ||
757 | + port-range: ${GBT28181_MEDIA_RTP_PORT_RANGE:30000,30500} # 端口范围 | ||
758 | + # [可选] 国标级联在此范围内选择端口发送媒体流, | ||
759 | + send-port-range: ${GBT28181_MEDIA_RTP_PORT_RANGE:30000,30500} # 端口范围 | ||
760 | + # 录像辅助服务, 部署此服务可以实现zlm录像的管理与下载, 0 表示不使用 | ||
761 | + record-assist-port: 0 | ||
762 | + defaultStateCheckIntervalInSec: "${DEFAULT_STATE_CHECK_INTERVAL:10}" | ||
724 | tcp: | 763 | tcp: |
725 | # Enable/disable tcp transport protocol. | 764 | # Enable/disable tcp transport protocol. |
726 | enabled: "${TCP_ENABLED:true}" | 765 | enabled: "${TCP_ENABLED:true}" |
@@ -1227,43 +1266,6 @@ logging: | @@ -1227,43 +1266,6 @@ logging: | ||
1227 | frp: | 1266 | frp: |
1228 | server: | 1267 | server: |
1229 | address: ${FRP_SERVER_ADDRESS:http://127.0.0.1} | 1268 | address: ${FRP_SERVER_ADDRESS:http://127.0.0.1} |
1230 | -sip: | ||
1231 | - # [必须修改] 本机的IP,对应你的网卡,监听什么ip就是使用什么网卡, | ||
1232 | - # 如果要监听多张网卡,可以使用逗号分隔多个IP, 例如: 192.168.1.4,10.0.0.4 | ||
1233 | - # 如果不明白,就使用0.0.0.0,大部分情况都是可以的 | ||
1234 | - # 请不要使用127.0.0.1,任何包括localhost在内的域名都是不可以的。 | ||
1235 | - ip: ${GBT28181_SIP_IP:127.0.0.1} | ||
1236 | - # [可选] 28181服务监听的端口 | ||
1237 | - port: ${GBT28181_SIP_PORT:5060} | ||
1238 | - #[可选] | ||
1239 | - id: ${GBT28181_SIP_ID:51010700599000000001} | ||
1240 | - # 根据国标6.1.2中规定,domain宜采用ID统一编码的前十位编码。国标附录D中定义前8位为中心编码(由省级、市级、区级、基层编号组成,参照GB/T 2260-2007) | ||
1241 | - # 后两位为行业编码,定义参照附录D.3 | ||
1242 | - # 标识四川成都武侯下区 信息行业接入 | ||
1243 | - # [可选] | ||
1244 | - domain: ${GBT28181_SIP_DOMAIN:5101070059} | ||
1245 | - #[可选] | ||
1246 | - password: ${GBT28181_SIP_PASSWORD:61332286} | ||
1247 | -#zlm 默认服务器配置 | ||
1248 | -media: | ||
1249 | - id: ${GBT28181_MEDIA_GENERAL_ID:D2okJWKKaQ5bX7Va} | ||
1250 | - # [必须修改] zlm服务器的内网IP | ||
1251 | - ip: ${GBT28181_MEDIA_IP:127.0.0.1} | ||
1252 | - # [必须修改] zlm服务器的http.port | ||
1253 | - http-port: ${GBT28181_MEDIA_HTTP_PORT:28080} | ||
1254 | - # [可选] zlm服务器的hook.admin_params=secret | ||
1255 | - secret: ${GBT28181_MEDIA_API_SECRET:QhrTN7k6HcDnt0YyeolwHwiVYDgIHPMZ} | ||
1256 | - # 启用多端口模式, 多端口模式使用端口区分每路流,兼容性更好。 单端口使用流的ssrc区分, 点播超时建议使用多端口测试 | ||
1257 | - rtp: | ||
1258 | - # [可选] 是否启用多端口模式, 开启后会在portRange范围内选择端口用于媒体流传输 | ||
1259 | - enable: true | ||
1260 | - # [可选] 在此范围内选择端口用于媒体流传输, 必须提前在zlm上配置该属性,不然自动配置此属性可能不成功 | ||
1261 | - port-range: ${GBT28181_MEDIA_RTP_PORT_RANGE:30000,30500} # 端口范围 | ||
1262 | - # [可选] 国标级联在此范围内选择端口发送媒体流, | ||
1263 | - send-port-range: ${GBT28181_MEDIA_RTP_PORT_RANGE:30000,30500} # 端口范围 | ||
1264 | - # 录像辅助服务, 部署此服务可以实现zlm录像的管理与下载, 0 表示不使用 | ||
1265 | - record-assist-port: 0 | ||
1266 | - defaultStateCheckIntervalInSec: "${DEFAULT_STATE_CHECK_INTERVAL:10}" | ||
1267 | 1269 | ||
1268 | thingskit: | 1270 | thingskit: |
1269 | release: | 1271 | release: |
@@ -680,6 +680,7 @@ message TransportApiRequestMsg { | @@ -680,6 +680,7 @@ message TransportApiRequestMsg { | ||
680 | //Thingskit function | 680 | //Thingskit function |
681 | ScriptProto script = 14; | 681 | ScriptProto script = 14; |
682 | Gbt28181RequestMsg gbt28181RequestMsg = 15; | 682 | Gbt28181RequestMsg gbt28181RequestMsg = 15; |
683 | + Gbt28181MediaServerMsg gbt28181MediaServerMsg = 16; | ||
683 | } | 684 | } |
684 | 685 | ||
685 | /* Response from ThingsBoard Core Service to Transport Service */ | 686 | /* Response from ThingsBoard Core Service to Transport Service */ |
@@ -698,6 +699,7 @@ message TransportApiResponseMsg { | @@ -698,6 +699,7 @@ message TransportApiResponseMsg { | ||
698 | //Thingskit function | 699 | //Thingskit function |
699 | repeated ScriptProto scriptsResponseMsg = 11; | 700 | repeated ScriptProto scriptsResponseMsg = 11; |
700 | Gbt28181ResponseMsg gbt28181ResponseMsg = 12; | 701 | Gbt28181ResponseMsg gbt28181ResponseMsg = 12; |
702 | + repeated Gbt28181MediaServerMsg gbt28181MediaServerMsg = 13; | ||
701 | } | 703 | } |
702 | 704 | ||
703 | /* Messages that are handled by ThingsBoard Core Service */ | 705 | /* Messages that are handled by ThingsBoard Core Service */ |
@@ -826,5 +828,11 @@ message Gbt28181ResponseMsg{ | @@ -826,5 +828,11 @@ message Gbt28181ResponseMsg{ | ||
826 | int64 entityIdMSB = 11; | 828 | int64 entityIdMSB = 11; |
827 | int64 entityIdLSB = 12; | 829 | int64 entityIdLSB = 12; |
828 | } | 830 | } |
831 | +message Gbt28181MediaServerMsg{ | ||
832 | + bytes profile = 1; | ||
833 | +} | ||
834 | +message Gbt28181MediaResponseMsg{ | ||
835 | + repeated Gbt28181MediaServerMsg profiles = 1; | ||
836 | +} | ||
829 | 837 | ||
830 | 838 |
@@ -3,7 +3,6 @@ package org.thingsboard.server.common.data.yunteng.common.media; | @@ -3,7 +3,6 @@ package org.thingsboard.server.common.data.yunteng.common.media; | ||
3 | import java.util.*; | 3 | import java.util.*; |
4 | import lombok.extern.slf4j.Slf4j; | 4 | import lombok.extern.slf4j.Slf4j; |
5 | import org.springframework.beans.factory.annotation.Autowired; | 5 | import org.springframework.beans.factory.annotation.Autowired; |
6 | -import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; | ||
7 | import org.springframework.stereotype.Component; | 6 | import org.springframework.stereotype.Component; |
8 | import org.thingsboard.server.common.data.yunteng.config.media.UserSetting; | 7 | import org.thingsboard.server.common.data.yunteng.config.media.UserSetting; |
9 | import org.thingsboard.server.common.data.yunteng.constant.FastIotConstants; | 8 | import org.thingsboard.server.common.data.yunteng.constant.FastIotConstants; |
@@ -88,12 +87,14 @@ public class VideoStreamSessionManager { | @@ -88,12 +87,14 @@ public class VideoStreamSessionManager { | ||
88 | public Optional<SsrcTransactionDTO> getSsrcTransaction(String fullKey) { | 87 | public Optional<SsrcTransactionDTO> getSsrcTransaction(String fullKey) { |
89 | return cacheUtils.get(cacheName, fullKey); | 88 | return cacheUtils.get(cacheName, fullKey); |
90 | } | 89 | } |
91 | - public Optional<SsrcTransactionDTO> getSsrcTransaction(String cameraCode, String channelId, String stream) { | ||
92 | - Optional<Set<String>> keys =getSsrcTransactionChannelKey(cameraCode, channelId,stream); | ||
93 | 90 | ||
94 | - if(keys.isPresent()){ | ||
95 | - Optional<String> fullKey =keys.get().stream().findFirst(); | ||
96 | - if(fullKey.isPresent()){ | 91 | + public Optional<SsrcTransactionDTO> getSsrcTransaction( |
92 | + String cameraCode, String channelId, String stream) { | ||
93 | + Optional<Set<String>> keys = getSsrcTransactionChannelKey(cameraCode, channelId, stream); | ||
94 | + | ||
95 | + if (keys.isPresent()) { | ||
96 | + Optional<String> fullKey = keys.get().stream().findFirst(); | ||
97 | + if (fullKey.isPresent()) { | ||
97 | return getSsrcTransaction(fullKey.get()); | 98 | return getSsrcTransaction(fullKey.get()); |
98 | } | 99 | } |
99 | } | 100 | } |
common/data/src/main/java/org/thingsboard/server/common/data/yunteng/config/media/MediaConfig.java
deleted
100644 → 0
1 | -package org.thingsboard.server.common.data.yunteng.config.media; | ||
2 | - | ||
3 | -import lombok.Data; | ||
4 | -import lombok.extern.slf4j.Slf4j; | ||
5 | -import org.springframework.beans.factory.annotation.Value; | ||
6 | -import org.springframework.boot.context.properties.ConfigurationProperties; | ||
7 | -import org.springframework.stereotype.Component; | ||
8 | -import org.springframework.util.ObjectUtils; | ||
9 | -import org.thingsboard.server.common.data.yunteng.dto.sip.MediaServerDTO; | ||
10 | - | ||
11 | -import java.net.InetAddress; | ||
12 | -import java.net.UnknownHostException; | ||
13 | -import java.util.Objects; | ||
14 | -import java.util.regex.Pattern; | ||
15 | - | ||
16 | -/** | ||
17 | - * 配置文件里面的流媒体配置信息 | ||
18 | - */ | ||
19 | -@ConfigurationProperties(prefix = "media") | ||
20 | -@Component | ||
21 | -@Data | ||
22 | -@Slf4j | ||
23 | -public class MediaConfig { | ||
24 | - @Value("${media.id}") | ||
25 | - private String mediaServerId; | ||
26 | - | ||
27 | - @Value("${media.ip}") | ||
28 | - private String ip; | ||
29 | - | ||
30 | - @Value("${media.hook-ip:}") | ||
31 | - private String hookIp; | ||
32 | - | ||
33 | - @Value("${sip.ip}") | ||
34 | - private String sipIp; | ||
35 | - | ||
36 | - @Value("${sip.domain}") | ||
37 | - private String sipDomain; | ||
38 | - | ||
39 | - @Value("${media.sdp-ip:${media.ip}}") | ||
40 | - private String sdpIp; | ||
41 | - | ||
42 | - @Value("${media.stream-ip:${media.ip}}") | ||
43 | - private String streamIp; | ||
44 | - | ||
45 | - @Value("${media.http-port}") | ||
46 | - private Integer httpPort; | ||
47 | - | ||
48 | - @Value("${media.http-ssl-port:0}") | ||
49 | - private Integer httpSslPort = 0; | ||
50 | - | ||
51 | - @Value("${media.rtmp-port:0}") | ||
52 | - private Integer rtmpPort = 0; | ||
53 | - | ||
54 | - @Value("${media.rtmp-ssl-port:0}") | ||
55 | - private Integer rtmpSslPort = 0; | ||
56 | - | ||
57 | - @Value("${media.rtp-proxy-port:0}") | ||
58 | - private Integer rtpProxyPort = 0; | ||
59 | - | ||
60 | - @Value("${media.rtsp-port:0}") | ||
61 | - private Integer rtspPort = 0; | ||
62 | - | ||
63 | - @Value("${media.rtsp-ssl-port:0}") | ||
64 | - private Integer rtspSslPort = 0; | ||
65 | - | ||
66 | - @Value("${media.auto-config:true}") | ||
67 | - private boolean autoConfig = true; | ||
68 | - | ||
69 | - @Value("${media.secret}") | ||
70 | - private String secret; | ||
71 | - | ||
72 | - @Value("${media.rtp.enable}") | ||
73 | - private boolean rtpEnable; | ||
74 | - | ||
75 | - @Value("${media.rtp.port-range}") | ||
76 | - private String rtpPortRange; | ||
77 | - | ||
78 | - @Value("${media.rtp.send-port-range}") | ||
79 | - private String rtpSendPortRange; | ||
80 | - | ||
81 | - @Value("${media.record-assist-port:0}") | ||
82 | - private Integer recordAssistPort = 0; | ||
83 | - private boolean status; | ||
84 | - | ||
85 | - public MediaServerDTO getMediaSerItem() { | ||
86 | - MediaServerDTO mediaServerItem = new MediaServerDTO(); | ||
87 | - mediaServerItem.setMediaServerId(mediaServerId); | ||
88 | - mediaServerItem.setIp(ip); | ||
89 | - mediaServerItem.setDefaultServer(true); | ||
90 | - mediaServerItem.setHookIp(getHookIp()); | ||
91 | - mediaServerItem.setSdpIp(getSdpIp()); | ||
92 | - mediaServerItem.setStreamIp(getStreamIp()); | ||
93 | - mediaServerItem.setHttpPort(httpPort); | ||
94 | - mediaServerItem.setHttpSslPort(httpSslPort); | ||
95 | - mediaServerItem.setRtmpPort(rtmpPort); | ||
96 | - mediaServerItem.setRtmpSslPort(rtmpSslPort); | ||
97 | - mediaServerItem.setRtpProxyPort(getRtpProxyPort()); | ||
98 | - mediaServerItem.setRtspPort(rtspPort); | ||
99 | - mediaServerItem.setRtspSslPort(rtspSslPort); | ||
100 | - mediaServerItem.setAutoConfig(autoConfig); | ||
101 | - mediaServerItem.setSecret(secret); | ||
102 | - mediaServerItem.setRtpEnable(rtpEnable); | ||
103 | - mediaServerItem.setRtpPortRange(rtpPortRange); | ||
104 | - mediaServerItem.setSendRtpPortRange(rtpSendPortRange); | ||
105 | - mediaServerItem.setRecordAssistPort(recordAssistPort); | ||
106 | - mediaServerItem.setHookAliveInterval(30.00f); | ||
107 | - mediaServerItem.setStatus(status); | ||
108 | - return mediaServerItem; | ||
109 | - } | ||
110 | - | ||
111 | - public String getHookIp() { | ||
112 | - if (ObjectUtils.isEmpty(hookIp)) { | ||
113 | - return sipIp.split(",")[0]; | ||
114 | - } else { | ||
115 | - return hookIp; | ||
116 | - } | ||
117 | - } | ||
118 | - | ||
119 | - public String getSipIp() { | ||
120 | - if (sipIp == null) { | ||
121 | - return this.ip; | ||
122 | - } else { | ||
123 | - return sipIp; | ||
124 | - } | ||
125 | - } | ||
126 | - | ||
127 | - public int getRtpProxyPort() { | ||
128 | - return Objects.requireNonNullElse(rtpProxyPort, 0); | ||
129 | - } | ||
130 | - | ||
131 | - public String getSdpIp() { | ||
132 | - if (ObjectUtils.isEmpty(sdpIp)) { | ||
133 | - return ip; | ||
134 | - } else { | ||
135 | - if (isValidIPAddress(sdpIp)) { | ||
136 | - return sdpIp; | ||
137 | - } else { | ||
138 | - // 按照域名解析 | ||
139 | - String hostAddress = null; | ||
140 | - try { | ||
141 | - hostAddress = InetAddress.getByName(sdpIp).getHostAddress(); | ||
142 | - } catch (UnknownHostException e) { | ||
143 | - log.error("[获取SDP IP]: 域名解析失败"); | ||
144 | - } | ||
145 | - return hostAddress; | ||
146 | - } | ||
147 | - } | ||
148 | - } | ||
149 | - | ||
150 | - public String getStreamIp() { | ||
151 | - if (ObjectUtils.isEmpty(streamIp)) { | ||
152 | - return ip; | ||
153 | - } else { | ||
154 | - return streamIp; | ||
155 | - } | ||
156 | - } | ||
157 | - | ||
158 | - private boolean isValidIPAddress(String ipAddress) { | ||
159 | - if ((ipAddress != null) && (!ipAddress.isEmpty())) { | ||
160 | - return Pattern.matches( | ||
161 | - "^([1-9]|[1-9]\\d|1\\d{2}|2[0-4]\\d|25[0-5])(\\.(\\d|[1-9]\\d|1\\d{2}|2[0-4]\\d|25[0-5])){3}$", | ||
162 | - ipAddress); | ||
163 | - } | ||
164 | - return false; | ||
165 | - } | ||
166 | -} |
1 | package org.thingsboard.server.common.data.yunteng.config.media; | 1 | package org.thingsboard.server.common.data.yunteng.config.media; |
2 | 2 | ||
3 | import lombok.Data; | 3 | import lombok.Data; |
4 | -import org.springframework.boot.context.properties.ConfigurationProperties; | ||
5 | import org.springframework.stereotype.Component; | 4 | import org.springframework.stereotype.Component; |
6 | 5 | ||
7 | -@ConfigurationProperties(prefix = "user-settings") | ||
8 | @Component | 6 | @Component |
9 | @Data | 7 | @Data |
10 | public class UserSetting { | 8 | public class UserSetting { |
11 | - private String serverId = "000000"; | ||
12 | - private Boolean seniorSdp = Boolean.FALSE; | ||
13 | - private Boolean pushAuthority = Boolean.TRUE; | ||
14 | - private Boolean recordSip = Boolean.TRUE; | ||
15 | - private Boolean recordPushLive = Boolean.TRUE; | ||
16 | - private String recordPath = null; | ||
17 | - private Boolean streamOnDemand = Boolean.TRUE; | ||
18 | - private Boolean sipUseSourceIpAsRemoteAddress = Boolean.FALSE; | ||
19 | - private Integer playTimeout = 30000; | 9 | + private String serverId = "000000"; |
10 | + private Boolean seniorSdp = Boolean.FALSE; | ||
11 | + private Boolean pushAuthority = Boolean.TRUE; | ||
12 | + private Boolean recordSip = Boolean.TRUE; | ||
13 | + private Boolean recordPushLive = Boolean.TRUE; | ||
14 | + private String recordPath = null; | ||
15 | + private Boolean streamOnDemand = Boolean.TRUE; | ||
16 | + private Boolean sipUseSourceIpAsRemoteAddress = Boolean.FALSE; | ||
17 | + private Integer playTimeout = 30000; | ||
20 | } | 18 | } |
@@ -3,8 +3,6 @@ package org.thingsboard.server.common.data.yunteng.dto.sip; | @@ -3,8 +3,6 @@ package org.thingsboard.server.common.data.yunteng.dto.sip; | ||
3 | import io.swagger.annotations.ApiModelProperty; | 3 | import io.swagger.annotations.ApiModelProperty; |
4 | import lombok.Data; | 4 | import lombok.Data; |
5 | import lombok.EqualsAndHashCode; | 5 | import lombok.EqualsAndHashCode; |
6 | -import org.springframework.util.ObjectUtils; | ||
7 | -import org.thingsboard.server.common.data.yunteng.config.media.ZLMediaKitServerConfig; | ||
8 | import org.thingsboard.server.common.data.yunteng.dto.TenantDTO; | 6 | import org.thingsboard.server.common.data.yunteng.dto.TenantDTO; |
9 | 7 | ||
10 | @EqualsAndHashCode(callSuper = true) | 8 | @EqualsAndHashCode(callSuper = true) |
@@ -63,11 +61,11 @@ public class MediaServerDTO extends TenantDTO { | @@ -63,11 +61,11 @@ public class MediaServerDTO extends TenantDTO { | ||
63 | @ApiModelProperty(value = "流媒体服务器的状态") | 61 | @ApiModelProperty(value = "流媒体服务器的状态") |
64 | private boolean status; | 62 | private boolean status; |
65 | 63 | ||
66 | - @ApiModelProperty(value = "多端口RTP收流端口范围") | 64 | + @ApiModelProperty(value = "RTP收流端口范围") |
67 | private String rtpPortRange; | 65 | private String rtpPortRange; |
68 | 66 | ||
69 | - @ApiModelProperty(value = "RTP发流端口范围") | ||
70 | - private String sendRtpPortRange; | 67 | + @ApiModelProperty(value = "RTP推流端口范围") |
68 | + private String rtpSendPortRange; | ||
71 | 69 | ||
72 | @ApiModelProperty(value = "assist服务端口") | 70 | @ApiModelProperty(value = "assist服务端口") |
73 | private Integer recordAssistPort; | 71 | private Integer recordAssistPort; |
@@ -81,33 +79,7 @@ public class MediaServerDTO extends TenantDTO { | @@ -81,33 +79,7 @@ public class MediaServerDTO extends TenantDTO { | ||
81 | @ApiModelProperty(value = "当前使用到的端口") | 79 | @ApiModelProperty(value = "当前使用到的端口") |
82 | private Integer currentPort; | 80 | private Integer currentPort; |
83 | 81 | ||
84 | - public MediaServerDTO(){ | ||
85 | - | ||
86 | - } | ||
87 | - public MediaServerDTO(ZLMediaKitServerConfig zlmServerConfig, String sipIp) { | ||
88 | - setId(zlmServerConfig.getGeneralMediaServerId()); | ||
89 | - ip = zlmServerConfig.getIp(); | ||
90 | - hookIp = ObjectUtils.isEmpty(zlmServerConfig.getHookIp()) ? sipIp : zlmServerConfig.getHookIp(); | ||
91 | - sdpIp = | ||
92 | - ObjectUtils.isEmpty(zlmServerConfig.getSdpIp()) | ||
93 | - ? zlmServerConfig.getIp() | ||
94 | - : zlmServerConfig.getSdpIp(); | ||
95 | - streamIp = | ||
96 | - ObjectUtils.isEmpty(zlmServerConfig.getStreamIp()) | ||
97 | - ? zlmServerConfig.getIp() | ||
98 | - : zlmServerConfig.getStreamIp(); | ||
99 | - httpPort = zlmServerConfig.getHttpPort(); | ||
100 | - httpSslPort = zlmServerConfig.getHttpSslPort(); | ||
101 | - rtmpPort = zlmServerConfig.getRtmpPort(); | ||
102 | - rtmpSslPort = zlmServerConfig.getRtmpSslPort(); | ||
103 | - rtpProxyPort = zlmServerConfig.getRtpProxyPort(); | ||
104 | - rtspPort = zlmServerConfig.getRtspPort(); | ||
105 | - rtspSslPort = zlmServerConfig.getRtspSslPort(); | ||
106 | - autoConfig = true; // 默认值true; | ||
107 | - secret = zlmServerConfig.getApiSecret(); | ||
108 | - hookAliveInterval = zlmServerConfig.getHookAliveInterval(); | ||
109 | - rtpEnable = false; // 默认使用单端口;直到用户自己设置开启多端口 | ||
110 | - rtpPortRange = zlmServerConfig.getPortRange().replace("_", ","); // 默认使用30000,30500作为级联时发送流的端口号 | ||
111 | - recordAssistPort = 0; // 默认关闭 | ||
112 | - } | 82 | + private String hookEnable; |
83 | + | ||
84 | + public MediaServerDTO() {} | ||
113 | } | 85 | } |
1 | package org.thingsboard.server.common.data.yunteng.dto.sip; | 1 | package org.thingsboard.server.common.data.yunteng.dto.sip; |
2 | 2 | ||
3 | import io.swagger.annotations.ApiModelProperty; | 3 | import io.swagger.annotations.ApiModelProperty; |
4 | +import java.io.Serializable; | ||
4 | import lombok.Data; | 5 | import lombok.Data; |
5 | import org.thingsboard.server.common.data.yunteng.constant.FastIotConstants; | 6 | import org.thingsboard.server.common.data.yunteng.constant.FastIotConstants; |
6 | 7 | ||
7 | -import java.io.Serializable; | ||
8 | - | ||
9 | @Data | 8 | @Data |
10 | public class SipDeviceDTO implements Serializable { | 9 | public class SipDeviceDTO implements Serializable { |
11 | @ApiModelProperty(value = "设备国标编号") | 10 | @ApiModelProperty(value = "设备国标编号") |
@@ -37,6 +36,7 @@ public class SipDeviceDTO implements Serializable { | @@ -37,6 +36,7 @@ public class SipDeviceDTO implements Serializable { | ||
37 | 36 | ||
38 | @ApiModelProperty(value = "是否开启ssrc校验,默认关闭,开启可以防止串流") | 37 | @ApiModelProperty(value = "是否开启ssrc校验,默认关闭,开启可以防止串流") |
39 | private boolean ssrcCheck = true; | 38 | private boolean ssrcCheck = true; |
39 | + | ||
40 | @ApiModelProperty(value = "生产厂商") | 40 | @ApiModelProperty(value = "生产厂商") |
41 | private String manufacturer; | 41 | private String manufacturer; |
42 | 42 | ||
@@ -48,12 +48,13 @@ public class SipDeviceDTO implements Serializable { | @@ -48,12 +48,13 @@ public class SipDeviceDTO implements Serializable { | ||
48 | 48 | ||
49 | @ApiModelProperty(value = "固件版本") | 49 | @ApiModelProperty(value = "固件版本") |
50 | private String firmware; | 50 | private String firmware; |
51 | + | ||
51 | public Integer getStreamModeForParam() { | 52 | public Integer getStreamModeForParam() { |
52 | if (FastIotConstants.StreamMode.UDP.equalsIgnoreCase(streamMode)) { | 53 | if (FastIotConstants.StreamMode.UDP.equalsIgnoreCase(streamMode)) { |
53 | return 0; | 54 | return 0; |
54 | - }else if (FastIotConstants.StreamMode.TCP_PASSIVE.equalsIgnoreCase(streamMode)) { | 55 | + } else if (FastIotConstants.StreamMode.TCP_PASSIVE.equalsIgnoreCase(streamMode)) { |
55 | return 1; | 56 | return 1; |
56 | - }else if (FastIotConstants.StreamMode.TCP_ACTIVE.equalsIgnoreCase(streamMode)) { | 57 | + } else if (FastIotConstants.StreamMode.TCP_ACTIVE.equalsIgnoreCase(streamMode)) { |
57 | return 2; | 58 | return 2; |
58 | } | 59 | } |
59 | return 0; | 60 | return 0; |
@@ -2,6 +2,8 @@ package org.thingsboard.server.common.data.yunteng.utils; | @@ -2,6 +2,8 @@ package org.thingsboard.server.common.data.yunteng.utils; | ||
2 | 2 | ||
3 | import lombok.extern.slf4j.Slf4j; | 3 | import lombok.extern.slf4j.Slf4j; |
4 | 4 | ||
5 | +import java.util.regex.Pattern; | ||
6 | + | ||
5 | /** | 7 | /** |
6 | * 数值格式相关工具类 | 8 | * 数值格式相关工具类 |
7 | */ | 9 | */ |
@@ -35,4 +37,18 @@ public class DataUtils { | @@ -35,4 +37,18 @@ public class DataUtils { | ||
35 | return false; | 37 | return false; |
36 | } | 38 | } |
37 | } | 39 | } |
40 | + | ||
41 | + /** | ||
42 | + * 是否有效的IP地址 | ||
43 | + * @param ipAddress IP地址字符串 | ||
44 | + * @return | ||
45 | + */ | ||
46 | + public static boolean isIPAddress(String ipAddress) { | ||
47 | + if ((ipAddress != null) && (!ipAddress.isEmpty())) { | ||
48 | + return Pattern.matches( | ||
49 | + "^([1-9]|[1-9]\\d|1\\d{2}|2[0-4]\\d|25[0-5])(\\.(\\d|[1-9]\\d|1\\d{2}|2[0-4]\\d|25[0-5])){3}$", | ||
50 | + ipAddress); | ||
51 | + } | ||
52 | + return false; | ||
53 | + } | ||
38 | } | 54 | } |
common/transport/gbt28181/src/main/java/org/thingsboard/server/transport/adaptors/GbtTransportAdaptor.java
deleted
100644 → 0
1 | -/** | ||
2 | - * Copyright © 2016-2022 The Thingsboard Authors | ||
3 | - * <p> | ||
4 | - * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | - * you may not use this file except in compliance with the License. | ||
6 | - * You may obtain a copy of the License at | ||
7 | - * <p> | ||
8 | - * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | - * <p> | ||
10 | - * Unless required by applicable law or agreed to in writing, software | ||
11 | - * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | - * See the License for the specific language governing permissions and | ||
14 | - * limitations under the License. | ||
15 | - */ | ||
16 | -package org.thingsboard.server.transport.adaptors; | ||
17 | - | ||
18 | -import io.netty.buffer.ByteBuf; | ||
19 | -import io.netty.handler.codec.mqtt.MqttPublishMessage; | ||
20 | -import java.nio.charset.Charset; | ||
21 | -import java.nio.charset.StandardCharsets; | ||
22 | -import java.util.Optional; | ||
23 | -import java.util.concurrent.ExecutionException; | ||
24 | -import org.thingsboard.server.common.data.ota.OtaPackageType; | ||
25 | -import org.thingsboard.server.common.transport.adaptor.AdaptorException; | ||
26 | -import org.thingsboard.server.gen.transport.TransportProtos.*; | ||
27 | -import org.thingsboard.server.transport.session.GbtDeviceSessionCtx; | ||
28 | - | ||
29 | -/** | ||
30 | - * 将收到的数据流转换为接口需要的数据格式 | ||
31 | - * 1、基于解析脚本将ByteBuf转JSON对象。 | ||
32 | - * 2、将JSON对象转PROTOBUF对象。 | ||
33 | - */ | ||
34 | -public interface GbtTransportAdaptor { | ||
35 | - static char[] HEX_VOCABLE = {'0', '1', '2', '3', '4', '5', '6', '7', | ||
36 | - '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}; | ||
37 | - static final Charset UTF8 = StandardCharsets.UTF_8; | ||
38 | - | ||
39 | - | ||
40 | - /** | ||
41 | - * 设备数据转遥测数据 | ||
42 | - * | ||
43 | - * @param ctx | ||
44 | - * @param inbound 设备上报的数据字符串 | ||
45 | - * @return 平台需要的遥测数据 | ||
46 | - * @throws AdaptorException | ||
47 | - */ | ||
48 | - PostTelemetryMsg convertToPostTelemetry(GbtDeviceSessionCtx ctx, String inbound) throws AdaptorException; | ||
49 | - | ||
50 | - | ||
51 | - PostAttributeMsg convertToPostAttributes(GbtDeviceSessionCtx ctx, String inbound) throws AdaptorException; | ||
52 | - | ||
53 | - GetAttributeRequestMsg convertToGetAttributes(GbtDeviceSessionCtx ctx, MqttPublishMessage inbound, String topicBase) throws AdaptorException; | ||
54 | - | ||
55 | - ToDeviceRpcResponseMsg convertToDeviceRpcResponse(GbtDeviceSessionCtx ctx, String inbound) throws AdaptorException; | ||
56 | - | ||
57 | - ToServerRpcRequestMsg convertToServerRpcRequest(GbtDeviceSessionCtx ctx, MqttPublishMessage mqttMsg, String topicBase) throws AdaptorException; | ||
58 | - | ||
59 | - | ||
60 | - | ||
61 | - Optional<String> convertToPublish(GbtDeviceSessionCtx ctx, GetAttributeResponseMsg responseMsg, String topicBase) throws AdaptorException; | ||
62 | - | ||
63 | - | ||
64 | - Optional<String> convertToPublish(GbtDeviceSessionCtx ctx, AttributeUpdateNotificationMsg notificationMsg, String topic) throws AdaptorException; | ||
65 | - | ||
66 | - | ||
67 | - Optional<String> convertToPublish(GbtDeviceSessionCtx ctx, ToDeviceRpcRequestMsg rpcRequest) throws ExecutionException, InterruptedException; | ||
68 | - | ||
69 | - Optional<String> convertToPublish(GbtDeviceSessionCtx ctx, ToServerRpcResponseMsg rpcResponse, String topicBase) throws AdaptorException; | ||
70 | - | ||
71 | - ProvisionDeviceRequestMsg convertToProvisionRequestMsg(GbtDeviceSessionCtx ctx, MqttPublishMessage inbound) throws AdaptorException; | ||
72 | - | ||
73 | - Optional<String> convertToPublish(GbtDeviceSessionCtx ctx, ProvisionDeviceResponseMsg provisionResponse) throws AdaptorException; | ||
74 | - | ||
75 | - Optional<String> convertToPublish(GbtDeviceSessionCtx ctx, byte[] firmwareChunk, String requestId, int chunk, OtaPackageType firmwareType) throws AdaptorException; | ||
76 | - | ||
77 | - public static byte[] toBytes(ByteBuf inbound) { | ||
78 | - byte[] bytes = new byte[inbound.readableBytes()]; | ||
79 | - int readerIndex = inbound.readerIndex(); | ||
80 | - inbound.getBytes(readerIndex, bytes); | ||
81 | - return bytes; | ||
82 | - } | ||
83 | - | ||
84 | - public static String bytesToHex(byte[] bs) { | ||
85 | - StringBuilder sb = new StringBuilder(); | ||
86 | - for (byte b : bs) { | ||
87 | - int high = (b >> 4) & 0x0f; | ||
88 | - int low = b & 0x0f; | ||
89 | - sb.append(HEX_VOCABLE[high]); | ||
90 | - sb.append(HEX_VOCABLE[low]); | ||
91 | - } | ||
92 | - return sb.toString(); | ||
93 | - } | ||
94 | -} |
common/transport/gbt28181/src/main/java/org/thingsboard/server/transport/adaptors/JsonGbtAdaptor.java
deleted
100644 → 0
1 | -/** | ||
2 | - * Copyright © 2016-2022 The Thingsboard Authors | ||
3 | - * <p> | ||
4 | - * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | - * you may not use this file except in compliance with the License. | ||
6 | - * You may obtain a copy of the License at | ||
7 | - * <p> | ||
8 | - * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | - * <p> | ||
10 | - * Unless required by applicable law or agreed to in writing, software | ||
11 | - * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | - * See the License for the specific language governing permissions and | ||
14 | - * limitations under the License. | ||
15 | - */ | ||
16 | -package org.thingsboard.server.transport.adaptors; | ||
17 | - | ||
18 | -import com.google.gson.JsonElement; | ||
19 | -import com.google.gson.JsonObject; | ||
20 | -import com.google.gson.JsonParser; | ||
21 | -import com.google.gson.JsonSyntaxException; | ||
22 | -import io.netty.buffer.ByteBuf; | ||
23 | -import io.netty.handler.codec.mqtt.MqttPublishMessage; | ||
24 | -import java.nio.charset.Charset; | ||
25 | -import java.nio.charset.StandardCharsets; | ||
26 | -import java.util.*; | ||
27 | -import java.util.concurrent.ExecutionException; | ||
28 | -import lombok.extern.slf4j.Slf4j; | ||
29 | -import org.springframework.stereotype.Component; | ||
30 | -import org.springframework.util.StringUtils; | ||
31 | -import org.thingsboard.server.common.data.ota.OtaPackageType; | ||
32 | -import org.thingsboard.server.common.transport.adaptor.AdaptorException; | ||
33 | -import org.thingsboard.server.common.transport.adaptor.JsonConverter; | ||
34 | -import org.thingsboard.server.gen.transport.TransportProtos; | ||
35 | -import org.thingsboard.server.transport.session.GbtDeviceSessionCtx; | ||
36 | - | ||
37 | -/** | ||
38 | - * @author Andrew Shvayka | ||
39 | - */ | ||
40 | -@Component | ||
41 | -@Slf4j | ||
42 | -public class JsonGbtAdaptor implements GbtTransportAdaptor { | ||
43 | - | ||
44 | - protected static final Charset UTF8 = StandardCharsets.UTF_8; | ||
45 | - private static final JsonParser parser = new JsonParser(); | ||
46 | - | ||
47 | - | ||
48 | - @Override | ||
49 | - public TransportProtos.PostTelemetryMsg convertToPostTelemetry(GbtDeviceSessionCtx ctx, String payload) throws AdaptorException { | ||
50 | - try { | ||
51 | - return JsonConverter.convertToTelemetryProto(new JsonParser().parse(payload)); | ||
52 | - } catch (IllegalStateException | JsonSyntaxException ex) { | ||
53 | - log.debug("Failed to decode post telemetry request", ex); | ||
54 | - throw new AdaptorException(ex); | ||
55 | - } | ||
56 | - } | ||
57 | - | ||
58 | - | ||
59 | - @Override | ||
60 | - public TransportProtos.PostAttributeMsg convertToPostAttributes(GbtDeviceSessionCtx ctx, String payload) throws AdaptorException { | ||
61 | - try { | ||
62 | - return JsonConverter.convertToAttributesProto(new JsonParser().parse(payload)); | ||
63 | - } catch (IllegalStateException | JsonSyntaxException ex) { | ||
64 | - log.debug("Failed to decode post attributes request", ex); | ||
65 | - throw new AdaptorException(ex); | ||
66 | - } | ||
67 | - } | ||
68 | - | ||
69 | - | ||
70 | - @Override | ||
71 | - public TransportProtos.ProvisionDeviceRequestMsg convertToProvisionRequestMsg(GbtDeviceSessionCtx ctx, MqttPublishMessage inbound) throws AdaptorException { | ||
72 | - String payload = validatePayload(ctx.getSessionId(), inbound.payload(), false); | ||
73 | - try { | ||
74 | - return JsonConverter.convertToProvisionRequestMsg(payload); | ||
75 | - } catch (IllegalStateException | JsonSyntaxException ex) { | ||
76 | - throw new AdaptorException(ex); | ||
77 | - } | ||
78 | - } | ||
79 | - | ||
80 | - @Override | ||
81 | - public TransportProtos.GetAttributeRequestMsg convertToGetAttributes(GbtDeviceSessionCtx ctx, MqttPublishMessage inbound, String topicBase) throws AdaptorException { | ||
82 | - return processGetAttributeRequestMsg(inbound, topicBase); | ||
83 | - } | ||
84 | - | ||
85 | - @Override | ||
86 | - public TransportProtos.ToDeviceRpcResponseMsg convertToDeviceRpcResponse(GbtDeviceSessionCtx ctx, String inbound) throws AdaptorException { | ||
87 | - try { | ||
88 | -// Integer requestId = ctx.getRpcRequesting(inbound.getIdentifier()); | ||
89 | -// if(requestId != null){ | ||
90 | -// String payload = JacksonUtil.toString(inbound.getDatas()); | ||
91 | -// return TransportProtos.ToDeviceRpcResponseMsg.newBuilder().setRequestId(requestId).setPayload(payload).build(); | ||
92 | -// } | ||
93 | - return null; | ||
94 | - } catch (RuntimeException e) { | ||
95 | - log.debug("Failed to decode rpc response", e); | ||
96 | - throw new AdaptorException(e); | ||
97 | - } | ||
98 | - } | ||
99 | - | ||
100 | - @Override | ||
101 | - public TransportProtos.ToServerRpcRequestMsg convertToServerRpcRequest(GbtDeviceSessionCtx ctx, MqttPublishMessage inbound, String topicBase) throws AdaptorException { | ||
102 | - return processToServerRpcRequestMsg(ctx, inbound, topicBase); | ||
103 | - } | ||
104 | - | ||
105 | - @Override | ||
106 | - public Optional<String> convertToPublish(GbtDeviceSessionCtx ctx, TransportProtos.GetAttributeResponseMsg responseMsg, String topicBase) throws AdaptorException { | ||
107 | - return processConvertFromAttributeResponseMsg(ctx, responseMsg, topicBase); | ||
108 | - } | ||
109 | - | ||
110 | - | ||
111 | - @Override | ||
112 | - public Optional<String> convertToPublish(GbtDeviceSessionCtx ctx, TransportProtos.AttributeUpdateNotificationMsg notificationMsg, String topic) { | ||
113 | - return Optional.of(createTcpMessage(ctx, JsonConverter.toJson(notificationMsg))); | ||
114 | - } | ||
115 | - | ||
116 | - | ||
117 | - @Override | ||
118 | - public Optional<String> convertToPublish(GbtDeviceSessionCtx ctx, TransportProtos.ToDeviceRpcRequestMsg rpcRequest) throws ExecutionException, InterruptedException { | ||
119 | - String payload = rpcRequest.getParams();//methodThingskit | ||
120 | - | ||
121 | -// TcpDownEntry data = new TcpDownEntry(); | ||
122 | -// data.setDatas(payload); | ||
123 | -// data.setIdentifier(payload); | ||
124 | - return Optional.of("data"); | ||
125 | - } | ||
126 | - | ||
127 | - | ||
128 | - | ||
129 | - @Override | ||
130 | - public Optional<String> convertToPublish(GbtDeviceSessionCtx ctx, TransportProtos.ToServerRpcResponseMsg rpcResponse, String topicBase) { | ||
131 | - return Optional.of(createTcpMessage(ctx, JsonConverter.toJson(rpcResponse))); | ||
132 | - } | ||
133 | - | ||
134 | - @Override | ||
135 | - public Optional<String> convertToPublish(GbtDeviceSessionCtx ctx, TransportProtos.ProvisionDeviceResponseMsg provisionResponse) { | ||
136 | - return Optional.of(createTcpMessage(ctx, JsonConverter.toJson(provisionResponse))); | ||
137 | - } | ||
138 | - | ||
139 | - @Override | ||
140 | - public Optional<String> convertToPublish(GbtDeviceSessionCtx ctx, byte[] firmwareChunk, String requestId, int chunk, OtaPackageType firmwareType) { | ||
141 | - return Optional.of(null); | ||
142 | - } | ||
143 | - | ||
144 | - public static JsonElement validateJsonPayload(UUID sessionId, ByteBuf payloadData) throws AdaptorException { | ||
145 | - String payload = validatePayload(sessionId, payloadData, false); | ||
146 | - try { | ||
147 | - return new JsonParser().parse(payload); | ||
148 | - } catch (JsonSyntaxException ex) { | ||
149 | - log.debug("Payload is in incorrect format: {}", payload); | ||
150 | - throw new AdaptorException(ex); | ||
151 | - } | ||
152 | - } | ||
153 | - | ||
154 | - private TransportProtos.GetAttributeRequestMsg processGetAttributeRequestMsg(MqttPublishMessage inbound, String topicBase) throws AdaptorException { | ||
155 | - String topicName = inbound.variableHeader().topicName(); | ||
156 | - try { | ||
157 | - TransportProtos.GetAttributeRequestMsg.Builder result = TransportProtos.GetAttributeRequestMsg.newBuilder(); | ||
158 | - result.setRequestId(getRequestId(topicName, topicBase)); | ||
159 | - String payload = inbound.payload().toString(UTF8); | ||
160 | - JsonElement requestBody = new JsonParser().parse(payload); | ||
161 | - Set<String> clientKeys = toStringSet(requestBody, "clientKeys"); | ||
162 | - Set<String> sharedKeys = toStringSet(requestBody, "sharedKeys"); | ||
163 | - if (clientKeys != null) { | ||
164 | - result.addAllClientAttributeNames(clientKeys); | ||
165 | - } | ||
166 | - if (sharedKeys != null) { | ||
167 | - result.addAllSharedAttributeNames(sharedKeys); | ||
168 | - } | ||
169 | - return result.build(); | ||
170 | - } catch (RuntimeException e) { | ||
171 | - log.debug("Failed to decode get attributes request", e); | ||
172 | - throw new AdaptorException(e); | ||
173 | - } | ||
174 | - } | ||
175 | - | ||
176 | - | ||
177 | - private TransportProtos.ToServerRpcRequestMsg processToServerRpcRequestMsg(GbtDeviceSessionCtx ctx, MqttPublishMessage inbound, String topicBase) throws AdaptorException { | ||
178 | - String topicName = inbound.variableHeader().topicName(); | ||
179 | - String payload = validatePayload(ctx.getSessionId(), inbound.payload(), false); | ||
180 | - try { | ||
181 | - int requestId = getRequestId(topicName, topicBase); | ||
182 | - return JsonConverter.convertToServerRpcRequest(new JsonParser().parse(payload), requestId); | ||
183 | - } catch (IllegalStateException | JsonSyntaxException ex) { | ||
184 | - log.debug("Failed to decode to server rpc request", ex); | ||
185 | - throw new AdaptorException(ex); | ||
186 | - } | ||
187 | - } | ||
188 | - | ||
189 | - private Optional<String> processConvertFromAttributeResponseMsg(GbtDeviceSessionCtx ctx, TransportProtos.GetAttributeResponseMsg responseMsg, String topicBase) throws AdaptorException { | ||
190 | - if (!StringUtils.isEmpty(responseMsg.getError())) { | ||
191 | - throw new AdaptorException(responseMsg.getError()); | ||
192 | - } else { | ||
193 | - int requestId = responseMsg.getRequestId(); | ||
194 | - if (requestId >= 0) { | ||
195 | - return Optional.of(createTcpMessage(ctx, | ||
196 | - JsonConverter.toJson(responseMsg))); | ||
197 | - } | ||
198 | - return Optional.empty(); | ||
199 | - } | ||
200 | - } | ||
201 | - | ||
202 | - private Optional<String> processConvertFromGatewayAttributeResponseMsg(GbtDeviceSessionCtx ctx, String deviceName, TransportProtos.GetAttributeResponseMsg responseMsg) throws AdaptorException { | ||
203 | - if (!StringUtils.isEmpty(responseMsg.getError())) { | ||
204 | - throw new AdaptorException(responseMsg.getError()); | ||
205 | - } else { | ||
206 | - JsonObject result = JsonConverter.getJsonObjectForGateway(deviceName, responseMsg); | ||
207 | - return Optional.of(createTcpMessage(ctx, result)); | ||
208 | - } | ||
209 | - } | ||
210 | - | ||
211 | - | ||
212 | - private Set<String> toStringSet(JsonElement requestBody, String name) { | ||
213 | - JsonElement element = requestBody.getAsJsonObject().get(name); | ||
214 | - if (element != null) { | ||
215 | - return new HashSet<>(Arrays.asList(element.getAsString().split(","))); | ||
216 | - } else { | ||
217 | - return null; | ||
218 | - } | ||
219 | - } | ||
220 | - | ||
221 | - private static String validatePayload(UUID sessionId, ByteBuf payloadData, boolean isEmptyPayloadAllowed) throws AdaptorException { | ||
222 | - String payload = payloadData.toString(UTF8); | ||
223 | - if (payload == null) { | ||
224 | - log.debug("[{}] Payload is empty!", sessionId); | ||
225 | - if (!isEmptyPayloadAllowed) { | ||
226 | - throw new AdaptorException(new IllegalArgumentException("Payload is empty!")); | ||
227 | - } | ||
228 | - } | ||
229 | - return payload; | ||
230 | - } | ||
231 | - | ||
232 | - | ||
233 | - private int getRequestId(String topicName, String topic) { | ||
234 | - return Integer.parseInt(topicName.substring(topic.length())); | ||
235 | - } | ||
236 | - | ||
237 | - | ||
238 | - protected String createTcpMessage(GbtDeviceSessionCtx ctx, JsonElement json) { | ||
239 | -// TCPMessage msg = new TCPMessage(MqttMessageType.PUBLISH,); | ||
240 | -//// new MqttFixedHeader(MqttMessageType.PUBLISH, false, ctx.getQoSForTopic(topic), false, 0); | ||
241 | -// MqttPublishVariableHeader header = new MqttPublishVariableHeader(topic, ctx.nextMsgId()); | ||
242 | -// ByteBuf payload = ALLOCATOR.buffer(); | ||
243 | -// payload.writeBytes(json.toString().getBytes(UTF8)); | ||
244 | -// return new MqttPublishMessage(mqttFixedHeader, header, payload); | ||
245 | - return null; | ||
246 | - } | ||
247 | - | ||
248 | - | ||
249 | -} |
@@ -10,13 +10,11 @@ import javax.sip.address.AddressFactory; | @@ -10,13 +10,11 @@ import javax.sip.address.AddressFactory; | ||
10 | import javax.sip.address.SipURI; | 10 | import javax.sip.address.SipURI; |
11 | import javax.sip.header.*; | 11 | import javax.sip.header.*; |
12 | import org.springframework.beans.factory.annotation.Autowired; | 12 | import org.springframework.beans.factory.annotation.Autowired; |
13 | -import org.springframework.stereotype.Component; | ||
14 | -import org.thingsboard.server.common.data.yunteng.config.media.SipConfig; | ||
15 | -import org.thingsboard.server.common.data.yunteng.config.media.ThingsKitVersionConfig; | ||
16 | -import org.thingsboard.server.transport.gbt28181.SipLayer; | 13 | +import org.thingsboard.server.transport.config.SipConfig; |
14 | +import org.thingsboard.server.transport.config.ThingsKitVersionConfig; | ||
15 | +import org.thingsboard.server.transport.gbt28181.sip.SipTransportService; | ||
17 | 16 | ||
18 | -@Component | ||
19 | -public class AbstractSIPRequestProcess { | 17 | +public abstract class AbstractSIPRequestProcess { |
20 | @Autowired private SipConfig sipConfig; | 18 | @Autowired private SipConfig sipConfig; |
21 | @Autowired protected ThingsKitVersionConfig thingsKitVersionConfig; | 19 | @Autowired protected ThingsKitVersionConfig thingsKitVersionConfig; |
22 | 20 | ||
@@ -41,7 +39,7 @@ public class AbstractSIPRequestProcess { | @@ -41,7 +39,7 @@ public class AbstractSIPRequestProcess { | ||
41 | ViaHeader viaHeader = | 39 | ViaHeader viaHeader = |
42 | sipFactory | 40 | sipFactory |
43 | .createHeaderFactory() | 41 | .createHeaderFactory() |
44 | - .createViaHeader(SipLayer.getLocalIp(localIp), sipConfig.getPort(), transport, viaTag); | 42 | + .createViaHeader(SipTransportService.getLocalIp(localIp), sipConfig.getPort(), transport, viaTag); |
45 | viaHeader.setRPort(); | 43 | viaHeader.setRPort(); |
46 | viaHeaders.add(viaHeader); | 44 | viaHeaders.add(viaHeader); |
47 | return viaHeaders; | 45 | return viaHeaders; |
@@ -78,7 +76,7 @@ public class AbstractSIPRequestProcess { | @@ -78,7 +76,7 @@ public class AbstractSIPRequestProcess { | ||
78 | throws PeerUnavailableException, ParseException { | 76 | throws PeerUnavailableException, ParseException { |
79 | SipURI sipUri = | 77 | SipURI sipUri = |
80 | buildRequestLineSipUri( | 78 | buildRequestLineSipUri( |
81 | - sipConfig.getId(), SipLayer.getLocalIp(localIp) + ":" + sipConfig.getPort()); | 79 | + sipConfig.getId(), SipTransportService.getLocalIp(localIp) + ":" + sipConfig.getPort()); |
82 | Address concatAddress = sipFactory.createAddressFactory().createAddress(sipUri); | 80 | Address concatAddress = sipFactory.createAddressFactory().createAddress(sipUri); |
83 | return sipFactory.createHeaderFactory().createContactHeader(concatAddress); | 81 | return sipFactory.createHeaderFactory().createContactHeader(concatAddress); |
84 | } | 82 | } |
@@ -15,12 +15,16 @@ import javax.sip.address.SipURI; | @@ -15,12 +15,16 @@ import javax.sip.address.SipURI; | ||
15 | import javax.sip.header.*; | 15 | import javax.sip.header.*; |
16 | import javax.sip.message.Request; | 16 | import javax.sip.message.Request; |
17 | import javax.sip.message.Response; | 17 | import javax.sip.message.Response; |
18 | + | ||
19 | +import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; | ||
18 | import org.springframework.stereotype.Component; | 20 | import org.springframework.stereotype.Component; |
19 | import org.thingsboard.server.common.data.yunteng.dto.sip.SipMessageHeaderDTO; | 21 | import org.thingsboard.server.common.data.yunteng.dto.sip.SipMessageHeaderDTO; |
20 | import org.thingsboard.server.transport.session.GbtDeviceSessionCtx; | 22 | import org.thingsboard.server.transport.session.GbtDeviceSessionCtx; |
21 | import org.thingsboard.server.transport.util.TKSipUtils; | 23 | import org.thingsboard.server.transport.util.TKSipUtils; |
22 | 24 | ||
23 | @Component | 25 | @Component |
26 | +@ConditionalOnExpression( | ||
27 | + "'${service.type:null}'=='tb-transport' || ('${service.type:null}'=='monolith' && '${transport.api_enabled:true}'=='true' && '${transport.gbt28181.enabled}'=='true')") | ||
24 | public class SIPRequestHeaderProcess extends AbstractSIPRequestProcess { | 28 | public class SIPRequestHeaderProcess extends AbstractSIPRequestProcess { |
25 | public Request createMessageRequest( | 29 | public Request createMessageRequest( |
26 | GbtDeviceSessionCtx sessionCtx, | 30 | GbtDeviceSessionCtx sessionCtx, |
common/transport/gbt28181/src/main/java/org/thingsboard/server/transport/cmd/SIPSender.java
renamed from
common/transport/gbt28181/src/main/java/org/thingsboard/server/transport/SIPSender.java
1 | -package org.thingsboard.server.transport; | 1 | +package org.thingsboard.server.transport.cmd; |
2 | 2 | ||
3 | import gov.nist.javax.sip.SipProviderImpl; | 3 | import gov.nist.javax.sip.SipProviderImpl; |
4 | import java.text.ParseException; | 4 | import java.text.ParseException; |
@@ -11,15 +11,18 @@ import javax.sip.message.Request; | @@ -11,15 +11,18 @@ import javax.sip.message.Request; | ||
11 | import javax.sip.message.Response; | 11 | import javax.sip.message.Response; |
12 | import lombok.extern.slf4j.Slf4j; | 12 | import lombok.extern.slf4j.Slf4j; |
13 | import org.springframework.beans.factory.annotation.Autowired; | 13 | import org.springframework.beans.factory.annotation.Autowired; |
14 | +import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; | ||
14 | import org.springframework.stereotype.Component; | 15 | import org.springframework.stereotype.Component; |
15 | import org.springframework.util.ObjectUtils; | 16 | import org.springframework.util.ObjectUtils; |
16 | -import org.thingsboard.server.common.data.yunteng.config.media.ThingsKitVersionConfig; | ||
17 | -import org.thingsboard.server.transport.gbt28181.SipLayer; | 17 | +import org.thingsboard.server.transport.config.ThingsKitVersionConfig; |
18 | +import org.thingsboard.server.transport.gbt28181.sip.SipTransportService; | ||
18 | import org.thingsboard.server.transport.gbt28181.SipSubscribe; | 19 | import org.thingsboard.server.transport.gbt28181.SipSubscribe; |
19 | import org.thingsboard.server.transport.util.TKSipUtils; | 20 | import org.thingsboard.server.transport.util.TKSipUtils; |
20 | 21 | ||
21 | /** 发送SIP信息 */ | 22 | /** 发送SIP信息 */ |
22 | @Component | 23 | @Component |
24 | +@ConditionalOnExpression( | ||
25 | + "'${service.type:null}'=='tb-transport' || ('${service.type:null}'=='monolith' && '${transport.api_enabled:true}'=='true' && '${transport.gbt28181.enabled}'=='true')") | ||
23 | @Slf4j | 26 | @Slf4j |
24 | public class SIPSender { | 27 | public class SIPSender { |
25 | 28 | ||
@@ -80,7 +83,7 @@ public class SIPSender { | @@ -80,7 +83,7 @@ public class SIPSender { | ||
80 | } | 83 | } |
81 | 84 | ||
82 | SipProviderImpl sipProvider = | 85 | SipProviderImpl sipProvider = |
83 | - TCP.equals(transport) ? SipLayer.getTcpSipProvider(ip) : SipLayer.getUdpSipProvider(ip); | 86 | + TCP.equals(transport) ? SipTransportService.getTcpSipProvider(ip) : SipTransportService.getUdpSipProvider(ip); |
84 | if (sipProvider == null) { | 87 | if (sipProvider == null) { |
85 | log.error("[发送信息失败] 未找到{}://{}的监听信息", transport, ip); | 88 | log.error("[发送信息失败] 未找到{}://{}的监听信息", transport, ip); |
86 | return; | 89 | return; |
@@ -94,23 +97,23 @@ public class SIPSender { | @@ -94,23 +97,23 @@ public class SIPSender { | ||
94 | 97 | ||
95 | public CallIdHeader getNewCallIdHeader(String ip, String transport) { | 98 | public CallIdHeader getNewCallIdHeader(String ip, String transport) { |
96 | if (ObjectUtils.isEmpty(transport)) { | 99 | if (ObjectUtils.isEmpty(transport)) { |
97 | - return SipLayer.getUdpSipProvider().getNewCallId(); | 100 | + return SipTransportService.getUdpSipProvider().getNewCallId(); |
98 | } | 101 | } |
99 | SipProviderImpl sipProvider; | 102 | SipProviderImpl sipProvider; |
100 | if (ObjectUtils.isEmpty(ip)) { | 103 | if (ObjectUtils.isEmpty(ip)) { |
101 | sipProvider = | 104 | sipProvider = |
102 | transport.equalsIgnoreCase(TCP) | 105 | transport.equalsIgnoreCase(TCP) |
103 | - ? SipLayer.getTcpSipProvider() | ||
104 | - : SipLayer.getUdpSipProvider(); | 106 | + ? SipTransportService.getTcpSipProvider() |
107 | + : SipTransportService.getUdpSipProvider(); | ||
105 | } else { | 108 | } else { |
106 | sipProvider = | 109 | sipProvider = |
107 | transport.equalsIgnoreCase(TCP) | 110 | transport.equalsIgnoreCase(TCP) |
108 | - ? SipLayer.getTcpSipProvider(ip) | ||
109 | - : SipLayer.getUdpSipProvider(ip); | 111 | + ? SipTransportService.getTcpSipProvider(ip) |
112 | + : SipTransportService.getUdpSipProvider(ip); | ||
110 | } | 113 | } |
111 | 114 | ||
112 | if (sipProvider == null) { | 115 | if (sipProvider == null) { |
113 | - sipProvider = SipLayer.getUdpSipProvider(); | 116 | + sipProvider = SipTransportService.getUdpSipProvider(); |
114 | } | 117 | } |
115 | 118 | ||
116 | if (sipProvider != null) { | 119 | if (sipProvider != null) { |
@@ -13,8 +13,7 @@ import org.thingsboard.server.common.data.yunteng.config.media.UserSetting; | @@ -13,8 +13,7 @@ import org.thingsboard.server.common.data.yunteng.config.media.UserSetting; | ||
13 | import org.thingsboard.server.common.data.yunteng.constant.FastIotConstants; | 13 | import org.thingsboard.server.common.data.yunteng.constant.FastIotConstants; |
14 | import org.thingsboard.server.common.data.yunteng.dto.sip.*; | 14 | import org.thingsboard.server.common.data.yunteng.dto.sip.*; |
15 | import org.thingsboard.server.common.data.yunteng.enums.VideoCmdEnum; | 15 | import org.thingsboard.server.common.data.yunteng.enums.VideoCmdEnum; |
16 | -import org.thingsboard.server.transport.SIPSender; | ||
17 | -import org.thingsboard.server.transport.gbt28181.SipLayer; | 16 | +import org.thingsboard.server.transport.gbt28181.sip.SipTransportService; |
18 | import org.thingsboard.server.transport.gbt28181.SipSubscribe; | 17 | import org.thingsboard.server.transport.gbt28181.SipSubscribe; |
19 | import org.thingsboard.server.transport.session.GbtDeviceSessionCtx; | 18 | import org.thingsboard.server.transport.session.GbtDeviceSessionCtx; |
20 | import org.thingsboard.server.transport.util.TKSipUtils; | 19 | import org.thingsboard.server.transport.util.TKSipUtils; |
@@ -41,11 +40,11 @@ public class TKSipCommanderServiceImpl implements TKSipCommanderService { | @@ -41,11 +40,11 @@ public class TKSipCommanderServiceImpl implements TKSipCommanderService { | ||
41 | sessionCtx.getCameraCode()); | 40 | sessionCtx.getCameraCode()); |
42 | CallIdHeader callIdHeader = | 41 | CallIdHeader callIdHeader = |
43 | sipSender.getNewCallIdHeader( | 42 | sipSender.getNewCallIdHeader( |
44 | - SipLayer.getLocalIp(sessionCtx.getLocalIp()), sessionCtx.getTransport()); | 43 | + SipTransportService.getLocalIp(sessionCtx.getLocalIp()), sessionCtx.getTransport()); |
45 | Request request = | 44 | Request request = |
46 | headerProvider.createMessageRequest( | 45 | headerProvider.createMessageRequest( |
47 | sessionCtx, sipMessageHeaderDTO, xmlContent, callIdHeader); | 46 | sessionCtx, sipMessageHeaderDTO, xmlContent, callIdHeader); |
48 | - sipSender.transmitRequest(SipLayer.getLocalIp(sessionCtx.getLocalIp()), request); | 47 | + sipSender.transmitRequest(SipTransportService.getLocalIp(sessionCtx.getLocalIp()), request); |
49 | } | 48 | } |
50 | 49 | ||
51 | @Override | 50 | @Override |
@@ -63,13 +62,13 @@ public class TKSipCommanderServiceImpl implements TKSipCommanderService { | @@ -63,13 +62,13 @@ public class TKSipCommanderServiceImpl implements TKSipCommanderService { | ||
63 | deviceSessionCtx.getCameraCode()); | 62 | deviceSessionCtx.getCameraCode()); |
64 | CallIdHeader callIdHeader = | 63 | CallIdHeader callIdHeader = |
65 | sipSender.getNewCallIdHeader( | 64 | sipSender.getNewCallIdHeader( |
66 | - SipLayer.getLocalIp(deviceSessionCtx.getLocalIp()), deviceSessionCtx.getTransport()); | 65 | + SipTransportService.getLocalIp(deviceSessionCtx.getLocalIp()), deviceSessionCtx.getTransport()); |
67 | Request request = | 66 | Request request = |
68 | headerProvider.createMessageRequest( | 67 | headerProvider.createMessageRequest( |
69 | deviceSessionCtx, sipMessageHeaderDTO, xmlContent, callIdHeader); | 68 | deviceSessionCtx, sipMessageHeaderDTO, xmlContent, callIdHeader); |
70 | 69 | ||
71 | sipSender.transmitRequest( | 70 | sipSender.transmitRequest( |
72 | - SipLayer.getLocalIp(deviceSessionCtx.getLocalIp()), request, errorEvent); | 71 | + SipTransportService.getLocalIp(deviceSessionCtx.getLocalIp()), request, errorEvent); |
73 | } | 72 | } |
74 | 73 | ||
75 | @Override | 74 | @Override |
@@ -86,12 +85,12 @@ public class TKSipCommanderServiceImpl implements TKSipCommanderService { | @@ -86,12 +85,12 @@ public class TKSipCommanderServiceImpl implements TKSipCommanderService { | ||
86 | ptzCmd); | 85 | ptzCmd); |
87 | CallIdHeader callIdHeader = | 86 | CallIdHeader callIdHeader = |
88 | sipSender.getNewCallIdHeader( | 87 | sipSender.getNewCallIdHeader( |
89 | - SipLayer.getLocalIp(deviceSessionCtx.getLocalIp()), deviceSessionCtx.getTransport()); | 88 | + SipTransportService.getLocalIp(deviceSessionCtx.getLocalIp()), deviceSessionCtx.getTransport()); |
90 | Request request = | 89 | Request request = |
91 | headerProvider.createMessageRequest( | 90 | headerProvider.createMessageRequest( |
92 | deviceSessionCtx, sipMessageHeaderDTO, xmlContent, callIdHeader); | 91 | deviceSessionCtx, sipMessageHeaderDTO, xmlContent, callIdHeader); |
93 | 92 | ||
94 | - sipSender.transmitRequest(SipLayer.getLocalIp(deviceSessionCtx.getLocalIp()), request); | 93 | + sipSender.transmitRequest(SipTransportService.getLocalIp(deviceSessionCtx.getLocalIp()), request); |
95 | } | 94 | } |
96 | 95 | ||
97 | @Override | 96 | @Override |
@@ -110,13 +109,13 @@ public class TKSipCommanderServiceImpl implements TKSipCommanderService { | @@ -110,13 +109,13 @@ public class TKSipCommanderServiceImpl implements TKSipCommanderService { | ||
110 | 109 | ||
111 | CallIdHeader callIdHeader = | 110 | CallIdHeader callIdHeader = |
112 | sipSender.getNewCallIdHeader( | 111 | sipSender.getNewCallIdHeader( |
113 | - SipLayer.getLocalIp(devSession.getLocalIp()), devSession.getTransport()); | 112 | + SipTransportService.getLocalIp(devSession.getLocalIp()), devSession.getTransport()); |
114 | Request request = | 113 | Request request = |
115 | headerProvider.createInviteRequest( | 114 | headerProvider.createInviteRequest( |
116 | devSession, sipMessageHeaderDTO, channelId, content, callIdHeader, ssrc); | 115 | devSession, sipMessageHeaderDTO, channelId, content, callIdHeader, ssrc); |
117 | 116 | ||
118 | sipSender.transmitRequest( | 117 | sipSender.transmitRequest( |
119 | - SipLayer.getLocalIp(devSession.getLocalIp()), request, errorEvent, okEvent); | 118 | + SipTransportService.getLocalIp(devSession.getLocalIp()), request, errorEvent, okEvent); |
120 | } | 119 | } |
121 | 120 | ||
122 | @Override | 121 | @Override |
@@ -144,7 +143,7 @@ public class TKSipCommanderServiceImpl implements TKSipCommanderService { | @@ -144,7 +143,7 @@ public class TKSipCommanderServiceImpl implements TKSipCommanderService { | ||
144 | headerDTO.getViaTag(), | 143 | headerDTO.getViaTag(), |
145 | headerDTO.getFromTag(), | 144 | headerDTO.getFromTag(), |
146 | headerDTO.getToTag()); | 145 | headerDTO.getToTag()); |
147 | - sipSender.transmitRequest(SipLayer.getLocalIp(device.getLocalIp()), byteRequest, null, okEvent); | 146 | + sipSender.transmitRequest(SipTransportService.getLocalIp(device.getLocalIp()), byteRequest, null, okEvent); |
148 | } | 147 | } |
149 | 148 | ||
150 | private String buildMessageBodyQueryXml( | 149 | private String buildMessageBodyQueryXml( |
common/transport/gbt28181/src/main/java/org/thingsboard/server/transport/config/MediaConfig.java
0 → 100644
1 | +package org.thingsboard.server.transport.config; | ||
2 | + | ||
3 | +import java.io.Serializable; | ||
4 | +import lombok.Data; | ||
5 | +import lombok.extern.slf4j.Slf4j; | ||
6 | +import org.springframework.beans.factory.annotation.Value; | ||
7 | +import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; | ||
8 | +import org.springframework.boot.context.properties.ConfigurationProperties; | ||
9 | +import org.springframework.stereotype.Component; | ||
10 | + | ||
11 | +/** 配置文件里面的流媒体配置信息 */ | ||
12 | +@ConfigurationProperties(prefix = "transport.gbt28181.media") | ||
13 | +@Component | ||
14 | +@ConditionalOnExpression( | ||
15 | + "'${service.type:null}'=='tb-transport' || ('${service.type:null}'=='monolith' && '${transport.api_enabled:true}'=='true' && '${transport.gbt28181.enabled}'=='true')") | ||
16 | +@Data | ||
17 | +@Slf4j | ||
18 | +public class MediaConfig implements Serializable { | ||
19 | + @Value("${transport.gbt28181.media.id}") | ||
20 | + private String mediaServerId; | ||
21 | + | ||
22 | + @Value("${transport.gbt28181.media.ip}") | ||
23 | + private String ip; | ||
24 | + | ||
25 | + @Value("${transport.gbt28181.media.hook-ip:}") | ||
26 | + private String hookIp; | ||
27 | + | ||
28 | + @Value("${transport.gbt28181.media.sdp-ip:${transport.gbt28181.media.ip}}") | ||
29 | + private String sdpIp; | ||
30 | + | ||
31 | + @Value("${transport.gbt28181.media.stream-ip:${transport.gbt28181.media.ip}}") | ||
32 | + private String streamIp; | ||
33 | + | ||
34 | + @Value("${transport.gbt28181.media.http-port}") | ||
35 | + private Integer httpPort; | ||
36 | + | ||
37 | + @Value("${transport.gbt28181.media.http-ssl-port:0}") | ||
38 | + private Integer httpSslPort = 0; | ||
39 | + | ||
40 | + @Value("${transport.gbt28181.media.rtmp-port:0}") | ||
41 | + private Integer rtmpPort = 0; | ||
42 | + | ||
43 | + @Value("${transport.gbt28181.media.rtmp-ssl-port:0}") | ||
44 | + private Integer rtmpSslPort = 0; | ||
45 | + | ||
46 | + @Value("${transport.gbt28181.media.rtp-proxy-port:0}") | ||
47 | + private Integer rtpProxyPort = 0; | ||
48 | + | ||
49 | + @Value("${transport.gbt28181.media.rtsp-port:0}") | ||
50 | + private Integer rtspPort = 0; | ||
51 | + | ||
52 | + @Value("${transport.gbt28181.media.rtsp-ssl-port:0}") | ||
53 | + private Integer rtspSslPort = 0; | ||
54 | + | ||
55 | + @Value("${transport.gbt28181.media.auto-config:true}") | ||
56 | + private boolean autoConfig = true; | ||
57 | + | ||
58 | + @Value("${transport.gbt28181.media.secret}") | ||
59 | + private String secret; | ||
60 | + | ||
61 | + @Value("${transport.gbt28181.media.rtp.enable}") | ||
62 | + private boolean rtpEnable; | ||
63 | + | ||
64 | + @Value("${transport.gbt28181.media.rtp.port-range}") | ||
65 | + private String rtpPortRange; | ||
66 | + | ||
67 | + @Value("${transport.gbt28181.media.rtp.send-port-range}") | ||
68 | + private String rtpSendPortRange; | ||
69 | + | ||
70 | + @Value("${transport.gbt28181.media.record-assist-port:0}") | ||
71 | + private Integer recordAssistPort = 0; | ||
72 | + | ||
73 | + private boolean status; | ||
74 | +} |
common/transport/gbt28181/src/main/java/org/thingsboard/server/transport/config/SipConfig.java
renamed from
common/data/src/main/java/org/thingsboard/server/common/data/yunteng/config/media/SipConfig.java
1 | -package org.thingsboard.server.common.data.yunteng.config.media; | 1 | +package org.thingsboard.server.transport.config; |
2 | 2 | ||
3 | import lombok.Data; | 3 | import lombok.Data; |
4 | +import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; | ||
4 | import org.springframework.boot.context.properties.ConfigurationProperties; | 5 | import org.springframework.boot.context.properties.ConfigurationProperties; |
5 | import org.springframework.stereotype.Component; | 6 | import org.springframework.stereotype.Component; |
6 | 7 | ||
7 | -@ConfigurationProperties(prefix = "sip") | 8 | +@ConfigurationProperties(prefix = "transport.gbt28181.sip") |
8 | @Component | 9 | @Component |
10 | +@ConditionalOnExpression( | ||
11 | + "'${service.type:null}'=='tb-transport' || ('${service.type:null}'=='monolith' && '${transport.api_enabled:true}'=='true' && '${transport.gbt28181.enabled}'=='true')") | ||
9 | @Data | 12 | @Data |
10 | public class SipConfig { | 13 | public class SipConfig { |
11 | - private String ip; | ||
12 | - private String showIp; | ||
13 | - private Integer port; | ||
14 | - private String id; | ||
15 | - private String domain; | ||
16 | - private String password; | ||
17 | - Integer ptzSpeed = 50; | ||
18 | - Integer registerTimeInterval = 120; | ||
19 | - private boolean alarm; | 14 | + private String ip; |
15 | + private String showIp; | ||
16 | + private Integer port; | ||
17 | + private String id; | ||
18 | + private String domain; | ||
19 | + private String password; | ||
20 | + Integer ptzSpeed = 50; | ||
21 | + Integer registerTimeInterval = 120; | ||
22 | + private boolean alarm; | ||
20 | 23 | ||
21 | - public String getShowIp() { | ||
22 | - if (this.showIp == null) { | ||
23 | - return this.ip; | ||
24 | - } | ||
25 | - return showIp; | 24 | + public String getShowIp() { |
25 | + if (this.showIp == null) { | ||
26 | + return this.ip; | ||
26 | } | 27 | } |
28 | + return showIp; | ||
29 | + } | ||
27 | } | 30 | } |
common/transport/gbt28181/src/main/java/org/thingsboard/server/transport/config/ThingsKitVersionConfig.java
renamed from
common/data/src/main/java/org/thingsboard/server/common/data/yunteng/config/media/ThingsKitVersionConfig.java
1 | -package org.thingsboard.server.common.data.yunteng.config.media; | 1 | +package org.thingsboard.server.transport.config; |
2 | 2 | ||
3 | import lombok.Data; | 3 | import lombok.Data; |
4 | import org.springframework.beans.factory.annotation.Value; | 4 | import org.springframework.beans.factory.annotation.Value; |
5 | +import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; | ||
5 | import org.springframework.stereotype.Component; | 6 | import org.springframework.stereotype.Component; |
6 | 7 | ||
7 | @Component | 8 | @Component |
9 | +@ConditionalOnExpression( | ||
10 | + "'${service.type:null}'=='tb-transport' || ('${service.type:null}'=='monolith' && '${transport.api_enabled:true}'=='true' && '${transport.gbt28181.enabled}'=='true')") | ||
8 | @Data | 11 | @Data |
9 | public class ThingsKitVersionConfig { | 12 | public class ThingsKitVersionConfig { |
10 | @Value("${thingskit.release.version}") | 13 | @Value("${thingskit.release.version}") |
@@ -13,12 +13,15 @@ import javax.sip.header.CallIdHeader; | @@ -13,12 +13,15 @@ import javax.sip.header.CallIdHeader; | ||
13 | import javax.sip.message.Response; | 13 | import javax.sip.message.Response; |
14 | import org.slf4j.Logger; | 14 | import org.slf4j.Logger; |
15 | import org.slf4j.LoggerFactory; | 15 | import org.slf4j.LoggerFactory; |
16 | +import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; | ||
16 | import org.springframework.scheduling.annotation.Scheduled; | 17 | import org.springframework.scheduling.annotation.Scheduled; |
17 | import org.springframework.stereotype.Component; | 18 | import org.springframework.stereotype.Component; |
18 | -import org.thingsboard.server.transport.gbt28181.event.DeviceNotFoundEvent; | 19 | +import org.thingsboard.server.transport.gbt28181.sip.event.DeviceNotFoundEvent; |
19 | 20 | ||
20 | /** SIP订阅信息 */ | 21 | /** SIP订阅信息 */ |
21 | @Component | 22 | @Component |
23 | +@ConditionalOnExpression( | ||
24 | + "'${service.type:null}'=='tb-transport' || ('${service.type:null}'=='monolith' && '${transport.api_enabled:true}'=='true' && '${transport.gbt28181.enabled}'=='true')") | ||
22 | public class SipSubscribe { | 25 | public class SipSubscribe { |
23 | 26 | ||
24 | private final Logger logger = LoggerFactory.getLogger(SipSubscribe.class); | 27 | private final Logger logger = LoggerFactory.getLogger(SipSubscribe.class); |
@@ -36,8 +36,6 @@ import javax.sip.header.HeaderFactory; | @@ -36,8 +36,6 @@ import javax.sip.header.HeaderFactory; | ||
36 | import javax.sip.header.WWWAuthenticateHeader; | 36 | import javax.sip.header.WWWAuthenticateHeader; |
37 | import javax.sip.message.Request; | 37 | import javax.sip.message.Request; |
38 | import javax.sip.message.Response; | 38 | import javax.sip.message.Response; |
39 | -import org.slf4j.Logger; | ||
40 | -import org.slf4j.LoggerFactory; | ||
41 | 39 | ||
42 | /** Implements the HTTP digest authentication method server side functionality. */ | 40 | /** Implements the HTTP digest authentication method server side functionality. */ |
43 | public class DigestServerAuthenticationHelper { | 41 | public class DigestServerAuthenticationHelper { |
@@ -99,6 +97,7 @@ public class DigestServerAuthenticationHelper { | @@ -99,6 +97,7 @@ public class DigestServerAuthenticationHelper { | ||
99 | } | 97 | } |
100 | return response; | 98 | return response; |
101 | } | 99 | } |
100 | + | ||
102 | /** | 101 | /** |
103 | * Authenticate the inbound request. | 102 | * Authenticate the inbound request. |
104 | * | 103 | * |
common/transport/gbt28181/src/main/java/org/thingsboard/server/transport/gbt28181/auth/RemoteAddressInfo.java
renamed from
common/transport/gbt28181/src/main/java/org/thingsboard/server/transport/info/RemoteAddressInfo.java
1 | -package org.thingsboard.server.transport.info; | 1 | +package org.thingsboard.server.transport.gbt28181.auth; |
2 | 2 | ||
3 | +import lombok.Data; | ||
4 | + | ||
5 | +@Data | ||
3 | public class RemoteAddressInfo { | 6 | public class RemoteAddressInfo { |
4 | private String ip; | 7 | private String ip; |
5 | private int port; | 8 | private int port; |
@@ -8,20 +11,4 @@ public class RemoteAddressInfo { | @@ -8,20 +11,4 @@ public class RemoteAddressInfo { | ||
8 | this.ip = ip; | 11 | this.ip = ip; |
9 | this.port = port; | 12 | this.port = port; |
10 | } | 13 | } |
11 | - | ||
12 | - public String getIp() { | ||
13 | - return ip; | ||
14 | - } | ||
15 | - | ||
16 | - public void setIp(String ip) { | ||
17 | - this.ip = ip; | ||
18 | - } | ||
19 | - | ||
20 | - public int getPort() { | ||
21 | - return port; | ||
22 | - } | ||
23 | - | ||
24 | - public void setPort(int port) { | ||
25 | - this.port = port; | ||
26 | - } | ||
27 | } | 14 | } |
@@ -7,6 +7,7 @@ import java.util.*; | @@ -7,6 +7,7 @@ import java.util.*; | ||
7 | import java.util.concurrent.ConcurrentHashMap; | 7 | import java.util.concurrent.ConcurrentHashMap; |
8 | import java.util.concurrent.TimeUnit; | 8 | import java.util.concurrent.TimeUnit; |
9 | 9 | ||
10 | +import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; | ||
10 | import org.springframework.scheduling.annotation.Scheduled; | 11 | import org.springframework.scheduling.annotation.Scheduled; |
11 | import org.springframework.stereotype.Component; | 12 | import org.springframework.stereotype.Component; |
12 | import org.thingsboard.server.common.data.yunteng.dto.sip.CatalogDataDTO; | 13 | import org.thingsboard.server.common.data.yunteng.dto.sip.CatalogDataDTO; |
@@ -16,6 +17,8 @@ import org.thingsboard.server.common.data.yunteng.dto.sip.VideoChanelDTO; | @@ -16,6 +17,8 @@ import org.thingsboard.server.common.data.yunteng.dto.sip.VideoChanelDTO; | ||
16 | import org.thingsboard.server.common.data.yunteng.enums.CatalogDataStatusEnum; | 17 | import org.thingsboard.server.common.data.yunteng.enums.CatalogDataStatusEnum; |
17 | 18 | ||
18 | @Component | 19 | @Component |
20 | +@ConditionalOnExpression( | ||
21 | + "'${service.type:null}'=='tb-transport' || ('${service.type:null}'=='monolith' && '${transport.api_enabled:true}'=='true' && '${transport.gbt28181.enabled}'=='true')") | ||
19 | public class CatalogDataCatch { | 22 | public class CatalogDataCatch { |
20 | 23 | ||
21 | public static Map<String, CatalogDataDTO> data = new ConcurrentHashMap<>(); | 24 | public static Map<String, CatalogDataDTO> data = new ConcurrentHashMap<>(); |
common/transport/gbt28181/src/main/java/org/thingsboard/server/transport/gbt28181/session/GbtTransportContext.java
renamed from
common/transport/gbt28181/src/main/java/org/thingsboard/server/transport/GbtTransportContext.java
1 | -package org.thingsboard.server.transport; | 1 | +package org.thingsboard.server.transport.gbt28181.session; |
2 | 2 | ||
3 | -import gov.nist.core.HostPort; | ||
4 | import io.netty.handler.ssl.SslHandler; | 3 | import io.netty.handler.ssl.SslHandler; |
5 | -import java.net.InetSocketAddress; | ||
6 | import java.util.concurrent.Executors; | 4 | import java.util.concurrent.Executors; |
7 | import java.util.concurrent.ScheduledExecutorService; | 5 | import java.util.concurrent.ScheduledExecutorService; |
8 | import java.util.concurrent.atomic.AtomicInteger; | 6 | import java.util.concurrent.atomic.AtomicInteger; |
@@ -10,13 +8,11 @@ import javax.annotation.PostConstruct; | @@ -10,13 +8,11 @@ import javax.annotation.PostConstruct; | ||
10 | import lombok.Getter; | 8 | import lombok.Getter; |
11 | import lombok.Setter; | 9 | import lombok.Setter; |
12 | import lombok.extern.slf4j.Slf4j; | 10 | import lombok.extern.slf4j.Slf4j; |
13 | -import org.springframework.beans.factory.annotation.Autowired; | ||
14 | import org.springframework.beans.factory.annotation.Value; | 11 | import org.springframework.beans.factory.annotation.Value; |
15 | import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; | 12 | import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; |
16 | import org.springframework.stereotype.Component; | 13 | import org.springframework.stereotype.Component; |
17 | import org.thingsboard.common.util.ThingsBoardThreadFactory; | 14 | import org.thingsboard.common.util.ThingsBoardThreadFactory; |
18 | import org.thingsboard.server.common.transport.TransportContext; | 15 | import org.thingsboard.server.common.transport.TransportContext; |
19 | -import org.thingsboard.server.transport.adaptors.GbtTransportAdaptor; | ||
20 | 16 | ||
21 | @Slf4j | 17 | @Slf4j |
22 | @Component | 18 | @Component |
@@ -24,8 +20,6 @@ import org.thingsboard.server.transport.adaptors.GbtTransportAdaptor; | @@ -24,8 +20,6 @@ import org.thingsboard.server.transport.adaptors.GbtTransportAdaptor; | ||
24 | "'${service.type:null}'=='tb-transport' || ('${service.type:null}'=='monolith' && '${transport.api_enabled:true}'=='true' && '${transport.gbt28181.enabled}'=='true')") | 20 | "'${service.type:null}'=='tb-transport' || ('${service.type:null}'=='monolith' && '${transport.api_enabled:true}'=='true' && '${transport.gbt28181.enabled}'=='true')") |
25 | public class GbtTransportContext extends TransportContext { | 21 | public class GbtTransportContext extends TransportContext { |
26 | 22 | ||
27 | - /** 注入多种数据协议处理器,例如:modbus等 */ | ||
28 | - @Getter @Autowired private GbtTransportAdaptor jsonAdaptor; | ||
29 | 23 | ||
30 | @Getter | 24 | @Getter |
31 | @Value("${transport.tcp.netty.max_payload_size}") | 25 | @Value("${transport.tcp.netty.max_payload_size}") |
common/transport/gbt28181/src/main/java/org/thingsboard/server/transport/gbt28181/sip/DefaultProperties.java
renamed from
common/transport/gbt28181/src/main/java/org/thingsboard/server/transport/gbt28181/DefaultProperties.java
common/transport/gbt28181/src/main/java/org/thingsboard/server/transport/gbt28181/sip/ISIPRequestProcessor.java
renamed from
common/transport/gbt28181/src/main/java/org/thingsboard/server/transport/gbt28181/ISIPRequestProcessor.java
common/transport/gbt28181/src/main/java/org/thingsboard/server/transport/gbt28181/sip/ISIPResponseProcessor.java
renamed from
common/transport/gbt28181/src/main/java/org/thingsboard/server/transport/gbt28181/ISIPResponseProcessor.java
common/transport/gbt28181/src/main/java/org/thingsboard/server/transport/gbt28181/sip/SipTransportService.java
renamed from
common/transport/gbt28181/src/main/java/org/thingsboard/server/transport/gbt28181/SipLayer.java
@@ -11,7 +11,7 @@ | @@ -11,7 +11,7 @@ | ||
11 | * express or implied. See the License for the specific language governing permissions and | 11 | * express or implied. See the License for the specific language governing permissions and |
12 | * limitations under the License. | 12 | * limitations under the License. |
13 | */ | 13 | */ |
14 | -package org.thingsboard.server.transport.gbt28181; | 14 | +package org.thingsboard.server.transport.gbt28181.sip; |
15 | 15 | ||
16 | import gov.nist.javax.sip.SipProviderImpl; | 16 | import gov.nist.javax.sip.SipProviderImpl; |
17 | import gov.nist.javax.sip.SipStackImpl; | 17 | import gov.nist.javax.sip.SipStackImpl; |
@@ -26,20 +26,20 @@ import org.springframework.stereotype.Service; | @@ -26,20 +26,20 @@ import org.springframework.stereotype.Service; | ||
26 | import org.springframework.util.ObjectUtils; | 26 | import org.springframework.util.ObjectUtils; |
27 | import org.thingsboard.server.common.data.DataConstants; | 27 | import org.thingsboard.server.common.data.DataConstants; |
28 | import org.thingsboard.server.common.data.TbTransportService; | 28 | import org.thingsboard.server.common.data.TbTransportService; |
29 | -import org.thingsboard.server.common.data.yunteng.config.media.SipConfig; | ||
30 | -import org.thingsboard.server.transport.SIPProvider; | 29 | +import org.thingsboard.server.transport.gbt28181.sip.processor.SIPProvider; |
30 | +import org.thingsboard.server.transport.config.SipConfig; | ||
31 | 31 | ||
32 | /** | 32 | /** |
33 | * @author Andrew Shvayka | 33 | * @author Andrew Shvayka |
34 | */ | 34 | */ |
35 | -@Service("GBT28181TransportService") | ||
36 | -@ConditionalOnExpression("'${service.type:null}'=='tb-transport' || ('${service.type:null}'=='monolith' && '${transport.api_enabled:true}'=='true' && '${transport.gbt28181.enabled}'=='true')") | 35 | +@Service() |
36 | +@ConditionalOnExpression( | ||
37 | + "'${service.type:null}'=='tb-transport' || ('${service.type:null}'=='monolith' && '${transport.api_enabled:true}'=='true' && '${transport.gbt28181.enabled}'=='true')") | ||
37 | @Slf4j | 38 | @Slf4j |
38 | -public class SipLayer implements TbTransportService { | 39 | +public class SipTransportService implements TbTransportService { |
39 | private static final Map<String, SipProviderImpl> tcpSipProviderMap = new ConcurrentHashMap<>(); | 40 | private static final Map<String, SipProviderImpl> tcpSipProviderMap = new ConcurrentHashMap<>(); |
40 | private static final Map<String, SipProviderImpl> udpSipProviderMap = new ConcurrentHashMap<>(); | 41 | private static final Map<String, SipProviderImpl> udpSipProviderMap = new ConcurrentHashMap<>(); |
41 | - @Autowired | ||
42 | - private SIPProvider sipProvider; | 42 | + @Autowired private SIPProvider sipProvider; |
43 | 43 | ||
44 | @Autowired private SipConfig sipConfig; | 44 | @Autowired private SipConfig sipConfig; |
45 | 45 |
common/transport/gbt28181/src/main/java/org/thingsboard/server/transport/gbt28181/sip/event/DeviceNotFoundEvent.java
renamed from
common/transport/gbt28181/src/main/java/org/thingsboard/server/transport/gbt28181/event/DeviceNotFoundEvent.java
1 | -package org.thingsboard.server.transport.gbt28181.event; | 1 | +package org.thingsboard.server.transport.gbt28181.sip.event; |
2 | 2 | ||
3 | import java.util.EventObject; | 3 | import java.util.EventObject; |
4 | import javax.sip.Dialog; | 4 | import javax.sip.Dialog; |
5 | +import lombok.Getter; | ||
6 | +import lombok.Setter; | ||
5 | 7 | ||
8 | +@Getter | ||
9 | +@Setter | ||
6 | public class DeviceNotFoundEvent extends EventObject { | 10 | public class DeviceNotFoundEvent extends EventObject { |
7 | 11 | ||
8 | private String callId; | 12 | private String callId; |
@@ -16,12 +20,4 @@ public class DeviceNotFoundEvent extends EventObject { | @@ -16,12 +20,4 @@ public class DeviceNotFoundEvent extends EventObject { | ||
16 | public DeviceNotFoundEvent(Dialog dialog) { | 20 | public DeviceNotFoundEvent(Dialog dialog) { |
17 | super(dialog); | 21 | super(dialog); |
18 | } | 22 | } |
19 | - | ||
20 | - public String getCallId() { | ||
21 | - return callId; | ||
22 | - } | ||
23 | - | ||
24 | - public void setCallId(String callId) { | ||
25 | - this.callId = callId; | ||
26 | - } | ||
27 | } | 23 | } |
common/transport/gbt28181/src/main/java/org/thingsboard/server/transport/gbt28181/sip/processor/ITimeoutProcessor.java
renamed from
common/transport/gbt28181/src/main/java/org/thingsboard/server/transport/gbt28181/ITimeoutProcessor.java
common/transport/gbt28181/src/main/java/org/thingsboard/server/transport/gbt28181/sip/processor/SIPProcessorObserver.java
renamed from
common/transport/gbt28181/src/main/java/org/thingsboard/server/transport/SIPProcessorObserver.java
1 | -package org.thingsboard.server.transport; | 1 | +package org.thingsboard.server.transport.gbt28181.sip.processor; |
2 | 2 | ||
3 | import static org.thingsboard.server.common.transport.service.DefaultTransportService.SESSION_EVENT_MSG_CLOSED; | 3 | import static org.thingsboard.server.common.transport.service.DefaultTransportService.SESSION_EVENT_MSG_CLOSED; |
4 | import static org.thingsboard.server.common.transport.service.DefaultTransportService.SESSION_EVENT_MSG_OPEN; | 4 | import static org.thingsboard.server.common.transport.service.DefaultTransportService.SESSION_EVENT_MSG_OPEN; |
@@ -40,8 +40,6 @@ import org.thingsboard.server.common.data.DeviceTransportType; | @@ -40,8 +40,6 @@ import org.thingsboard.server.common.data.DeviceTransportType; | ||
40 | import org.thingsboard.server.common.data.StringUtils; | 40 | import org.thingsboard.server.common.data.StringUtils; |
41 | import org.thingsboard.server.common.data.id.DeviceId; | 41 | import org.thingsboard.server.common.data.id.DeviceId; |
42 | import org.thingsboard.server.common.data.rpc.RpcStatus; | 42 | import org.thingsboard.server.common.data.rpc.RpcStatus; |
43 | -import org.thingsboard.server.common.data.yunteng.common.media.VideoStreamSessionManager; | ||
44 | -import org.thingsboard.server.common.data.yunteng.config.media.SipConfig; | ||
45 | import org.thingsboard.server.common.data.yunteng.config.media.UserSetting; | 43 | import org.thingsboard.server.common.data.yunteng.config.media.UserSetting; |
46 | import org.thingsboard.server.common.data.yunteng.constant.FastIotConstants; | 44 | import org.thingsboard.server.common.data.yunteng.constant.FastIotConstants; |
47 | import org.thingsboard.server.common.data.yunteng.dto.sip.PTZCmdDTO; | 45 | import org.thingsboard.server.common.data.yunteng.dto.sip.PTZCmdDTO; |
@@ -58,11 +56,16 @@ import org.thingsboard.server.common.transport.auth.SessionInfoCreator; | @@ -58,11 +56,16 @@ import org.thingsboard.server.common.transport.auth.SessionInfoCreator; | ||
58 | import org.thingsboard.server.common.transport.auth.ValidateDeviceCredentialsResponse; | 56 | import org.thingsboard.server.common.transport.auth.ValidateDeviceCredentialsResponse; |
59 | import org.thingsboard.server.common.transport.util.DataDecodingEncodingService; | 57 | import org.thingsboard.server.common.transport.util.DataDecodingEncodingService; |
60 | import org.thingsboard.server.gen.transport.TransportProtos; | 58 | import org.thingsboard.server.gen.transport.TransportProtos; |
59 | +import org.thingsboard.server.transport.gbt28181.session.GbtTransportContext; | ||
61 | import org.thingsboard.server.transport.cmd.SIPRequestHeaderProcess; | 60 | import org.thingsboard.server.transport.cmd.SIPRequestHeaderProcess; |
62 | import org.thingsboard.server.transport.cmd.TKSipCommanderService; | 61 | import org.thingsboard.server.transport.cmd.TKSipCommanderService; |
62 | +import org.thingsboard.server.transport.config.MediaConfig; | ||
63 | +import org.thingsboard.server.transport.config.SipConfig; | ||
63 | import org.thingsboard.server.transport.gbt28181.*; | 64 | import org.thingsboard.server.transport.gbt28181.*; |
64 | import org.thingsboard.server.transport.gbt28181.auth.DigestServerAuthenticationHelper; | 65 | import org.thingsboard.server.transport.gbt28181.auth.DigestServerAuthenticationHelper; |
65 | -import org.thingsboard.server.transport.info.RemoteAddressInfo; | 66 | +import org.thingsboard.server.transport.gbt28181.sip.ISIPRequestProcessor; |
67 | +import org.thingsboard.server.transport.gbt28181.sip.ISIPResponseProcessor; | ||
68 | +import org.thingsboard.server.transport.gbt28181.auth.RemoteAddressInfo; | ||
66 | import org.thingsboard.server.transport.session.GbtDeviceSessionCtx; | 69 | import org.thingsboard.server.transport.session.GbtDeviceSessionCtx; |
67 | import org.thingsboard.server.transport.util.TKSipUtils; | 70 | import org.thingsboard.server.transport.util.TKSipUtils; |
68 | import org.thingsboard.server.transport.util.TKXmlUtil; | 71 | import org.thingsboard.server.transport.util.TKXmlUtil; |
@@ -81,6 +84,7 @@ public class SIPProcessorObserver extends SIPRequestProcessorParent | @@ -81,6 +84,7 @@ public class SIPProcessorObserver extends SIPRequestProcessorParent | ||
81 | 84 | ||
82 | private final SIPRequestHeaderProcess headerProvider; | 85 | private final SIPRequestHeaderProcess headerProvider; |
83 | private final SipConfig sipConfig; | 86 | private final SipConfig sipConfig; |
87 | + private final MediaConfig mediaConfig; | ||
84 | private final UserSetting userSetting; | 88 | private final UserSetting userSetting; |
85 | private final TKSipCommanderService commanderService; | 89 | private final TKSipCommanderService commanderService; |
86 | private final DataDecodingEncodingService encodingService; | 90 | private final DataDecodingEncodingService encodingService; |
@@ -93,7 +97,9 @@ public class SIPProcessorObserver extends SIPRequestProcessorParent | @@ -93,7 +97,9 @@ public class SIPProcessorObserver extends SIPRequestProcessorParent | ||
93 | 97 | ||
94 | @Getter | 98 | @Getter |
95 | private final ConcurrentHashMap<DeviceId, String> onlineDevice = new ConcurrentHashMap<>(); | 99 | private final ConcurrentHashMap<DeviceId, String> onlineDevice = new ConcurrentHashMap<>(); |
96 | - private final ConcurrentHashMap<String, List<VideoChanelDTO>> deviceNewChanel = new ConcurrentHashMap<>(); | 100 | + |
101 | + private final ConcurrentHashMap<String, List<VideoChanelDTO>> deviceNewChanel = | ||
102 | + new ConcurrentHashMap<>(); | ||
97 | private static final Map<String, ISIPRequestProcessor> requestProcessorMap = | 103 | private static final Map<String, ISIPRequestProcessor> requestProcessorMap = |
98 | new ConcurrentHashMap<>(); | 104 | new ConcurrentHashMap<>(); |
99 | private static final Map<String, ISIPResponseProcessor> responseProcessorMap = | 105 | private static final Map<String, ISIPResponseProcessor> responseProcessorMap = |
@@ -101,6 +107,7 @@ public class SIPProcessorObserver extends SIPRequestProcessorParent | @@ -101,6 +107,7 @@ public class SIPProcessorObserver extends SIPRequestProcessorParent | ||
101 | private static ITimeoutProcessor timeoutProcessor; | 107 | private static ITimeoutProcessor timeoutProcessor; |
102 | 108 | ||
103 | private final SipSubscribe sipSubscribe; | 109 | private final SipSubscribe sipSubscribe; |
110 | + | ||
104 | /** | 111 | /** |
105 | * 添加 request订阅 | 112 | * 添加 request订阅 |
106 | * | 113 | * |
@@ -159,7 +166,7 @@ public class SIPProcessorObserver extends SIPRequestProcessorParent | @@ -159,7 +166,7 @@ public class SIPProcessorObserver extends SIPRequestProcessorParent | ||
159 | CSeqHeader cseqHeader = (CSeqHeader) responseEvent.getResponse().getHeader(CSeqHeader.NAME); | 166 | CSeqHeader cseqHeader = (CSeqHeader) responseEvent.getResponse().getHeader(CSeqHeader.NAME); |
160 | String methodName = cseqHeader.getMethod(); | 167 | String methodName = cseqHeader.getMethod(); |
161 | SIPResponse request = (SIPResponse) responseEvent.getResponse(); | 168 | SIPResponse request = (SIPResponse) responseEvent.getResponse(); |
162 | - log.debug( | 169 | + log.info( |
163 | "收到ResponseEvent,方法类型【{}】,状态码【{}】,事件内容【{}】", | 170 | "收到ResponseEvent,方法类型【{}】,状态码【{}】,事件内容【{}】", |
164 | methodName, | 171 | methodName, |
165 | status, | 172 | status, |
@@ -178,8 +185,11 @@ public class SIPProcessorObserver extends SIPRequestProcessorParent | @@ -178,8 +185,11 @@ public class SIPProcessorObserver extends SIPRequestProcessorParent | ||
178 | default: | 185 | default: |
179 | log.debug("不支持的响应类型【{}】", method); | 186 | log.debug("不支持的响应类型【{}】", method); |
180 | } | 187 | } |
181 | - if (status != Response.UNAUTHORIZED && responseEvent.getResponse() != null && sipSubscribe.getOkSubscribesSize() > 0 ) { | ||
182 | - CallIdHeader callIdHeader = (CallIdHeader)responseEvent.getResponse().getHeader(CallIdHeader.NAME); | 188 | + if (status != Response.UNAUTHORIZED |
189 | + && responseEvent.getResponse() != null | ||
190 | + && sipSubscribe.getOkSubscribesSize() > 0) { | ||
191 | + CallIdHeader callIdHeader = | ||
192 | + (CallIdHeader) responseEvent.getResponse().getHeader(CallIdHeader.NAME); | ||
183 | if (callIdHeader != null) { | 193 | if (callIdHeader != null) { |
184 | SipSubscribe.Event subscribe = sipSubscribe.getOkSubscribe(callIdHeader.getCallId()); | 194 | SipSubscribe.Event subscribe = sipSubscribe.getOkSubscribe(callIdHeader.getCallId()); |
185 | if (subscribe != null) { | 195 | if (subscribe != null) { |
@@ -192,20 +202,26 @@ public class SIPProcessorObserver extends SIPRequestProcessorParent | @@ -192,20 +202,26 @@ public class SIPProcessorObserver extends SIPRequestProcessorParent | ||
192 | } else if ((status >= Response.TRYING) && (status < Response.OK)) { | 202 | } else if ((status >= Response.TRYING) && (status < Response.OK)) { |
193 | // 增加其它无需回复的响应,如101、180等 | 203 | // 增加其它无需回复的响应,如101、180等 |
194 | } else { | 204 | } else { |
195 | - log.error("收到ResponseEvent,设备【{}】,状态码【{}】,失败原因【{}】,ResponseEvent内容【{}】",response.getHeader(FromHeader.NAME),status, response.getReasonPhrase(),response.getRawContent() == null ? null : new String(response.getRawContent())); | ||
196 | - if (responseEvent.getResponse() != null && sipSubscribe.getErrorSubscribesSize() > 0 ) { | ||
197 | - CallIdHeader callIdHeader = (CallIdHeader)responseEvent.getResponse().getHeader(CallIdHeader.NAME); | ||
198 | - if (callIdHeader != null) { | ||
199 | - SipSubscribe.Event subscribe = sipSubscribe.getErrorSubscribe(callIdHeader.getCallId()); | ||
200 | - if (subscribe != null) { | ||
201 | - SipSubscribe.EventResult eventResult = new SipSubscribe.EventResult(responseEvent); | ||
202 | - subscribe.response(eventResult); | ||
203 | - sipSubscribe.removeErrorSubscribe(callIdHeader.getCallId()); | ||
204 | - } | 205 | + log.error( |
206 | + "收到ResponseEvent,设备【{}】,状态码【{}】,失败原因【{}】,ResponseEvent内容【{}】", | ||
207 | + response.getHeader(FromHeader.NAME), | ||
208 | + status, | ||
209 | + response.getReasonPhrase(), | ||
210 | + response.getRawContent() == null ? null : new String(response.getRawContent())); | ||
211 | + if (responseEvent.getResponse() != null && sipSubscribe.getErrorSubscribesSize() > 0) { | ||
212 | + CallIdHeader callIdHeader = | ||
213 | + (CallIdHeader) responseEvent.getResponse().getHeader(CallIdHeader.NAME); | ||
214 | + if (callIdHeader != null) { | ||
215 | + SipSubscribe.Event subscribe = sipSubscribe.getErrorSubscribe(callIdHeader.getCallId()); | ||
216 | + if (subscribe != null) { | ||
217 | + SipSubscribe.EventResult eventResult = new SipSubscribe.EventResult(responseEvent); | ||
218 | + subscribe.response(eventResult); | ||
219 | + sipSubscribe.removeErrorSubscribe(callIdHeader.getCallId()); | ||
205 | } | 220 | } |
221 | + } | ||
206 | } | 222 | } |
207 | if (responseEvent.getDialog() != null) { | 223 | if (responseEvent.getDialog() != null) { |
208 | - responseEvent.getDialog().delete(); | 224 | + responseEvent.getDialog().delete(); |
209 | } | 225 | } |
210 | } | 226 | } |
211 | } | 227 | } |
@@ -219,7 +235,7 @@ public class SIPProcessorObserver extends SIPRequestProcessorParent | @@ -219,7 +235,7 @@ public class SIPProcessorObserver extends SIPRequestProcessorParent | ||
219 | public void processRequest(RequestEvent requestEvent) { | 235 | public void processRequest(RequestEvent requestEvent) { |
220 | String methodName = requestEvent.getRequest().getMethod(); | 236 | String methodName = requestEvent.getRequest().getMethod(); |
221 | SIPRequest request = (SIPRequest) requestEvent.getRequest(); | 237 | SIPRequest request = (SIPRequest) requestEvent.getRequest(); |
222 | - log.debug( | 238 | + log.info( |
223 | "收到RequestEvent,方法类型【{}】,事件内容【{}】", | 239 | "收到RequestEvent,方法类型【{}】,事件内容【{}】", |
224 | methodName, | 240 | methodName, |
225 | request.getRawContent() == null ? null : new String(request.getRawContent())); | 241 | request.getRawContent() == null ? null : new String(request.getRawContent())); |
@@ -307,14 +323,15 @@ public class SIPProcessorObserver extends SIPRequestProcessorParent | @@ -307,14 +323,15 @@ public class SIPProcessorObserver extends SIPRequestProcessorParent | ||
307 | */ | 323 | */ |
308 | void processResponseMessage(GbtDeviceSessionCtx ctx, ResponseEvent msg) {} | 324 | void processResponseMessage(GbtDeviceSessionCtx ctx, ResponseEvent msg) {} |
309 | 325 | ||
310 | - private String cameraAddress(SIPRequest request){ | 326 | + private String cameraAddress(SIPRequest request) { |
311 | RemoteAddressInfo remoteAddressInfo = | 327 | RemoteAddressInfo remoteAddressInfo = |
312 | - TKSipUtils.getRemoteAddressFromRequest( | ||
313 | - request, userSetting.getSipUseSourceIpAsRemoteAddress()); | 328 | + TKSipUtils.getRemoteAddressFromRequest( |
329 | + request, userSetting.getSipUseSourceIpAsRemoteAddress()); | ||
314 | String hostAddress = remoteAddressInfo.getIp(); | 330 | String hostAddress = remoteAddressInfo.getIp(); |
315 | int remotePort = remoteAddressInfo.getPort(); | 331 | int remotePort = remoteAddressInfo.getPort(); |
316 | return hostAddress + ":" + remotePort; | 332 | return hostAddress + ":" + remotePort; |
317 | } | 333 | } |
334 | + | ||
318 | /** | 335 | /** |
319 | * 处理请求事件的MESSAGE消息,根据XML数据的根节点名称进行分发 | 336 | * 处理请求事件的MESSAGE消息,根据XML数据的根节点名称进行分发 |
320 | * | 337 | * |
@@ -342,7 +359,8 @@ public class SIPProcessorObserver extends SIPRequestProcessorParent | @@ -342,7 +359,8 @@ public class SIPProcessorObserver extends SIPRequestProcessorParent | ||
342 | } | 359 | } |
343 | if (ctx != null) { | 360 | if (ctx != null) { |
344 | if (!ctx.getHostAddress().equals(cameraAddress(request))) { | 361 | if (!ctx.getHostAddress().equals(cameraAddress(request))) { |
345 | - log.trace("摄像头【{}/{}】IP或端口已过期,断开连接", ctx.getDeviceInfo().getDeviceName(),ctx.getCameraCode()); | 362 | + log.trace( |
363 | + "摄像头【{}/{}】IP或端口已过期,断开连接", ctx.getDeviceInfo().getDeviceName(), ctx.getCameraCode()); | ||
346 | deviceSessions.remove(ctx.getCameraCode()); | 364 | deviceSessions.remove(ctx.getCameraCode()); |
347 | responseAck(request, Response.OK); | 365 | responseAck(request, Response.OK); |
348 | return; | 366 | return; |
@@ -454,7 +472,7 @@ public class SIPProcessorObserver extends SIPRequestProcessorParent | @@ -454,7 +472,7 @@ public class SIPProcessorObserver extends SIPRequestProcessorParent | ||
454 | transportService.deregisterSession(ds.getSessionInfo()); | 472 | transportService.deregisterSession(ds.getSessionInfo()); |
455 | transportService.process(ds.getSessionInfo(), SESSION_EVENT_MSG_CLOSED, null); | 473 | transportService.process(ds.getSessionInfo(), SESSION_EVENT_MSG_CLOSED, null); |
456 | try { | 474 | try { |
457 | - cameraResponseRequest(ds, request, null,null); | 475 | + cameraResponseRequest(ds, request, null, null); |
458 | } catch (InvalidArgumentException | ParseException | SipException e) { | 476 | } catch (InvalidArgumentException | ParseException | SipException e) { |
459 | throw new RuntimeException(e); | 477 | throw new RuntimeException(e); |
460 | } | 478 | } |
@@ -515,24 +533,25 @@ public class SIPProcessorObserver extends SIPRequestProcessorParent | @@ -515,24 +533,25 @@ public class SIPProcessorObserver extends SIPRequestProcessorParent | ||
515 | case DeviceInfo: | 533 | case DeviceInfo: |
516 | SipDeviceDTO cameraInfoDTO = TKXmlUtil.cameraInfoBuilder(rootElement); | 534 | SipDeviceDTO cameraInfoDTO = TKXmlUtil.cameraInfoBuilder(rootElement); |
517 | cameraInfoDTO.setHostAddress(request.getViaHost() + ":" + request.getViaPort()); | 535 | cameraInfoDTO.setHostAddress(request.getViaHost() + ":" + request.getViaPort()); |
536 | + cameraInfoDTO.setMediaServerId(mediaConfig.getMediaServerId()); | ||
518 | byte[] cameraMsgBytes = encodingService.encode(cameraInfoDTO); | 537 | byte[] cameraMsgBytes = encodingService.encode(cameraInfoDTO); |
519 | msgBuilder.setContext(ByteString.copyFrom(cameraMsgBytes)); | 538 | msgBuilder.setContext(ByteString.copyFrom(cameraMsgBytes)); |
520 | break; | 539 | break; |
521 | case Catalog: | 540 | case Catalog: |
522 | List<VideoChanelDTO> channelDTO = TKXmlUtil.channelInfoBuilder(devSession, rootElement); | 541 | List<VideoChanelDTO> channelDTO = TKXmlUtil.channelInfoBuilder(devSession, rootElement); |
523 | String cameraCode = devSession.getCameraCode(); | 542 | String cameraCode = devSession.getCameraCode(); |
524 | - int channelNum =1; | ||
525 | - if(!channelDTO.isEmpty()){ | ||
526 | - channelNum = channelDTO.get(0).getSumNum(); | ||
527 | - List<VideoChanelDTO> itemChanel = new ArrayList<>(); | ||
528 | - if(deviceNewChanel.containsKey(cameraCode)){ | ||
529 | - itemChanel =deviceNewChanel.get(cameraCode); | ||
530 | - }else{ | ||
531 | - deviceNewChanel.put(cameraCode,itemChanel); | ||
532 | - } | ||
533 | - itemChanel.addAll(channelDTO); | ||
534 | - } | ||
535 | - if(channelNum == deviceNewChanel.get(cameraCode).size()){ | 543 | + int channelNum = 1; |
544 | + if (!channelDTO.isEmpty()) { | ||
545 | + channelNum = channelDTO.get(0).getSumNum(); | ||
546 | + List<VideoChanelDTO> itemChanel = new ArrayList<>(); | ||
547 | + if (deviceNewChanel.containsKey(cameraCode)) { | ||
548 | + itemChanel = deviceNewChanel.get(cameraCode); | ||
549 | + } else { | ||
550 | + deviceNewChanel.put(cameraCode, itemChanel); | ||
551 | + } | ||
552 | + itemChanel.addAll(channelDTO); | ||
553 | + } | ||
554 | + if (channelNum == deviceNewChanel.get(cameraCode).size()) { | ||
536 | byte[] channaelMsgBytes = encodingService.encode(deviceNewChanel.get(cameraCode)); | 555 | byte[] channaelMsgBytes = encodingService.encode(deviceNewChanel.get(cameraCode)); |
537 | msgBuilder.setContext(ByteString.copyFrom(channaelMsgBytes)); | 556 | msgBuilder.setContext(ByteString.copyFrom(channaelMsgBytes)); |
538 | deviceNewChanel.remove(cameraCode); | 557 | deviceNewChanel.remove(cameraCode); |
@@ -644,7 +663,7 @@ public class SIPProcessorObserver extends SIPRequestProcessorParent | @@ -644,7 +663,7 @@ public class SIPProcessorObserver extends SIPRequestProcessorParent | ||
644 | return; | 663 | return; |
645 | } | 664 | } |
646 | DeviceProfile profile = msg.getDeviceProfile(); | 665 | DeviceProfile profile = msg.getDeviceProfile(); |
647 | - if(profile.getTransportType() != DeviceTransportType.GBT28181){ | 666 | + if (profile.getTransportType() != DeviceTransportType.GBT28181) { |
648 | return; | 667 | return; |
649 | } | 668 | } |
650 | GbtDeviceSessionCtx deviceSessionCtx = | 669 | GbtDeviceSessionCtx deviceSessionCtx = |
@@ -698,12 +717,12 @@ public class SIPProcessorObserver extends SIPRequestProcessorParent | @@ -698,12 +717,12 @@ public class SIPProcessorObserver extends SIPRequestProcessorParent | ||
698 | .build(); | 717 | .build(); |
699 | commanderService.queryDeviceInfo(deviceSessionCtx, deviceInfoHeader); | 718 | commanderService.queryDeviceInfo(deviceSessionCtx, deviceInfoHeader); |
700 | int sn = (int) ((Math.random() * 9 + 1) * 100000); | 719 | int sn = (int) ((Math.random() * 9 + 1) * 100000); |
701 | - rpcCameraChannel(deviceSessionCtx,sn); | 720 | + rpcCameraChannel(deviceSessionCtx, sn); |
702 | } catch (InvalidArgumentException | SipException | ParseException e) { | 721 | } catch (InvalidArgumentException | SipException | ParseException e) { |
703 | throw new RuntimeException(e); | 722 | throw new RuntimeException(e); |
704 | } | 723 | } |
705 | 724 | ||
706 | - // transportService.getCallbackExecutor().execute(() -> | 725 | + // transportService.getCallbackExecutor().execute(() -> |
707 | // processQueueMessage(ctx)); //this callback will execute in Producer worker thread and | 726 | // processQueueMessage(ctx)); //this callback will execute in Producer worker thread and |
708 | // hard or blocking work have to be submitted to the separate thread. | 727 | // hard or blocking work have to be submitted to the separate thread. |
709 | } | 728 | } |
@@ -735,9 +754,6 @@ public class SIPProcessorObserver extends SIPRequestProcessorParent | @@ -735,9 +754,6 @@ public class SIPProcessorObserver extends SIPRequestProcessorParent | ||
735 | // sipSender.transmitRequest(hostAddress, finalResponse); | 754 | // sipSender.transmitRequest(hostAddress, finalResponse); |
736 | } | 755 | } |
737 | 756 | ||
738 | - | ||
739 | - | ||
740 | - | ||
741 | /** | 757 | /** |
742 | * 向超时订阅发送消息 | 758 | * 向超时订阅发送消息 |
743 | * | 759 | * |
@@ -792,10 +808,12 @@ public class SIPProcessorObserver extends SIPRequestProcessorParent | @@ -792,10 +808,12 @@ public class SIPProcessorObserver extends SIPRequestProcessorParent | ||
792 | 808 | ||
793 | String channelId = rpcParamVal(rpcBody, FastIotConstants.ZLMediaBody.CHANNEL_ID); | 809 | String channelId = rpcParamVal(rpcBody, FastIotConstants.ZLMediaBody.CHANNEL_ID); |
794 | 810 | ||
795 | - switch (VideoMethodEnum.valueOf(methodType)){ | 811 | + switch (VideoMethodEnum.valueOf(methodType)) { |
796 | case BYE: | 812 | case BYE: |
797 | - SipMessageHeaderDTO messageHeaderDTO = JacksonUtil.convertValue(rpcBody.get(FastIotConstants.ZLMediaBody.MSG_HEADER),SipMessageHeaderDTO.class); | ||
798 | - commanderService.streamByeCmd(devSession,messageHeaderDTO,channelId); | 813 | + SipMessageHeaderDTO messageHeaderDTO = |
814 | + JacksonUtil.convertValue( | ||
815 | + rpcBody.get(FastIotConstants.ZLMediaBody.MSG_HEADER), SipMessageHeaderDTO.class); | ||
816 | + commanderService.streamByeCmd(devSession, messageHeaderDTO, channelId); | ||
799 | break; | 817 | break; |
800 | case INVITE: | 818 | case INVITE: |
801 | JsonNode mediaInform = rpcBody.get(FastIotConstants.ZLMediaBody.MEDIA); | 819 | JsonNode mediaInform = rpcBody.get(FastIotConstants.ZLMediaBody.MEDIA); |
@@ -807,64 +825,81 @@ public class SIPProcessorObserver extends SIPRequestProcessorParent | @@ -807,64 +825,81 @@ public class SIPProcessorObserver extends SIPRequestProcessorParent | ||
807 | String stream = rpcParamVal(rpcBody, FastIotConstants.ZLMediaBody.SSRCINFO_STREAM); | 825 | String stream = rpcParamVal(rpcBody, FastIotConstants.ZLMediaBody.SSRCINFO_STREAM); |
808 | 826 | ||
809 | ObjectNode responseJson = JacksonUtil.newObjectNode(); | 827 | ObjectNode responseJson = JacksonUtil.newObjectNode(); |
810 | - responseJson.put(FastIotConstants.ZLMediaBody.SSRCINFO_STREAM,stream); | ||
811 | - responseJson.put(FastIotConstants.ZLMediaBody.SSRCINFO_PORT,ssrcPort); | ||
812 | - responseJson.put(FastIotConstants.ZLMediaBody.SSRCINFO_SSRC,ssrc); | ||
813 | - responseJson.set(FastIotConstants.ZLMediaBody.MEDIA,mediaInform); | ||
814 | - responseJson.put(FastIotConstants.ZLMediaBody.CAMERA_CODE,cameraCode); | ||
815 | - | 828 | + responseJson.put(FastIotConstants.ZLMediaBody.SSRCINFO_STREAM, stream); |
829 | + responseJson.put(FastIotConstants.ZLMediaBody.SSRCINFO_PORT, ssrcPort); | ||
830 | + responseJson.put(FastIotConstants.ZLMediaBody.SSRCINFO_SSRC, ssrc); | ||
831 | + responseJson.set(FastIotConstants.ZLMediaBody.MEDIA, mediaInform); | ||
832 | + responseJson.put(FastIotConstants.ZLMediaBody.CAMERA_CODE, cameraCode); | ||
816 | 833 | ||
817 | SipMessageHeaderDTO sipMessageHeaderDTO = | 834 | SipMessageHeaderDTO sipMessageHeaderDTO = |
818 | - SipMessageHeaderDTO.builder() | ||
819 | - .viaTag(TKSipUtils.getNewViaTag()) | ||
820 | - .fromTag(TKSipUtils.getNewViaTag()) | ||
821 | - .toTag(null) | ||
822 | - .build(); | 835 | + SipMessageHeaderDTO.builder() |
836 | + .viaTag(TKSipUtils.getNewViaTag()) | ||
837 | + .fromTag(TKSipUtils.getNewViaTag()) | ||
838 | + .toTag(null) | ||
839 | + .build(); | ||
823 | 840 | ||
824 | commanderService.previewStreamCmd( | 841 | commanderService.previewStreamCmd( |
825 | - devSession, sipMessageHeaderDTO, sdpIp, ssrc, ssrcPort, channelId, | ||
826 | - e -> { | ||
827 | - // TODO: 2023/10/13 命令下发失败,需要流媒体处理的业务逻辑 | ||
828 | - | ||
829 | -// responseJson.set(FastIotConstants.ZLMediaBody.MSG_HEADER, JacksonUtil.valueToTree(e)); | ||
830 | - String contentString = JacksonUtil.toString(responseJson); | ||
831 | - log.warn("命令下发【失败】,响应给流媒体的数据【{}】",contentString); | ||
832 | - transportService.process(devSession.getSessionInfo(), | ||
833 | - TransportProtos.ToDeviceRpcResponseMsg.newBuilder() | ||
834 | - .setRequestId(rpcRequest.getRequestId()).setError(e.msg).build(), TransportServiceCallback.EMPTY); | ||
835 | - }, | ||
836 | - e -> { | ||
837 | - // TODO: 2023/10/13 命令下发成功,需要流媒体处理的业务逻辑 | ||
838 | - transportService.process(devSession.getSessionInfo(), rpcRequest, RpcStatus.SENT, TransportServiceCallback.EMPTY); | ||
839 | - | ||
840 | - | ||
841 | - responseJson.put(FastIotConstants.ZLMediaBody.CALL_ID,e.callId); | ||
842 | - ResponseEvent responseEvent = (ResponseEvent) e.event; | ||
843 | - SIPResponse response = (SIPResponse) responseEvent.getResponse(); | ||
844 | - SipMessageHeaderDTO sipMessage = | ||
845 | - SipMessageHeaderDTO.builder() | ||
846 | - .callId(response.getCallIdHeader().getCallId()) | ||
847 | - .fromTag(response.getFromTag()) | ||
848 | - .toTag(response.getToTag()) | ||
849 | - .viaBranch(response.getTopmostViaHeader().getBranch()) | ||
850 | - .build(); | ||
851 | - responseJson.set(FastIotConstants.ZLMediaBody.MSG_HEADER, JacksonUtil.valueToTree(sipMessage)); | ||
852 | - String contentString = new String(responseEvent.getResponse().getRawContent()); | ||
853 | - responseJson.put(FastIotConstants.ZLMediaBody.MSG_CONTEXT, contentString); | ||
854 | - responseJson.put(FastIotConstants.ZLMediaBody.SESSION_TYPE,SessionTypeEnum.PLAY.name()); | ||
855 | - responseJson.put(FastIotConstants.ZLMediaBody.CHANNEL_ID,channelId); | ||
856 | - responseJson.put(FastIotConstants.ZLMediaBody.SSRC_CHECK,devSession.isSsrcCheck()); | ||
857 | - String responseStr = JacksonUtil.toString(responseJson); | ||
858 | - log.warn("命令下发【成功】,CallId是否一致【{}】,响应给流媒体的数据【{}】",e.callId.equals(response.getCallIdHeader().getCallId()),responseStr); | ||
859 | - TransportProtos.ToDeviceRpcResponseMsg.Builder builder = TransportProtos.ToDeviceRpcResponseMsg.newBuilder(); | ||
860 | - builder.setRequestId(rpcRequest.getRequestId()).setPayload(responseStr); | ||
861 | - transportService.process(devSession.getSessionInfo(), | ||
862 | - builder.build(), TransportServiceCallback.EMPTY); | ||
863 | - | ||
864 | - }); | 842 | + devSession, |
843 | + sipMessageHeaderDTO, | ||
844 | + sdpIp, | ||
845 | + ssrc, | ||
846 | + ssrcPort, | ||
847 | + channelId, | ||
848 | + e -> { | ||
849 | + // TODO: 2023/10/13 命令下发失败,需要流媒体处理的业务逻辑 | ||
850 | + | ||
851 | + // responseJson.set(FastIotConstants.ZLMediaBody.MSG_HEADER, | ||
852 | + // JacksonUtil.valueToTree(e)); | ||
853 | + String contentString = JacksonUtil.toString(responseJson); | ||
854 | + log.warn("命令下发【失败】,响应给流媒体的数据【{}】", contentString); | ||
855 | + transportService.process( | ||
856 | + devSession.getSessionInfo(), | ||
857 | + TransportProtos.ToDeviceRpcResponseMsg.newBuilder() | ||
858 | + .setRequestId(rpcRequest.getRequestId()) | ||
859 | + .setError(e.msg) | ||
860 | + .build(), | ||
861 | + TransportServiceCallback.EMPTY); | ||
862 | + }, | ||
863 | + e -> { | ||
864 | + // TODO: 2023/10/13 命令下发成功,需要流媒体处理的业务逻辑 | ||
865 | + transportService.process( | ||
866 | + devSession.getSessionInfo(), | ||
867 | + rpcRequest, | ||
868 | + RpcStatus.SENT, | ||
869 | + TransportServiceCallback.EMPTY); | ||
870 | + | ||
871 | + responseJson.put(FastIotConstants.ZLMediaBody.CALL_ID, e.callId); | ||
872 | + ResponseEvent responseEvent = (ResponseEvent) e.event; | ||
873 | + SIPResponse response = (SIPResponse) responseEvent.getResponse(); | ||
874 | + SipMessageHeaderDTO sipMessage = | ||
875 | + SipMessageHeaderDTO.builder() | ||
876 | + .callId(response.getCallIdHeader().getCallId()) | ||
877 | + .fromTag(response.getFromTag()) | ||
878 | + .toTag(response.getToTag()) | ||
879 | + .viaBranch(response.getTopmostViaHeader().getBranch()) | ||
880 | + .build(); | ||
881 | + responseJson.set( | ||
882 | + FastIotConstants.ZLMediaBody.MSG_HEADER, JacksonUtil.valueToTree(sipMessage)); | ||
883 | + String contentString = new String(responseEvent.getResponse().getRawContent()); | ||
884 | + responseJson.put(FastIotConstants.ZLMediaBody.MSG_CONTEXT, contentString); | ||
885 | + responseJson.put( | ||
886 | + FastIotConstants.ZLMediaBody.SESSION_TYPE, SessionTypeEnum.PLAY.name()); | ||
887 | + responseJson.put(FastIotConstants.ZLMediaBody.CHANNEL_ID, channelId); | ||
888 | + responseJson.put(FastIotConstants.ZLMediaBody.SSRC_CHECK, devSession.isSsrcCheck()); | ||
889 | + String responseStr = JacksonUtil.toString(responseJson); | ||
890 | + log.warn( | ||
891 | + "命令下发【成功】,CallId是否一致【{}】,响应给流媒体的数据【{}】", | ||
892 | + e.callId.equals(response.getCallIdHeader().getCallId()), | ||
893 | + responseStr); | ||
894 | + TransportProtos.ToDeviceRpcResponseMsg.Builder builder = | ||
895 | + TransportProtos.ToDeviceRpcResponseMsg.newBuilder(); | ||
896 | + builder.setRequestId(rpcRequest.getRequestId()).setPayload(responseStr); | ||
897 | + transportService.process( | ||
898 | + devSession.getSessionInfo(), builder.build(), TransportServiceCallback.EMPTY); | ||
899 | + }); | ||
865 | break; | 900 | break; |
866 | case MESSAGE: | 901 | case MESSAGE: |
867 | - toDeviceRpcMessage(devSession,channelId,rpcBody); | 902 | + toDeviceRpcMessage(devSession, channelId, rpcBody); |
868 | break; | 903 | break; |
869 | } | 904 | } |
870 | } catch (InvalidArgumentException | SipException | ParseException e) { | 905 | } catch (InvalidArgumentException | SipException | ParseException e) { |
@@ -873,47 +908,54 @@ public class SIPProcessorObserver extends SIPRequestProcessorParent | @@ -873,47 +908,54 @@ public class SIPProcessorObserver extends SIPRequestProcessorParent | ||
873 | } | 908 | } |
874 | } | 909 | } |
875 | 910 | ||
876 | - private void toDeviceRpcMessage(GbtDeviceSessionCtx devSession,String channelId,JsonNode rpcBody) throws InvalidArgumentException, ParseException, SipException { | 911 | + private void toDeviceRpcMessage( |
912 | + GbtDeviceSessionCtx devSession, String channelId, JsonNode rpcBody) | ||
913 | + throws InvalidArgumentException, ParseException, SipException { | ||
877 | SipMessageHeaderDTO controlHeaderDTO = | 914 | SipMessageHeaderDTO controlHeaderDTO = |
878 | - SipMessageHeaderDTO.builder() | ||
879 | - .viaTag(TKSipUtils.getNewViaTag()) | ||
880 | - .fromTag(TKSipUtils.getNewViaTag()) | ||
881 | - .toTag(null) | ||
882 | - .build(); | 915 | + SipMessageHeaderDTO.builder() |
916 | + .viaTag(TKSipUtils.getNewViaTag()) | ||
917 | + .fromTag(TKSipUtils.getNewViaTag()) | ||
918 | + .toTag(null) | ||
919 | + .build(); | ||
883 | String msgType = rpcBody.get(FastIotConstants.ZLMediaBody.MSG_TYPE).asText(); | 920 | String msgType = rpcBody.get(FastIotConstants.ZLMediaBody.MSG_TYPE).asText(); |
884 | - switch (VideoXmlEnum.valueOf(msgType)){ | 921 | + switch (VideoXmlEnum.valueOf(msgType)) { |
885 | case Control: | 922 | case Control: |
886 | - PTZCmdDTO ptzCmdDTO = JacksonUtil.convertValue(rpcBody.get(FastIotConstants.ZLMediaBody.MSG_CONTEXT),PTZCmdDTO.class); | ||
887 | - commanderService.controlPtzCmd(channelId,devSession,controlHeaderDTO,ptzCmdDTO); | 923 | + PTZCmdDTO ptzCmdDTO = |
924 | + JacksonUtil.convertValue( | ||
925 | + rpcBody.get(FastIotConstants.ZLMediaBody.MSG_CONTEXT), PTZCmdDTO.class); | ||
926 | + commanderService.controlPtzCmd(channelId, devSession, controlHeaderDTO, ptzCmdDTO); | ||
888 | break; | 927 | break; |
889 | case Query: | 928 | case Query: |
890 | int sn = rpcBody.get(FastIotConstants.ZLMediaBody.MSG_CONTEXT).intValue(); | 929 | int sn = rpcBody.get(FastIotConstants.ZLMediaBody.MSG_CONTEXT).intValue(); |
891 | - rpcCameraChannel(devSession,sn); | 930 | + rpcCameraChannel(devSession, sn); |
892 | } | 931 | } |
893 | } | 932 | } |
894 | 933 | ||
895 | /** | 934 | /** |
896 | * 查询设备通道信息 | 935 | * 查询设备通道信息 |
936 | + * | ||
897 | * @throws InvalidArgumentException | 937 | * @throws InvalidArgumentException |
898 | * @throws SipException | 938 | * @throws SipException |
899 | * @throws ParseException | 939 | * @throws ParseException |
900 | */ | 940 | */ |
901 | - private void rpcCameraChannel(GbtDeviceSessionCtx deviceSessionCtx,int sn) throws InvalidArgumentException, SipException, ParseException { | 941 | + private void rpcCameraChannel(GbtDeviceSessionCtx deviceSessionCtx, int sn) |
942 | + throws InvalidArgumentException, SipException, ParseException { | ||
902 | SipMessageHeaderDTO catalogHeader = | 943 | SipMessageHeaderDTO catalogHeader = |
903 | - SipMessageHeaderDTO.builder() | ||
904 | - .viaTag(TKSipUtils.getNewViaTag()) | ||
905 | - .fromTag(TKSipUtils.getNewFromTag()) | ||
906 | - .build(); | 944 | + SipMessageHeaderDTO.builder() |
945 | + .viaTag(TKSipUtils.getNewViaTag()) | ||
946 | + .fromTag(TKSipUtils.getNewFromTag()) | ||
947 | + .build(); | ||
907 | commanderService.queryCatalog( | 948 | commanderService.queryCatalog( |
908 | - deviceSessionCtx, | ||
909 | - catalogHeader, | ||
910 | - sn, | ||
911 | - ev -> { | ||
912 | - String errorMsg = String.format("同步通道失败,错误码: %s, %s", ev.statusCode, ev.msg); | ||
913 | - // catalogResponseMessageHandler.setChannelSyncEnd(device.getDeviceId(), | ||
914 | - // errorMsg); | ||
915 | - }); | 949 | + deviceSessionCtx, |
950 | + catalogHeader, | ||
951 | + sn, | ||
952 | + ev -> { | ||
953 | + String errorMsg = String.format("同步通道失败,错误码: %s, %s", ev.statusCode, ev.msg); | ||
954 | + // catalogResponseMessageHandler.setChannelSyncEnd(device.getDeviceId(), | ||
955 | + // errorMsg); | ||
956 | + }); | ||
916 | } | 957 | } |
958 | + | ||
917 | private String rpcParamVal(JsonNode rpcBody, String key) { | 959 | private String rpcParamVal(JsonNode rpcBody, String key) { |
918 | if (rpcBody.has(key)) { | 960 | if (rpcBody.has(key)) { |
919 | return rpcBody.get(key).asText(); | 961 | return rpcBody.get(key).asText(); |
common/transport/gbt28181/src/main/java/org/thingsboard/server/transport/gbt28181/sip/processor/SIPProvider.java
renamed from
common/transport/gbt28181/src/main/java/org/thingsboard/server/transport/SIPProvider.java
common/transport/gbt28181/src/main/java/org/thingsboard/server/transport/gbt28181/sip/processor/SIPRequestProcessorParent.java
renamed from
common/transport/gbt28181/src/main/java/org/thingsboard/server/transport/gbt28181/SIPRequestProcessorParent.java
1 | -package org.thingsboard.server.transport.gbt28181; | 1 | +package org.thingsboard.server.transport.gbt28181.sip.processor; |
2 | 2 | ||
3 | import gov.nist.javax.sip.message.SIPRequest; | 3 | import gov.nist.javax.sip.message.SIPRequest; |
4 | import gov.nist.javax.sip.message.SIPResponse; | 4 | import gov.nist.javax.sip.message.SIPResponse; |
@@ -20,7 +20,7 @@ import org.dom4j.DocumentException; | @@ -20,7 +20,7 @@ import org.dom4j.DocumentException; | ||
20 | import org.dom4j.Element; | 20 | import org.dom4j.Element; |
21 | import org.dom4j.io.SAXReader; | 21 | import org.dom4j.io.SAXReader; |
22 | import org.springframework.beans.factory.annotation.Autowired; | 22 | import org.springframework.beans.factory.annotation.Autowired; |
23 | -import org.thingsboard.server.transport.SIPSender; | 23 | +import org.thingsboard.server.transport.cmd.SIPSender; |
24 | import org.thingsboard.server.transport.util.TKSipUtils; | 24 | import org.thingsboard.server.transport.util.TKSipUtils; |
25 | 25 | ||
26 | /** 处理接收IPCamera发来的SIP协议请求消息 */ | 26 | /** 处理接收IPCamera发来的SIP协议请求消息 */ |
common/transport/gbt28181/src/main/java/org/thingsboard/server/transport/gbt28181/sip/processor/TimeoutProcessorImpl.java
renamed from
common/transport/gbt28181/src/main/java/org/thingsboard/server/transport/process/timeout/TimeoutProcessorImpl.java
1 | -package org.thingsboard.server.transport.process.timeout; | 1 | +package org.thingsboard.server.transport.gbt28181.sip.processor; |
2 | 2 | ||
3 | import javax.sip.TimeoutEvent; | 3 | import javax.sip.TimeoutEvent; |
4 | import javax.sip.header.CallIdHeader; | 4 | import javax.sip.header.CallIdHeader; |
@@ -8,8 +8,6 @@ import org.springframework.beans.factory.InitializingBean; | @@ -8,8 +8,6 @@ import org.springframework.beans.factory.InitializingBean; | ||
8 | import org.springframework.beans.factory.annotation.Autowired; | 8 | import org.springframework.beans.factory.annotation.Autowired; |
9 | import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; | 9 | import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; |
10 | import org.springframework.stereotype.Component; | 10 | import org.springframework.stereotype.Component; |
11 | -import org.thingsboard.server.transport.gbt28181.ITimeoutProcessor; | ||
12 | -import org.thingsboard.server.transport.SIPProcessorObserver; | ||
13 | import org.thingsboard.server.transport.gbt28181.SipSubscribe; | 11 | import org.thingsboard.server.transport.gbt28181.SipSubscribe; |
14 | 12 | ||
15 | @Component | 13 | @Component |
1 | +package org.thingsboard.server.transport.gbt28181.zlm; | ||
2 | + | ||
3 | +import com.google.protobuf.ByteString; | ||
4 | +import java.net.InetAddress; | ||
5 | +import java.net.UnknownHostException; | ||
6 | +import java.util.List; | ||
7 | +import lombok.Getter; | ||
8 | +import lombok.RequiredArgsConstructor; | ||
9 | +import lombok.extern.slf4j.Slf4j; | ||
10 | +import org.springframework.beans.factory.annotation.Value; | ||
11 | +import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; | ||
12 | +import org.springframework.boot.context.event.ApplicationReadyEvent; | ||
13 | +import org.springframework.context.event.EventListener; | ||
14 | +import org.springframework.core.annotation.Order; | ||
15 | +import org.springframework.stereotype.Component; | ||
16 | +import org.thingsboard.common.util.JacksonUtil; | ||
17 | +import org.thingsboard.server.common.data.StringUtils; | ||
18 | +import org.thingsboard.server.common.data.yunteng.constant.FastIotConstants; | ||
19 | +import org.thingsboard.server.common.data.yunteng.core.cache.CacheUtils; | ||
20 | +import org.thingsboard.server.common.data.yunteng.utils.DataUtils; | ||
21 | +import org.thingsboard.server.common.transport.TransportService; | ||
22 | +import org.thingsboard.server.common.transport.util.DataDecodingEncodingService; | ||
23 | +import org.thingsboard.server.gen.transport.TransportProtos; | ||
24 | +import org.thingsboard.server.transport.config.MediaConfig; | ||
25 | +import org.thingsboard.server.transport.config.SipConfig; | ||
26 | + | ||
27 | +@Component() | ||
28 | +@Slf4j | ||
29 | +@RequiredArgsConstructor | ||
30 | +@ConditionalOnExpression( | ||
31 | + "'${service.type:null}'=='tb-transport' || ('${service.type:null}'=='monolith' && '${transport.api_enabled:true}'=='true' && '${transport.gbt28181.enabled}'=='true')") | ||
32 | +public class ZLMediaKitStateRunner { | ||
33 | + private final MediaConfig mediaConfig; | ||
34 | + private final SipConfig sipConfig; | ||
35 | + private final DataDecodingEncodingService encodingService; | ||
36 | + private final CacheUtils cacheUtils; | ||
37 | + | ||
38 | + @Value("${transport.gbt28181.media.defaultStateCheckIntervalInSec}") | ||
39 | + @Getter | ||
40 | + private int defaultStateCheckIntervalInSec; | ||
41 | + | ||
42 | + private final TransportService transportService; | ||
43 | + | ||
44 | + @EventListener(ApplicationReadyEvent.class) | ||
45 | + @Order(value = 3) | ||
46 | + public void init(ApplicationReadyEvent applicationReadyEvent) throws UnknownHostException { | ||
47 | + TransportProtos.Gbt28181MediaServerMsg.Builder msgBuilder = | ||
48 | + TransportProtos.Gbt28181MediaServerMsg.newBuilder(); | ||
49 | + cacheUtils.put( | ||
50 | + FastIotConstants.CacheSipKey.TK_SIP_CACHE_NAME, | ||
51 | + mediaConfig.getMediaServerId(), | ||
52 | + sipConfig.getDomain()); | ||
53 | + if (StringUtils.isEmpty(mediaConfig.getHookIp())) { | ||
54 | + mediaConfig.setHookIp(sipConfig.getIp().split(",")[0]); | ||
55 | + } | ||
56 | + if (StringUtils.isEmpty(mediaConfig.getStreamIp())) { | ||
57 | + mediaConfig.setStreamIp(mediaConfig.getIp()); | ||
58 | + } | ||
59 | + String sdpIp = mediaConfig.getSdpIp(); | ||
60 | + if (StringUtils.isEmpty(sdpIp)) { | ||
61 | + sdpIp = mediaConfig.getIp(); | ||
62 | + } else if (!DataUtils.isIPAddress(sdpIp)) { | ||
63 | + sdpIp = InetAddress.getByName(sdpIp).getHostAddress(); | ||
64 | + } | ||
65 | + mediaConfig.setSdpIp(sdpIp); | ||
66 | + byte[] mediaMsgBytes = encodingService.encode(JacksonUtil.valueToTree(mediaConfig)); | ||
67 | + msgBuilder.setProfile(ByteString.copyFrom(mediaMsgBytes)); | ||
68 | + // 从数据库获取所有的流媒体信息 | ||
69 | + List<TransportProtos.Gbt28181MediaServerMsg> dtoList = | ||
70 | + transportService.freshGtb28181Media(msgBuilder.build()); | ||
71 | + } | ||
72 | +} |
@@ -13,9 +13,7 @@ import lombok.Getter; | @@ -13,9 +13,7 @@ import lombok.Getter; | ||
13 | import lombok.Setter; | 13 | import lombok.Setter; |
14 | import lombok.extern.slf4j.Slf4j; | 14 | import lombok.extern.slf4j.Slf4j; |
15 | import org.thingsboard.server.common.transport.session.DeviceAwareSessionContext; | 15 | import org.thingsboard.server.common.transport.session.DeviceAwareSessionContext; |
16 | -import org.thingsboard.server.transport.GbtTransportContext; | ||
17 | - | ||
18 | -import javax.sip.RequestEvent; | 16 | +import org.thingsboard.server.transport.gbt28181.session.GbtTransportContext; |
19 | 17 | ||
20 | /** | 18 | /** |
21 | * @author Andrew Shvayka | 19 | * @author Andrew Shvayka |
@@ -10,10 +10,10 @@ import javax.sip.SipFactory; | @@ -10,10 +10,10 @@ import javax.sip.SipFactory; | ||
10 | import javax.sip.header.UserAgentHeader; | 10 | import javax.sip.header.UserAgentHeader; |
11 | import org.apache.commons.lang3.RandomStringUtils; | 11 | import org.apache.commons.lang3.RandomStringUtils; |
12 | import org.springframework.util.ObjectUtils; | 12 | import org.springframework.util.ObjectUtils; |
13 | -import org.thingsboard.server.common.data.yunteng.config.media.ThingsKitVersionConfig; | ||
14 | import org.thingsboard.server.common.data.yunteng.dto.sip.PTZCmdDTO; | 13 | import org.thingsboard.server.common.data.yunteng.dto.sip.PTZCmdDTO; |
15 | import org.thingsboard.server.common.data.yunteng.dto.sip.VideoChanelDTO; | 14 | import org.thingsboard.server.common.data.yunteng.dto.sip.VideoChanelDTO; |
16 | -import org.thingsboard.server.transport.info.RemoteAddressInfo; | 15 | +import org.thingsboard.server.transport.config.ThingsKitVersionConfig; |
16 | +import org.thingsboard.server.transport.gbt28181.auth.RemoteAddressInfo; | ||
17 | 17 | ||
18 | public class TKSipUtils { | 18 | public class TKSipUtils { |
19 | public static String getNewMessageViaBranchTag() { | 19 | public static String getNewMessageViaBranchTag() { |
@@ -55,14 +55,14 @@ public class TKSipUtils { | @@ -55,14 +55,14 @@ public class TKSipUtils { | ||
55 | builder.append(strTmp, 0, 2); | 55 | builder.append(strTmp, 0, 2); |
56 | strTmp = String.format("%X", combineCode2); | 56 | strTmp = String.format("%X", combineCode2); |
57 | builder.append(strTmp, 0, 1).append("0"); | 57 | builder.append(strTmp, 0, 1).append("0"); |
58 | - //计算校验码 | ||
59 | - int checkCode = (0XA5 + 0X0F + 0X01 + cmdCode + parameter1 + parameter2 + (combineCode2 & 0XF0)) % 0X100; | 58 | + // 计算校验码 |
59 | + int checkCode = | ||
60 | + (0XA5 + 0X0F + 0X01 + cmdCode + parameter1 + parameter2 + (combineCode2 & 0XF0)) % 0X100; | ||
60 | strTmp = String.format("%02X", checkCode); | 61 | strTmp = String.format("%02X", checkCode); |
61 | builder.append(strTmp, 0, 2); | 62 | builder.append(strTmp, 0, 2); |
62 | return builder.toString(); | 63 | return builder.toString(); |
63 | } | 64 | } |
64 | 65 | ||
65 | - | ||
66 | public static UserAgentHeader createUserAgentHeader(ThingsKitVersionConfig config) | 66 | public static UserAgentHeader createUserAgentHeader(ThingsKitVersionConfig config) |
67 | throws PeerUnavailableException, ParseException { | 67 | throws PeerUnavailableException, ParseException { |
68 | List<String> agentParam = new ArrayList<>(); | 68 | List<String> agentParam = new ArrayList<>(); |
1 | /** | 1 | /** |
2 | * Copyright © 2016-2022 The Thingsboard Authors | 2 | * Copyright © 2016-2022 The Thingsboard Authors |
3 | * | 3 | * |
4 | - * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | - * you may not use this file except in compliance with the License. | ||
6 | - * You may obtain a copy of the License at | 4 | + * <p>Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file |
5 | + * except in compliance with the License. You may obtain a copy of the License at | ||
7 | * | 6 | * |
8 | - * http://www.apache.org/licenses/LICENSE-2.0 | 7 | + * <p>http://www.apache.org/licenses/LICENSE-2.0 |
9 | * | 8 | * |
10 | - * Unless required by applicable law or agreed to in writing, software | ||
11 | - * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | - * See the License for the specific language governing permissions and | 9 | + * <p>Unless required by applicable law or agreed to in writing, software distributed under the |
10 | + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either | ||
11 | + * express or implied. See the License for the specific language governing permissions and | ||
14 | * limitations under the License. | 12 | * limitations under the License. |
15 | */ | 13 | */ |
16 | package org.thingsboard.server.common.transport; | 14 | package org.thingsboard.server.common.transport; |
17 | 15 | ||
16 | +import java.util.List; | ||
17 | +import java.util.concurrent.ExecutorService; | ||
18 | +import java.util.concurrent.atomic.AtomicInteger; | ||
18 | import org.thingsboard.server.common.data.DeviceProfile; | 19 | import org.thingsboard.server.common.data.DeviceProfile; |
19 | import org.thingsboard.server.common.data.DeviceTransportType; | 20 | import org.thingsboard.server.common.data.DeviceTransportType; |
20 | import org.thingsboard.server.common.data.rpc.RpcStatus; | 21 | import org.thingsboard.server.common.data.rpc.RpcStatus; |
@@ -40,10 +41,11 @@ import org.thingsboard.server.gen.transport.TransportProtos.GetSnmpDevicesRespon | @@ -40,10 +41,11 @@ import org.thingsboard.server.gen.transport.TransportProtos.GetSnmpDevicesRespon | ||
40 | import org.thingsboard.server.gen.transport.TransportProtos.LwM2MRequestMsg; | 41 | import org.thingsboard.server.gen.transport.TransportProtos.LwM2MRequestMsg; |
41 | import org.thingsboard.server.gen.transport.TransportProtos.LwM2MResponseMsg; | 42 | import org.thingsboard.server.gen.transport.TransportProtos.LwM2MResponseMsg; |
42 | import org.thingsboard.server.gen.transport.TransportProtos.PostAttributeMsg; | 43 | import org.thingsboard.server.gen.transport.TransportProtos.PostAttributeMsg; |
43 | -import org.thingsboard.server.gen.transport.TransportProtos.PostTelemetryMsg; | ||
44 | import org.thingsboard.server.gen.transport.TransportProtos.PostEventMsg; | 44 | import org.thingsboard.server.gen.transport.TransportProtos.PostEventMsg; |
45 | +import org.thingsboard.server.gen.transport.TransportProtos.PostTelemetryMsg; | ||
45 | import org.thingsboard.server.gen.transport.TransportProtos.ProvisionDeviceRequestMsg; | 46 | import org.thingsboard.server.gen.transport.TransportProtos.ProvisionDeviceRequestMsg; |
46 | import org.thingsboard.server.gen.transport.TransportProtos.ProvisionDeviceResponseMsg; | 47 | import org.thingsboard.server.gen.transport.TransportProtos.ProvisionDeviceResponseMsg; |
48 | +import org.thingsboard.server.gen.transport.TransportProtos.ScriptProto; | ||
47 | import org.thingsboard.server.gen.transport.TransportProtos.SessionEventMsg; | 49 | import org.thingsboard.server.gen.transport.TransportProtos.SessionEventMsg; |
48 | import org.thingsboard.server.gen.transport.TransportProtos.SessionInfoProto; | 50 | import org.thingsboard.server.gen.transport.TransportProtos.SessionInfoProto; |
49 | import org.thingsboard.server.gen.transport.TransportProtos.SubscribeToAttributeUpdatesMsg; | 51 | import org.thingsboard.server.gen.transport.TransportProtos.SubscribeToAttributeUpdatesMsg; |
@@ -57,104 +59,140 @@ import org.thingsboard.server.gen.transport.TransportProtos.ValidateBasicMqttCre | @@ -57,104 +59,140 @@ import org.thingsboard.server.gen.transport.TransportProtos.ValidateBasicMqttCre | ||
57 | import org.thingsboard.server.gen.transport.TransportProtos.ValidateDeviceLwM2MCredentialsRequestMsg; | 59 | import org.thingsboard.server.gen.transport.TransportProtos.ValidateDeviceLwM2MCredentialsRequestMsg; |
58 | import org.thingsboard.server.gen.transport.TransportProtos.ValidateDeviceTokenRequestMsg; | 60 | import org.thingsboard.server.gen.transport.TransportProtos.ValidateDeviceTokenRequestMsg; |
59 | import org.thingsboard.server.gen.transport.TransportProtos.ValidateDeviceX509CertRequestMsg; | 61 | import org.thingsboard.server.gen.transport.TransportProtos.ValidateDeviceX509CertRequestMsg; |
60 | -import org.thingsboard.server.gen.transport.TransportProtos.ScriptProto; | ||
61 | 62 | ||
62 | -import java.util.List; | ||
63 | -import java.util.concurrent.ExecutorService; | ||
64 | -import java.util.concurrent.atomic.AtomicInteger; | ||
65 | - | ||
66 | -/** | ||
67 | - * Created by ashvayka on 04.10.18. | ||
68 | - */ | 63 | +/** Created by ashvayka on 04.10.18. */ |
69 | public interface TransportService { | 64 | public interface TransportService { |
70 | 65 | ||
71 | - GetEntityProfileResponseMsg getEntityProfile(GetEntityProfileRequestMsg msg); | ||
72 | - | ||
73 | - GetResourceResponseMsg getResource(GetResourceRequestMsg msg); | ||
74 | - | ||
75 | - GetSnmpDevicesResponseMsg getSnmpDevicesIds(GetSnmpDevicesRequestMsg requestMsg); | ||
76 | - | ||
77 | - GetDeviceResponseMsg getDevice(GetDeviceRequestMsg requestMsg); | ||
78 | - | ||
79 | - GetDeviceCredentialsResponseMsg getDeviceCredentials(GetDeviceCredentialsRequestMsg requestMsg); | 66 | + GetEntityProfileResponseMsg getEntityProfile(GetEntityProfileRequestMsg msg); |
80 | 67 | ||
68 | + GetResourceResponseMsg getResource(GetResourceRequestMsg msg); | ||
81 | 69 | ||
70 | + GetSnmpDevicesResponseMsg getSnmpDevicesIds(GetSnmpDevicesRequestMsg requestMsg); | ||
82 | 71 | ||
83 | - void process(DeviceTransportType transportType, ValidateDeviceTokenRequestMsg msg, | ||
84 | - TransportServiceCallback<ValidateDeviceCredentialsResponse> callback); | 72 | + GetDeviceResponseMsg getDevice(GetDeviceRequestMsg requestMsg); |
85 | 73 | ||
86 | - void process(DeviceTransportType transportType, ValidateBasicMqttCredRequestMsg msg, | ||
87 | - TransportServiceCallback<ValidateDeviceCredentialsResponse> callback); | 74 | + GetDeviceCredentialsResponseMsg getDeviceCredentials(GetDeviceCredentialsRequestMsg requestMsg); |
88 | 75 | ||
89 | - void process(DeviceTransportType transportType, ValidateDeviceX509CertRequestMsg msg, | ||
90 | - TransportServiceCallback<ValidateDeviceCredentialsResponse> callback); | 76 | + void process( |
77 | + DeviceTransportType transportType, | ||
78 | + ValidateDeviceTokenRequestMsg msg, | ||
79 | + TransportServiceCallback<ValidateDeviceCredentialsResponse> callback); | ||
91 | 80 | ||
92 | - void process(ValidateDeviceLwM2MCredentialsRequestMsg msg, | ||
93 | - TransportServiceCallback<ValidateDeviceCredentialsResponse> callback); | 81 | + void process( |
82 | + DeviceTransportType transportType, | ||
83 | + ValidateBasicMqttCredRequestMsg msg, | ||
84 | + TransportServiceCallback<ValidateDeviceCredentialsResponse> callback); | ||
94 | 85 | ||
95 | - void process(GetOrCreateDeviceFromGatewayRequestMsg msg, | ||
96 | - TransportServiceCallback<GetOrCreateDeviceFromGatewayResponse> callback); | 86 | + void process( |
87 | + DeviceTransportType transportType, | ||
88 | + ValidateDeviceX509CertRequestMsg msg, | ||
89 | + TransportServiceCallback<ValidateDeviceCredentialsResponse> callback); | ||
97 | 90 | ||
98 | - void process(ProvisionDeviceRequestMsg msg, | ||
99 | - TransportServiceCallback<ProvisionDeviceResponseMsg> callback); | 91 | + void process( |
92 | + ValidateDeviceLwM2MCredentialsRequestMsg msg, | ||
93 | + TransportServiceCallback<ValidateDeviceCredentialsResponse> callback); | ||
100 | 94 | ||
101 | - void onProfileUpdate(DeviceProfile deviceProfile); | 95 | + void process( |
96 | + GetOrCreateDeviceFromGatewayRequestMsg msg, | ||
97 | + TransportServiceCallback<GetOrCreateDeviceFromGatewayResponse> callback); | ||
102 | 98 | ||
103 | - void process(LwM2MRequestMsg msg, | ||
104 | - TransportServiceCallback<LwM2MResponseMsg> callback); | 99 | + void process( |
100 | + ProvisionDeviceRequestMsg msg, TransportServiceCallback<ProvisionDeviceResponseMsg> callback); | ||
105 | 101 | ||
106 | - void process(SessionInfoProto sessionInfo, SessionEventMsg msg, TransportServiceCallback<Void> callback); | 102 | + void onProfileUpdate(DeviceProfile deviceProfile); |
107 | 103 | ||
108 | - void process(SessionInfoProto sessionInfo, PostTelemetryMsg msg, TransportServiceCallback<Void> callback); | 104 | + void process(LwM2MRequestMsg msg, TransportServiceCallback<LwM2MResponseMsg> callback); |
109 | 105 | ||
110 | - void process(SessionInfoProto sessionInfo, PostAttributeMsg msg, TransportServiceCallback<Void> callback); | 106 | + void process( |
107 | + SessionInfoProto sessionInfo, SessionEventMsg msg, TransportServiceCallback<Void> callback); | ||
111 | 108 | ||
109 | + void process( | ||
110 | + SessionInfoProto sessionInfo, PostTelemetryMsg msg, TransportServiceCallback<Void> callback); | ||
112 | 111 | ||
113 | - void process(SessionInfoProto sessionInfo, GetAttributeRequestMsg msg, TransportServiceCallback<Void> callback); | 112 | + void process( |
113 | + SessionInfoProto sessionInfo, PostAttributeMsg msg, TransportServiceCallback<Void> callback); | ||
114 | 114 | ||
115 | - void process(SessionInfoProto sessionInfo, SubscribeToAttributeUpdatesMsg msg, TransportServiceCallback<Void> callback); | 115 | + void process( |
116 | + SessionInfoProto sessionInfo, | ||
117 | + GetAttributeRequestMsg msg, | ||
118 | + TransportServiceCallback<Void> callback); | ||
116 | 119 | ||
117 | - void process(SessionInfoProto sessionInfo, SubscribeToRPCMsg msg, TransportServiceCallback<Void> callback); | 120 | + void process( |
121 | + SessionInfoProto sessionInfo, | ||
122 | + SubscribeToAttributeUpdatesMsg msg, | ||
123 | + TransportServiceCallback<Void> callback); | ||
118 | 124 | ||
119 | - void process(SessionInfoProto sessionInfo, ToDeviceRpcResponseMsg msg, TransportServiceCallback<Void> callback); | 125 | + void process( |
126 | + SessionInfoProto sessionInfo, SubscribeToRPCMsg msg, TransportServiceCallback<Void> callback); | ||
120 | 127 | ||
121 | - void process(SessionInfoProto sessionInfo, ToServerRpcRequestMsg msg, TransportServiceCallback<Void> callback); | 128 | + void process( |
129 | + SessionInfoProto sessionInfo, | ||
130 | + ToDeviceRpcResponseMsg msg, | ||
131 | + TransportServiceCallback<Void> callback); | ||
122 | 132 | ||
123 | - void process(SessionInfoProto sessionInfo, ToDeviceRpcRequestMsg msg, RpcStatus rpcStatus, TransportServiceCallback<Void> callback); | 133 | + void process( |
134 | + SessionInfoProto sessionInfo, | ||
135 | + ToServerRpcRequestMsg msg, | ||
136 | + TransportServiceCallback<Void> callback); | ||
124 | 137 | ||
125 | - void process(SessionInfoProto sessionInfo, SubscriptionInfoProto msg, TransportServiceCallback<Void> callback); | 138 | + void process( |
139 | + SessionInfoProto sessionInfo, | ||
140 | + ToDeviceRpcRequestMsg msg, | ||
141 | + RpcStatus rpcStatus, | ||
142 | + TransportServiceCallback<Void> callback); | ||
126 | 143 | ||
127 | - void process(SessionInfoProto sessionInfo, ClaimDeviceMsg msg, TransportServiceCallback<Void> callback); | 144 | + void process( |
145 | + SessionInfoProto sessionInfo, | ||
146 | + SubscriptionInfoProto msg, | ||
147 | + TransportServiceCallback<Void> callback); | ||
128 | 148 | ||
129 | - void process(TransportToDeviceActorMsg msg, TransportServiceCallback<Void> callback); | 149 | + void process( |
150 | + SessionInfoProto sessionInfo, ClaimDeviceMsg msg, TransportServiceCallback<Void> callback); | ||
130 | 151 | ||
131 | - void process(SessionInfoProto sessionInfoProto, GetOtaPackageRequestMsg msg, TransportServiceCallback<GetOtaPackageResponseMsg> callback); | 152 | + void process(TransportToDeviceActorMsg msg, TransportServiceCallback<Void> callback); |
132 | 153 | ||
133 | - SessionMetaData registerAsyncSession(SessionInfoProto sessionInfo, SessionMsgListener listener); | 154 | + void process( |
155 | + SessionInfoProto sessionInfoProto, | ||
156 | + GetOtaPackageRequestMsg msg, | ||
157 | + TransportServiceCallback<GetOtaPackageResponseMsg> callback); | ||
134 | 158 | ||
135 | - SessionMetaData registerSyncSession(SessionInfoProto sessionInfo, SessionMsgListener listener, long timeout); | 159 | + SessionMetaData registerAsyncSession(SessionInfoProto sessionInfo, SessionMsgListener listener); |
136 | 160 | ||
137 | - void reportActivity(SessionInfoProto sessionInfo); | 161 | + SessionMetaData registerSyncSession( |
162 | + SessionInfoProto sessionInfo, SessionMsgListener listener, long timeout); | ||
138 | 163 | ||
139 | - void deregisterSession(SessionInfoProto sessionInfo); | 164 | + void reportActivity(SessionInfoProto sessionInfo); |
140 | 165 | ||
141 | - void log(SessionInfoProto sessionInfo, String msg); | 166 | + void deregisterSession(SessionInfoProto sessionInfo); |
142 | 167 | ||
143 | - void notifyAboutUplink(SessionInfoProto sessionInfo, TransportProtos.UplinkNotificationMsg build, TransportServiceCallback<Void> empty); | 168 | + void log(SessionInfoProto sessionInfo, String msg); |
144 | 169 | ||
145 | - ExecutorService getCallbackExecutor(); | 170 | + void notifyAboutUplink( |
171 | + SessionInfoProto sessionInfo, | ||
172 | + TransportProtos.UplinkNotificationMsg build, | ||
173 | + TransportServiceCallback<Void> empty); | ||
146 | 174 | ||
147 | - boolean hasSession(SessionInfoProto sessionInfo); | 175 | + ExecutorService getCallbackExecutor(); |
148 | 176 | ||
149 | - void createGaugeStats(String openConnections, AtomicInteger connectionsCounter); | 177 | + boolean hasSession(SessionInfoProto sessionInfo); |
150 | 178 | ||
179 | + void createGaugeStats(String openConnections, AtomicInteger connectionsCounter); | ||
151 | 180 | ||
181 | + // Thingskit function:begin | ||
182 | + List<ScriptProto> getScripts(ScriptProto msg); | ||
152 | 183 | ||
184 | + void process( | ||
185 | + SessionInfoProto sessionInfo, | ||
186 | + PostEventMsg msg, | ||
187 | + TransportServiceCallback<Void> callback, | ||
188 | + String topicName); | ||
153 | 189 | ||
190 | + void process( | ||
191 | + SessionInfoProto sessionInfo, | ||
192 | + TransportProtos.Gbt28181RequestMsg msg, | ||
193 | + TransportServiceCallback<TransportProtos.Gbt28181ResponseMsg> callback); | ||
154 | 194 | ||
155 | - //Thingskit function:begin | ||
156 | - List<ScriptProto> getScripts(ScriptProto msg); | ||
157 | - void process(SessionInfoProto sessionInfo, PostEventMsg msg, TransportServiceCallback<Void> callback,String topicName); | ||
158 | - void process(SessionInfoProto sessionInfo, TransportProtos.Gbt28181RequestMsg msg, TransportServiceCallback<TransportProtos.Gbt28181ResponseMsg> callback); | ||
159 | - //Thingskit function:end | 195 | + List<TransportProtos.Gbt28181MediaServerMsg> freshGtb28181Media( |
196 | + TransportProtos.Gbt28181MediaServerMsg msg); | ||
197 | + // Thingskit function:end | ||
160 | } | 198 | } |