Commit 0db46d8cf1407c4d02a7dc59a7e480305c816706
Committed by
xp.Huang
1 parent
6b070a7f
refactor: GBT28181结构调整
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 | 36 | |
37 | 37 | @GetMapping("/start/{deviceId}/{channelId}") |
38 | 38 | @ApiOperation(value = "视频点播/预览") |
39 | -// @PreAuthorize("@check.checkPermissions({'SYS_ADMIN','PLATFORM_ADMIN','TENANT_ADMIN','CUSTOMER_USER'},{'api:yt:video:control:play'})") | |
40 | 39 | @PreAuthorize("hasAnyAuthority('SYS_ADMIN','PLATFORM_ADMIN','TENANT_ADMIN','CUSTOMER_USER')") |
41 | 40 | public DeferredResult<ResponseResult<StreamContentDTO>> startPlay( |
42 | 41 | @PathVariable("deviceId") String tbDeviceId, @PathVariable("channelId") String channelId) | ... | ... |
... | ... | @@ -3,16 +3,17 @@ package org.thingsboard.server.controller.yunteng.media; |
3 | 3 | import com.fasterxml.jackson.databind.JsonNode; |
4 | 4 | import io.swagger.annotations.Api; |
5 | 5 | import io.swagger.annotations.ApiOperation; |
6 | +import javax.servlet.http.HttpServletRequest; | |
6 | 7 | import lombok.RequiredArgsConstructor; |
7 | 8 | import lombok.extern.slf4j.Slf4j; |
9 | +import org.json.JSONObject; | |
8 | 10 | import org.springframework.web.bind.annotation.*; |
11 | +import org.springframework.web.context.request.async.DeferredResult; | |
9 | 12 | import org.thingsboard.server.common.data.exception.ThingsboardException; |
10 | 13 | import org.thingsboard.server.common.data.yunteng.constant.FastIotConstants; |
11 | -import org.thingsboard.server.common.data.yunteng.dto.DeviceDTO; | |
12 | 14 | import org.thingsboard.server.common.data.yunteng.dto.sip.VideoChanelDTO; |
13 | 15 | import org.thingsboard.server.common.data.yunteng.dto.sip.hook.param.*; |
14 | 16 | import org.thingsboard.server.controller.BaseController; |
15 | -import org.thingsboard.server.dao.yunteng.service.TkDeviceService; | |
16 | 17 | import org.thingsboard.server.dao.yunteng.service.media.TkMediaServerService; |
17 | 18 | import org.thingsboard.server.dao.yunteng.service.media.TkVideoChannelService; |
18 | 19 | import org.thingsboard.server.service.yunteng.media.TkVideoControlService; |
... | ... | @@ -57,21 +58,140 @@ public class ZLMediaKitHookController extends BaseController { |
57 | 58 | @ResponseBody |
58 | 59 | @PostMapping(value = "/on_stream_none_reader", produces = "application/json;charset=UTF-8") |
59 | 60 | @ApiOperation(value = "流无人观看时事件,用户可以通过此事件选择是否关闭无人看的流") |
60 | - public JsonNode onStreamNoneReader(@RequestBody OnStreamNoneReaderHookParam param) throws ThingsboardException { | |
61 | + public JsonNode onStreamNoneReader(@RequestBody OnStreamNoneReaderHookParam param) | |
62 | + throws ThingsboardException { | |
61 | 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 | 66 | String channelId = result.get(FastIotConstants.ZLMediaBody.CHANNEL_ID).asText(); |
64 | 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 | 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 | 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 | 12 | * limitations under the License. |
15 | 13 | */ |
16 | 14 | package org.thingsboard.server.service.transport; |
... | ... | @@ -37,7 +35,6 @@ import java.util.concurrent.locks.ReentrantLock; |
37 | 35 | import java.util.stream.Collectors; |
38 | 36 | import lombok.RequiredArgsConstructor; |
39 | 37 | import lombok.extern.slf4j.Slf4j; |
40 | -import org.apache.zookeeper.Op; | |
41 | 38 | import org.springframework.stereotype.Service; |
42 | 39 | import org.thingsboard.common.util.JacksonUtil; |
43 | 40 | import org.thingsboard.server.cache.ota.OtaPackageDataCache; |
... | ... | @@ -74,13 +71,15 @@ import org.thingsboard.server.common.data.relation.EntityRelation; |
74 | 71 | import org.thingsboard.server.common.data.security.DeviceCredentials; |
75 | 72 | import org.thingsboard.server.common.data.security.DeviceCredentialsType; |
76 | 73 | import org.thingsboard.server.common.data.yunteng.common.media.VideoStreamSessionManager; |
74 | +import org.thingsboard.server.common.data.yunteng.config.media.ZLMediaKitServerConfig; | |
77 | 75 | import org.thingsboard.server.common.data.yunteng.constant.FastIotConstants; |
78 | 76 | import org.thingsboard.server.common.data.yunteng.dto.DeviceDTO; |
79 | 77 | import org.thingsboard.server.common.data.yunteng.dto.TkDeviceScriptDTO; |
78 | +import org.thingsboard.server.common.data.yunteng.dto.sip.MediaServerDTO; | |
80 | 79 | import org.thingsboard.server.common.data.yunteng.dto.sip.SipDeviceDTO; |
81 | -import org.thingsboard.server.common.data.yunteng.dto.sip.SsrcTransactionDTO; | |
82 | 80 | import org.thingsboard.server.common.data.yunteng.dto.sip.VideoChanelDTO; |
83 | 81 | import org.thingsboard.server.common.data.yunteng.enums.VideoCmdEnum; |
82 | +import org.thingsboard.server.common.data.yunteng.utils.ZLMediaKitRestFulUtils; | |
84 | 83 | import org.thingsboard.server.common.msg.EncryptionUtil; |
85 | 84 | import org.thingsboard.server.common.msg.TbMsg; |
86 | 85 | import org.thingsboard.server.common.msg.TbMsgDataType; |
... | ... | @@ -99,6 +98,7 @@ import org.thingsboard.server.dao.yunteng.entities.TkVideoChannelEntity; |
99 | 98 | import org.thingsboard.server.dao.yunteng.service.TkDeviceScriptService; |
100 | 99 | import org.thingsboard.server.dao.yunteng.service.TkDeviceService; |
101 | 100 | import org.thingsboard.server.dao.yunteng.service.media.TkMediaServerNodeService; |
101 | +import org.thingsboard.server.dao.yunteng.service.media.TkMediaServerService; | |
102 | 102 | import org.thingsboard.server.dao.yunteng.service.media.TkVideoChannelService; |
103 | 103 | import org.thingsboard.server.gen.transport.TransportProtos; |
104 | 104 | import org.thingsboard.server.gen.transport.TransportProtos.DeviceInfoProto; |
... | ... | @@ -126,650 +126,891 @@ import org.thingsboard.server.service.install.DefaultSystemDataLoaderService; |
126 | 126 | import org.thingsboard.server.service.profile.TbDeviceProfileCache; |
127 | 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 | 130 | @Slf4j |
133 | 131 | @Service |
134 | 132 | @TbCoreComponent |
135 | 133 | @RequiredArgsConstructor |
136 | 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 | 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 | 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 | 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 | 915 | String cameraCode = sip.get(FastIotConstants.ZLMediaBody.CAMERA_CODE).asText(); |
754 | 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 | 721 | gbt28181: |
722 | 722 | # Enable/disable gbt28181 transport protocol. |
723 | 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 | 763 | tcp: |
725 | 764 | # Enable/disable tcp transport protocol. |
726 | 765 | enabled: "${TCP_ENABLED:true}" |
... | ... | @@ -1227,43 +1266,6 @@ logging: |
1227 | 1266 | frp: |
1228 | 1267 | server: |
1229 | 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 | 1270 | thingskit: |
1269 | 1271 | release: | ... | ... |
... | ... | @@ -680,6 +680,7 @@ message TransportApiRequestMsg { |
680 | 680 | //Thingskit function |
681 | 681 | ScriptProto script = 14; |
682 | 682 | Gbt28181RequestMsg gbt28181RequestMsg = 15; |
683 | + Gbt28181MediaServerMsg gbt28181MediaServerMsg = 16; | |
683 | 684 | } |
684 | 685 | |
685 | 686 | /* Response from ThingsBoard Core Service to Transport Service */ |
... | ... | @@ -698,6 +699,7 @@ message TransportApiResponseMsg { |
698 | 699 | //Thingskit function |
699 | 700 | repeated ScriptProto scriptsResponseMsg = 11; |
700 | 701 | Gbt28181ResponseMsg gbt28181ResponseMsg = 12; |
702 | + repeated Gbt28181MediaServerMsg gbt28181MediaServerMsg = 13; | |
701 | 703 | } |
702 | 704 | |
703 | 705 | /* Messages that are handled by ThingsBoard Core Service */ |
... | ... | @@ -826,5 +828,11 @@ message Gbt28181ResponseMsg{ |
826 | 828 | int64 entityIdMSB = 11; |
827 | 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 | 3 | import java.util.*; |
4 | 4 | import lombok.extern.slf4j.Slf4j; |
5 | 5 | import org.springframework.beans.factory.annotation.Autowired; |
6 | -import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; | |
7 | 6 | import org.springframework.stereotype.Component; |
8 | 7 | import org.thingsboard.server.common.data.yunteng.config.media.UserSetting; |
9 | 8 | import org.thingsboard.server.common.data.yunteng.constant.FastIotConstants; |
... | ... | @@ -88,12 +87,14 @@ public class VideoStreamSessionManager { |
88 | 87 | public Optional<SsrcTransactionDTO> getSsrcTransaction(String fullKey) { |
89 | 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 | 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 | 1 | package org.thingsboard.server.common.data.yunteng.config.media; |
2 | 2 | |
3 | 3 | import lombok.Data; |
4 | -import org.springframework.boot.context.properties.ConfigurationProperties; | |
5 | 4 | import org.springframework.stereotype.Component; |
6 | 5 | |
7 | -@ConfigurationProperties(prefix = "user-settings") | |
8 | 6 | @Component |
9 | 7 | @Data |
10 | 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 | 3 | import io.swagger.annotations.ApiModelProperty; |
4 | 4 | import lombok.Data; |
5 | 5 | import lombok.EqualsAndHashCode; |
6 | -import org.springframework.util.ObjectUtils; | |
7 | -import org.thingsboard.server.common.data.yunteng.config.media.ZLMediaKitServerConfig; | |
8 | 6 | import org.thingsboard.server.common.data.yunteng.dto.TenantDTO; |
9 | 7 | |
10 | 8 | @EqualsAndHashCode(callSuper = true) |
... | ... | @@ -63,11 +61,11 @@ public class MediaServerDTO extends TenantDTO { |
63 | 61 | @ApiModelProperty(value = "流媒体服务器的状态") |
64 | 62 | private boolean status; |
65 | 63 | |
66 | - @ApiModelProperty(value = "多端口RTP收流端口范围") | |
64 | + @ApiModelProperty(value = "RTP收流端口范围") | |
67 | 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 | 70 | @ApiModelProperty(value = "assist服务端口") |
73 | 71 | private Integer recordAssistPort; |
... | ... | @@ -81,33 +79,7 @@ public class MediaServerDTO extends TenantDTO { |
81 | 79 | @ApiModelProperty(value = "当前使用到的端口") |
82 | 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 | 1 | package org.thingsboard.server.common.data.yunteng.dto.sip; |
2 | 2 | |
3 | 3 | import io.swagger.annotations.ApiModelProperty; |
4 | +import java.io.Serializable; | |
4 | 5 | import lombok.Data; |
5 | 6 | import org.thingsboard.server.common.data.yunteng.constant.FastIotConstants; |
6 | 7 | |
7 | -import java.io.Serializable; | |
8 | - | |
9 | 8 | @Data |
10 | 9 | public class SipDeviceDTO implements Serializable { |
11 | 10 | @ApiModelProperty(value = "设备国标编号") |
... | ... | @@ -37,6 +36,7 @@ public class SipDeviceDTO implements Serializable { |
37 | 36 | |
38 | 37 | @ApiModelProperty(value = "是否开启ssrc校验,默认关闭,开启可以防止串流") |
39 | 38 | private boolean ssrcCheck = true; |
39 | + | |
40 | 40 | @ApiModelProperty(value = "生产厂商") |
41 | 41 | private String manufacturer; |
42 | 42 | |
... | ... | @@ -48,12 +48,13 @@ public class SipDeviceDTO implements Serializable { |
48 | 48 | |
49 | 49 | @ApiModelProperty(value = "固件版本") |
50 | 50 | private String firmware; |
51 | + | |
51 | 52 | public Integer getStreamModeForParam() { |
52 | 53 | if (FastIotConstants.StreamMode.UDP.equalsIgnoreCase(streamMode)) { |
53 | 54 | return 0; |
54 | - }else if (FastIotConstants.StreamMode.TCP_PASSIVE.equalsIgnoreCase(streamMode)) { | |
55 | + } else if (FastIotConstants.StreamMode.TCP_PASSIVE.equalsIgnoreCase(streamMode)) { | |
55 | 56 | return 1; |
56 | - }else if (FastIotConstants.StreamMode.TCP_ACTIVE.equalsIgnoreCase(streamMode)) { | |
57 | + } else if (FastIotConstants.StreamMode.TCP_ACTIVE.equalsIgnoreCase(streamMode)) { | |
57 | 58 | return 2; |
58 | 59 | } |
59 | 60 | return 0; | ... | ... |
... | ... | @@ -2,6 +2,8 @@ package org.thingsboard.server.common.data.yunteng.utils; |
2 | 2 | |
3 | 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 | 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 | 10 | import javax.sip.address.SipURI; |
11 | 11 | import javax.sip.header.*; |
12 | 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 | 18 | @Autowired private SipConfig sipConfig; |
21 | 19 | @Autowired protected ThingsKitVersionConfig thingsKitVersionConfig; |
22 | 20 | |
... | ... | @@ -41,7 +39,7 @@ public class AbstractSIPRequestProcess { |
41 | 39 | ViaHeader viaHeader = |
42 | 40 | sipFactory |
43 | 41 | .createHeaderFactory() |
44 | - .createViaHeader(SipLayer.getLocalIp(localIp), sipConfig.getPort(), transport, viaTag); | |
42 | + .createViaHeader(SipTransportService.getLocalIp(localIp), sipConfig.getPort(), transport, viaTag); | |
45 | 43 | viaHeader.setRPort(); |
46 | 44 | viaHeaders.add(viaHeader); |
47 | 45 | return viaHeaders; |
... | ... | @@ -78,7 +76,7 @@ public class AbstractSIPRequestProcess { |
78 | 76 | throws PeerUnavailableException, ParseException { |
79 | 77 | SipURI sipUri = |
80 | 78 | buildRequestLineSipUri( |
81 | - sipConfig.getId(), SipLayer.getLocalIp(localIp) + ":" + sipConfig.getPort()); | |
79 | + sipConfig.getId(), SipTransportService.getLocalIp(localIp) + ":" + sipConfig.getPort()); | |
82 | 80 | Address concatAddress = sipFactory.createAddressFactory().createAddress(sipUri); |
83 | 81 | return sipFactory.createHeaderFactory().createContactHeader(concatAddress); |
84 | 82 | } | ... | ... |
... | ... | @@ -15,12 +15,16 @@ import javax.sip.address.SipURI; |
15 | 15 | import javax.sip.header.*; |
16 | 16 | import javax.sip.message.Request; |
17 | 17 | import javax.sip.message.Response; |
18 | + | |
19 | +import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; | |
18 | 20 | import org.springframework.stereotype.Component; |
19 | 21 | import org.thingsboard.server.common.data.yunteng.dto.sip.SipMessageHeaderDTO; |
20 | 22 | import org.thingsboard.server.transport.session.GbtDeviceSessionCtx; |
21 | 23 | import org.thingsboard.server.transport.util.TKSipUtils; |
22 | 24 | |
23 | 25 | @Component |
26 | +@ConditionalOnExpression( | |
27 | + "'${service.type:null}'=='tb-transport' || ('${service.type:null}'=='monolith' && '${transport.api_enabled:true}'=='true' && '${transport.gbt28181.enabled}'=='true')") | |
24 | 28 | public class SIPRequestHeaderProcess extends AbstractSIPRequestProcess { |
25 | 29 | public Request createMessageRequest( |
26 | 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 | 3 | import gov.nist.javax.sip.SipProviderImpl; |
4 | 4 | import java.text.ParseException; |
... | ... | @@ -11,15 +11,18 @@ import javax.sip.message.Request; |
11 | 11 | import javax.sip.message.Response; |
12 | 12 | import lombok.extern.slf4j.Slf4j; |
13 | 13 | import org.springframework.beans.factory.annotation.Autowired; |
14 | +import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; | |
14 | 15 | import org.springframework.stereotype.Component; |
15 | 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 | 19 | import org.thingsboard.server.transport.gbt28181.SipSubscribe; |
19 | 20 | import org.thingsboard.server.transport.util.TKSipUtils; |
20 | 21 | |
21 | 22 | /** 发送SIP信息 */ |
22 | 23 | @Component |
24 | +@ConditionalOnExpression( | |
25 | + "'${service.type:null}'=='tb-transport' || ('${service.type:null}'=='monolith' && '${transport.api_enabled:true}'=='true' && '${transport.gbt28181.enabled}'=='true')") | |
23 | 26 | @Slf4j |
24 | 27 | public class SIPSender { |
25 | 28 | |
... | ... | @@ -80,7 +83,7 @@ public class SIPSender { |
80 | 83 | } |
81 | 84 | |
82 | 85 | SipProviderImpl sipProvider = |
83 | - TCP.equals(transport) ? SipLayer.getTcpSipProvider(ip) : SipLayer.getUdpSipProvider(ip); | |
86 | + TCP.equals(transport) ? SipTransportService.getTcpSipProvider(ip) : SipTransportService.getUdpSipProvider(ip); | |
84 | 87 | if (sipProvider == null) { |
85 | 88 | log.error("[发送信息失败] 未找到{}://{}的监听信息", transport, ip); |
86 | 89 | return; |
... | ... | @@ -94,23 +97,23 @@ public class SIPSender { |
94 | 97 | |
95 | 98 | public CallIdHeader getNewCallIdHeader(String ip, String transport) { |
96 | 99 | if (ObjectUtils.isEmpty(transport)) { |
97 | - return SipLayer.getUdpSipProvider().getNewCallId(); | |
100 | + return SipTransportService.getUdpSipProvider().getNewCallId(); | |
98 | 101 | } |
99 | 102 | SipProviderImpl sipProvider; |
100 | 103 | if (ObjectUtils.isEmpty(ip)) { |
101 | 104 | sipProvider = |
102 | 105 | transport.equalsIgnoreCase(TCP) |
103 | - ? SipLayer.getTcpSipProvider() | |
104 | - : SipLayer.getUdpSipProvider(); | |
106 | + ? SipTransportService.getTcpSipProvider() | |
107 | + : SipTransportService.getUdpSipProvider(); | |
105 | 108 | } else { |
106 | 109 | sipProvider = |
107 | 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 | 115 | if (sipProvider == null) { |
113 | - sipProvider = SipLayer.getUdpSipProvider(); | |
116 | + sipProvider = SipTransportService.getUdpSipProvider(); | |
114 | 117 | } |
115 | 118 | |
116 | 119 | if (sipProvider != null) { | ... | ... |
... | ... | @@ -13,8 +13,7 @@ import org.thingsboard.server.common.data.yunteng.config.media.UserSetting; |
13 | 13 | import org.thingsboard.server.common.data.yunteng.constant.FastIotConstants; |
14 | 14 | import org.thingsboard.server.common.data.yunteng.dto.sip.*; |
15 | 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 | 17 | import org.thingsboard.server.transport.gbt28181.SipSubscribe; |
19 | 18 | import org.thingsboard.server.transport.session.GbtDeviceSessionCtx; |
20 | 19 | import org.thingsboard.server.transport.util.TKSipUtils; |
... | ... | @@ -41,11 +40,11 @@ public class TKSipCommanderServiceImpl implements TKSipCommanderService { |
41 | 40 | sessionCtx.getCameraCode()); |
42 | 41 | CallIdHeader callIdHeader = |
43 | 42 | sipSender.getNewCallIdHeader( |
44 | - SipLayer.getLocalIp(sessionCtx.getLocalIp()), sessionCtx.getTransport()); | |
43 | + SipTransportService.getLocalIp(sessionCtx.getLocalIp()), sessionCtx.getTransport()); | |
45 | 44 | Request request = |
46 | 45 | headerProvider.createMessageRequest( |
47 | 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 | 50 | @Override |
... | ... | @@ -63,13 +62,13 @@ public class TKSipCommanderServiceImpl implements TKSipCommanderService { |
63 | 62 | deviceSessionCtx.getCameraCode()); |
64 | 63 | CallIdHeader callIdHeader = |
65 | 64 | sipSender.getNewCallIdHeader( |
66 | - SipLayer.getLocalIp(deviceSessionCtx.getLocalIp()), deviceSessionCtx.getTransport()); | |
65 | + SipTransportService.getLocalIp(deviceSessionCtx.getLocalIp()), deviceSessionCtx.getTransport()); | |
67 | 66 | Request request = |
68 | 67 | headerProvider.createMessageRequest( |
69 | 68 | deviceSessionCtx, sipMessageHeaderDTO, xmlContent, callIdHeader); |
70 | 69 | |
71 | 70 | sipSender.transmitRequest( |
72 | - SipLayer.getLocalIp(deviceSessionCtx.getLocalIp()), request, errorEvent); | |
71 | + SipTransportService.getLocalIp(deviceSessionCtx.getLocalIp()), request, errorEvent); | |
73 | 72 | } |
74 | 73 | |
75 | 74 | @Override |
... | ... | @@ -86,12 +85,12 @@ public class TKSipCommanderServiceImpl implements TKSipCommanderService { |
86 | 85 | ptzCmd); |
87 | 86 | CallIdHeader callIdHeader = |
88 | 87 | sipSender.getNewCallIdHeader( |
89 | - SipLayer.getLocalIp(deviceSessionCtx.getLocalIp()), deviceSessionCtx.getTransport()); | |
88 | + SipTransportService.getLocalIp(deviceSessionCtx.getLocalIp()), deviceSessionCtx.getTransport()); | |
90 | 89 | Request request = |
91 | 90 | headerProvider.createMessageRequest( |
92 | 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 | 96 | @Override |
... | ... | @@ -110,13 +109,13 @@ public class TKSipCommanderServiceImpl implements TKSipCommanderService { |
110 | 109 | |
111 | 110 | CallIdHeader callIdHeader = |
112 | 111 | sipSender.getNewCallIdHeader( |
113 | - SipLayer.getLocalIp(devSession.getLocalIp()), devSession.getTransport()); | |
112 | + SipTransportService.getLocalIp(devSession.getLocalIp()), devSession.getTransport()); | |
114 | 113 | Request request = |
115 | 114 | headerProvider.createInviteRequest( |
116 | 115 | devSession, sipMessageHeaderDTO, channelId, content, callIdHeader, ssrc); |
117 | 116 | |
118 | 117 | sipSender.transmitRequest( |
119 | - SipLayer.getLocalIp(devSession.getLocalIp()), request, errorEvent, okEvent); | |
118 | + SipTransportService.getLocalIp(devSession.getLocalIp()), request, errorEvent, okEvent); | |
120 | 119 | } |
121 | 120 | |
122 | 121 | @Override |
... | ... | @@ -144,7 +143,7 @@ public class TKSipCommanderServiceImpl implements TKSipCommanderService { |
144 | 143 | headerDTO.getViaTag(), |
145 | 144 | headerDTO.getFromTag(), |
146 | 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 | 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 | 3 | import lombok.Data; |
4 | +import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; | |
4 | 5 | import org.springframework.boot.context.properties.ConfigurationProperties; |
5 | 6 | import org.springframework.stereotype.Component; |
6 | 7 | |
7 | -@ConfigurationProperties(prefix = "sip") | |
8 | +@ConfigurationProperties(prefix = "transport.gbt28181.sip") | |
8 | 9 | @Component |
10 | +@ConditionalOnExpression( | |
11 | + "'${service.type:null}'=='tb-transport' || ('${service.type:null}'=='monolith' && '${transport.api_enabled:true}'=='true' && '${transport.gbt28181.enabled}'=='true')") | |
9 | 12 | @Data |
10 | 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 | 3 | import lombok.Data; |
4 | 4 | import org.springframework.beans.factory.annotation.Value; |
5 | +import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; | |
5 | 6 | import org.springframework.stereotype.Component; |
6 | 7 | |
7 | 8 | @Component |
9 | +@ConditionalOnExpression( | |
10 | + "'${service.type:null}'=='tb-transport' || ('${service.type:null}'=='monolith' && '${transport.api_enabled:true}'=='true' && '${transport.gbt28181.enabled}'=='true')") | |
8 | 11 | @Data |
9 | 12 | public class ThingsKitVersionConfig { |
10 | 13 | @Value("${thingskit.release.version}") | ... | ... |
... | ... | @@ -13,12 +13,15 @@ import javax.sip.header.CallIdHeader; |
13 | 13 | import javax.sip.message.Response; |
14 | 14 | import org.slf4j.Logger; |
15 | 15 | import org.slf4j.LoggerFactory; |
16 | +import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; | |
16 | 17 | import org.springframework.scheduling.annotation.Scheduled; |
17 | 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 | 21 | /** SIP订阅信息 */ |
21 | 22 | @Component |
23 | +@ConditionalOnExpression( | |
24 | + "'${service.type:null}'=='tb-transport' || ('${service.type:null}'=='monolith' && '${transport.api_enabled:true}'=='true' && '${transport.gbt28181.enabled}'=='true')") | |
22 | 25 | public class SipSubscribe { |
23 | 26 | |
24 | 27 | private final Logger logger = LoggerFactory.getLogger(SipSubscribe.class); | ... | ... |
... | ... | @@ -36,8 +36,6 @@ import javax.sip.header.HeaderFactory; |
36 | 36 | import javax.sip.header.WWWAuthenticateHeader; |
37 | 37 | import javax.sip.message.Request; |
38 | 38 | import javax.sip.message.Response; |
39 | -import org.slf4j.Logger; | |
40 | -import org.slf4j.LoggerFactory; | |
41 | 39 | |
42 | 40 | /** Implements the HTTP digest authentication method server side functionality. */ |
43 | 41 | public class DigestServerAuthenticationHelper { |
... | ... | @@ -99,6 +97,7 @@ public class DigestServerAuthenticationHelper { |
99 | 97 | } |
100 | 98 | return response; |
101 | 99 | } |
100 | + | |
102 | 101 | /** |
103 | 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 | 6 | public class RemoteAddressInfo { |
4 | 7 | private String ip; |
5 | 8 | private int port; |
... | ... | @@ -8,20 +11,4 @@ public class RemoteAddressInfo { |
8 | 11 | this.ip = ip; |
9 | 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 | 7 | import java.util.concurrent.ConcurrentHashMap; |
8 | 8 | import java.util.concurrent.TimeUnit; |
9 | 9 | |
10 | +import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; | |
10 | 11 | import org.springframework.scheduling.annotation.Scheduled; |
11 | 12 | import org.springframework.stereotype.Component; |
12 | 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 | 17 | import org.thingsboard.server.common.data.yunteng.enums.CatalogDataStatusEnum; |
17 | 18 | |
18 | 19 | @Component |
20 | +@ConditionalOnExpression( | |
21 | + "'${service.type:null}'=='tb-transport' || ('${service.type:null}'=='monolith' && '${transport.api_enabled:true}'=='true' && '${transport.gbt28181.enabled}'=='true')") | |
19 | 22 | public class CatalogDataCatch { |
20 | 23 | |
21 | 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 | 3 | import io.netty.handler.ssl.SslHandler; |
5 | -import java.net.InetSocketAddress; | |
6 | 4 | import java.util.concurrent.Executors; |
7 | 5 | import java.util.concurrent.ScheduledExecutorService; |
8 | 6 | import java.util.concurrent.atomic.AtomicInteger; |
... | ... | @@ -10,13 +8,11 @@ import javax.annotation.PostConstruct; |
10 | 8 | import lombok.Getter; |
11 | 9 | import lombok.Setter; |
12 | 10 | import lombok.extern.slf4j.Slf4j; |
13 | -import org.springframework.beans.factory.annotation.Autowired; | |
14 | 11 | import org.springframework.beans.factory.annotation.Value; |
15 | 12 | import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; |
16 | 13 | import org.springframework.stereotype.Component; |
17 | 14 | import org.thingsboard.common.util.ThingsBoardThreadFactory; |
18 | 15 | import org.thingsboard.server.common.transport.TransportContext; |
19 | -import org.thingsboard.server.transport.adaptors.GbtTransportAdaptor; | |
20 | 16 | |
21 | 17 | @Slf4j |
22 | 18 | @Component |
... | ... | @@ -24,8 +20,6 @@ import org.thingsboard.server.transport.adaptors.GbtTransportAdaptor; |
24 | 20 | "'${service.type:null}'=='tb-transport' || ('${service.type:null}'=='monolith' && '${transport.api_enabled:true}'=='true' && '${transport.gbt28181.enabled}'=='true')") |
25 | 21 | public class GbtTransportContext extends TransportContext { |
26 | 22 | |
27 | - /** 注入多种数据协议处理器,例如:modbus等 */ | |
28 | - @Getter @Autowired private GbtTransportAdaptor jsonAdaptor; | |
29 | 23 | |
30 | 24 | @Getter |
31 | 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 | 11 | * express or implied. See the License for the specific language governing permissions and |
12 | 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 | 16 | import gov.nist.javax.sip.SipProviderImpl; |
17 | 17 | import gov.nist.javax.sip.SipStackImpl; |
... | ... | @@ -26,20 +26,20 @@ import org.springframework.stereotype.Service; |
26 | 26 | import org.springframework.util.ObjectUtils; |
27 | 27 | import org.thingsboard.server.common.data.DataConstants; |
28 | 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 | 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 | 38 | @Slf4j |
38 | -public class SipLayer implements TbTransportService { | |
39 | +public class SipTransportService implements TbTransportService { | |
39 | 40 | private static final Map<String, SipProviderImpl> tcpSipProviderMap = new ConcurrentHashMap<>(); |
40 | 41 | private static final Map<String, SipProviderImpl> udpSipProviderMap = new ConcurrentHashMap<>(); |
41 | - @Autowired | |
42 | - private SIPProvider sipProvider; | |
42 | + @Autowired private SIPProvider sipProvider; | |
43 | 43 | |
44 | 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 | 3 | import java.util.EventObject; |
4 | 4 | import javax.sip.Dialog; |
5 | +import lombok.Getter; | |
6 | +import lombok.Setter; | |
5 | 7 | |
8 | +@Getter | |
9 | +@Setter | |
6 | 10 | public class DeviceNotFoundEvent extends EventObject { |
7 | 11 | |
8 | 12 | private String callId; |
... | ... | @@ -16,12 +20,4 @@ public class DeviceNotFoundEvent extends EventObject { |
16 | 20 | public DeviceNotFoundEvent(Dialog dialog) { |
17 | 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 | 3 | import static org.thingsboard.server.common.transport.service.DefaultTransportService.SESSION_EVENT_MSG_CLOSED; |
4 | 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 | 40 | import org.thingsboard.server.common.data.StringUtils; |
41 | 41 | import org.thingsboard.server.common.data.id.DeviceId; |
42 | 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 | 43 | import org.thingsboard.server.common.data.yunteng.config.media.UserSetting; |
46 | 44 | import org.thingsboard.server.common.data.yunteng.constant.FastIotConstants; |
47 | 45 | import org.thingsboard.server.common.data.yunteng.dto.sip.PTZCmdDTO; |
... | ... | @@ -58,11 +56,16 @@ import org.thingsboard.server.common.transport.auth.SessionInfoCreator; |
58 | 56 | import org.thingsboard.server.common.transport.auth.ValidateDeviceCredentialsResponse; |
59 | 57 | import org.thingsboard.server.common.transport.util.DataDecodingEncodingService; |
60 | 58 | import org.thingsboard.server.gen.transport.TransportProtos; |
59 | +import org.thingsboard.server.transport.gbt28181.session.GbtTransportContext; | |
61 | 60 | import org.thingsboard.server.transport.cmd.SIPRequestHeaderProcess; |
62 | 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 | 64 | import org.thingsboard.server.transport.gbt28181.*; |
64 | 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 | 69 | import org.thingsboard.server.transport.session.GbtDeviceSessionCtx; |
67 | 70 | import org.thingsboard.server.transport.util.TKSipUtils; |
68 | 71 | import org.thingsboard.server.transport.util.TKXmlUtil; |
... | ... | @@ -81,6 +84,7 @@ public class SIPProcessorObserver extends SIPRequestProcessorParent |
81 | 84 | |
82 | 85 | private final SIPRequestHeaderProcess headerProvider; |
83 | 86 | private final SipConfig sipConfig; |
87 | + private final MediaConfig mediaConfig; | |
84 | 88 | private final UserSetting userSetting; |
85 | 89 | private final TKSipCommanderService commanderService; |
86 | 90 | private final DataDecodingEncodingService encodingService; |
... | ... | @@ -93,7 +97,9 @@ public class SIPProcessorObserver extends SIPRequestProcessorParent |
93 | 97 | |
94 | 98 | @Getter |
95 | 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 | 103 | private static final Map<String, ISIPRequestProcessor> requestProcessorMap = |
98 | 104 | new ConcurrentHashMap<>(); |
99 | 105 | private static final Map<String, ISIPResponseProcessor> responseProcessorMap = |
... | ... | @@ -101,6 +107,7 @@ public class SIPProcessorObserver extends SIPRequestProcessorParent |
101 | 107 | private static ITimeoutProcessor timeoutProcessor; |
102 | 108 | |
103 | 109 | private final SipSubscribe sipSubscribe; |
110 | + | |
104 | 111 | /** |
105 | 112 | * 添加 request订阅 |
106 | 113 | * |
... | ... | @@ -159,7 +166,7 @@ public class SIPProcessorObserver extends SIPRequestProcessorParent |
159 | 166 | CSeqHeader cseqHeader = (CSeqHeader) responseEvent.getResponse().getHeader(CSeqHeader.NAME); |
160 | 167 | String methodName = cseqHeader.getMethod(); |
161 | 168 | SIPResponse request = (SIPResponse) responseEvent.getResponse(); |
162 | - log.debug( | |
169 | + log.info( | |
163 | 170 | "收到ResponseEvent,方法类型【{}】,状态码【{}】,事件内容【{}】", |
164 | 171 | methodName, |
165 | 172 | status, |
... | ... | @@ -178,8 +185,11 @@ public class SIPProcessorObserver extends SIPRequestProcessorParent |
178 | 185 | default: |
179 | 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 | 193 | if (callIdHeader != null) { |
184 | 194 | SipSubscribe.Event subscribe = sipSubscribe.getOkSubscribe(callIdHeader.getCallId()); |
185 | 195 | if (subscribe != null) { |
... | ... | @@ -192,20 +202,26 @@ public class SIPProcessorObserver extends SIPRequestProcessorParent |
192 | 202 | } else if ((status >= Response.TRYING) && (status < Response.OK)) { |
193 | 203 | // 增加其它无需回复的响应,如101、180等 |
194 | 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 | 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 | 235 | public void processRequest(RequestEvent requestEvent) { |
220 | 236 | String methodName = requestEvent.getRequest().getMethod(); |
221 | 237 | SIPRequest request = (SIPRequest) requestEvent.getRequest(); |
222 | - log.debug( | |
238 | + log.info( | |
223 | 239 | "收到RequestEvent,方法类型【{}】,事件内容【{}】", |
224 | 240 | methodName, |
225 | 241 | request.getRawContent() == null ? null : new String(request.getRawContent())); |
... | ... | @@ -307,14 +323,15 @@ public class SIPProcessorObserver extends SIPRequestProcessorParent |
307 | 323 | */ |
308 | 324 | void processResponseMessage(GbtDeviceSessionCtx ctx, ResponseEvent msg) {} |
309 | 325 | |
310 | - private String cameraAddress(SIPRequest request){ | |
326 | + private String cameraAddress(SIPRequest request) { | |
311 | 327 | RemoteAddressInfo remoteAddressInfo = |
312 | - TKSipUtils.getRemoteAddressFromRequest( | |
313 | - request, userSetting.getSipUseSourceIpAsRemoteAddress()); | |
328 | + TKSipUtils.getRemoteAddressFromRequest( | |
329 | + request, userSetting.getSipUseSourceIpAsRemoteAddress()); | |
314 | 330 | String hostAddress = remoteAddressInfo.getIp(); |
315 | 331 | int remotePort = remoteAddressInfo.getPort(); |
316 | 332 | return hostAddress + ":" + remotePort; |
317 | 333 | } |
334 | + | |
318 | 335 | /** |
319 | 336 | * 处理请求事件的MESSAGE消息,根据XML数据的根节点名称进行分发 |
320 | 337 | * |
... | ... | @@ -342,7 +359,8 @@ public class SIPProcessorObserver extends SIPRequestProcessorParent |
342 | 359 | } |
343 | 360 | if (ctx != null) { |
344 | 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 | 364 | deviceSessions.remove(ctx.getCameraCode()); |
347 | 365 | responseAck(request, Response.OK); |
348 | 366 | return; |
... | ... | @@ -454,7 +472,7 @@ public class SIPProcessorObserver extends SIPRequestProcessorParent |
454 | 472 | transportService.deregisterSession(ds.getSessionInfo()); |
455 | 473 | transportService.process(ds.getSessionInfo(), SESSION_EVENT_MSG_CLOSED, null); |
456 | 474 | try { |
457 | - cameraResponseRequest(ds, request, null,null); | |
475 | + cameraResponseRequest(ds, request, null, null); | |
458 | 476 | } catch (InvalidArgumentException | ParseException | SipException e) { |
459 | 477 | throw new RuntimeException(e); |
460 | 478 | } |
... | ... | @@ -515,24 +533,25 @@ public class SIPProcessorObserver extends SIPRequestProcessorParent |
515 | 533 | case DeviceInfo: |
516 | 534 | SipDeviceDTO cameraInfoDTO = TKXmlUtil.cameraInfoBuilder(rootElement); |
517 | 535 | cameraInfoDTO.setHostAddress(request.getViaHost() + ":" + request.getViaPort()); |
536 | + cameraInfoDTO.setMediaServerId(mediaConfig.getMediaServerId()); | |
518 | 537 | byte[] cameraMsgBytes = encodingService.encode(cameraInfoDTO); |
519 | 538 | msgBuilder.setContext(ByteString.copyFrom(cameraMsgBytes)); |
520 | 539 | break; |
521 | 540 | case Catalog: |
522 | 541 | List<VideoChanelDTO> channelDTO = TKXmlUtil.channelInfoBuilder(devSession, rootElement); |
523 | 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 | 555 | byte[] channaelMsgBytes = encodingService.encode(deviceNewChanel.get(cameraCode)); |
537 | 556 | msgBuilder.setContext(ByteString.copyFrom(channaelMsgBytes)); |
538 | 557 | deviceNewChanel.remove(cameraCode); |
... | ... | @@ -644,7 +663,7 @@ public class SIPProcessorObserver extends SIPRequestProcessorParent |
644 | 663 | return; |
645 | 664 | } |
646 | 665 | DeviceProfile profile = msg.getDeviceProfile(); |
647 | - if(profile.getTransportType() != DeviceTransportType.GBT28181){ | |
666 | + if (profile.getTransportType() != DeviceTransportType.GBT28181) { | |
648 | 667 | return; |
649 | 668 | } |
650 | 669 | GbtDeviceSessionCtx deviceSessionCtx = |
... | ... | @@ -698,12 +717,12 @@ public class SIPProcessorObserver extends SIPRequestProcessorParent |
698 | 717 | .build(); |
699 | 718 | commanderService.queryDeviceInfo(deviceSessionCtx, deviceInfoHeader); |
700 | 719 | int sn = (int) ((Math.random() * 9 + 1) * 100000); |
701 | - rpcCameraChannel(deviceSessionCtx,sn); | |
720 | + rpcCameraChannel(deviceSessionCtx, sn); | |
702 | 721 | } catch (InvalidArgumentException | SipException | ParseException e) { |
703 | 722 | throw new RuntimeException(e); |
704 | 723 | } |
705 | 724 | |
706 | - // transportService.getCallbackExecutor().execute(() -> | |
725 | + // transportService.getCallbackExecutor().execute(() -> | |
707 | 726 | // processQueueMessage(ctx)); //this callback will execute in Producer worker thread and |
708 | 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 | 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 | 808 | |
793 | 809 | String channelId = rpcParamVal(rpcBody, FastIotConstants.ZLMediaBody.CHANNEL_ID); |
794 | 810 | |
795 | - switch (VideoMethodEnum.valueOf(methodType)){ | |
811 | + switch (VideoMethodEnum.valueOf(methodType)) { | |
796 | 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 | 817 | break; |
800 | 818 | case INVITE: |
801 | 819 | JsonNode mediaInform = rpcBody.get(FastIotConstants.ZLMediaBody.MEDIA); |
... | ... | @@ -807,64 +825,81 @@ public class SIPProcessorObserver extends SIPRequestProcessorParent |
807 | 825 | String stream = rpcParamVal(rpcBody, FastIotConstants.ZLMediaBody.SSRCINFO_STREAM); |
808 | 826 | |
809 | 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 | 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 | 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 | 900 | break; |
866 | 901 | case MESSAGE: |
867 | - toDeviceRpcMessage(devSession,channelId,rpcBody); | |
902 | + toDeviceRpcMessage(devSession, channelId, rpcBody); | |
868 | 903 | break; |
869 | 904 | } |
870 | 905 | } catch (InvalidArgumentException | SipException | ParseException e) { |
... | ... | @@ -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 | 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 | 920 | String msgType = rpcBody.get(FastIotConstants.ZLMediaBody.MSG_TYPE).asText(); |
884 | - switch (VideoXmlEnum.valueOf(msgType)){ | |
921 | + switch (VideoXmlEnum.valueOf(msgType)) { | |
885 | 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 | 927 | break; |
889 | 928 | case Query: |
890 | 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 | 937 | * @throws InvalidArgumentException |
898 | 938 | * @throws SipException |
899 | 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 | 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 | 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 | 959 | private String rpcParamVal(JsonNode rpcBody, String key) { |
918 | 960 | if (rpcBody.has(key)) { |
919 | 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 | 3 | import gov.nist.javax.sip.message.SIPRequest; |
4 | 4 | import gov.nist.javax.sip.message.SIPResponse; |
... | ... | @@ -20,7 +20,7 @@ import org.dom4j.DocumentException; |
20 | 20 | import org.dom4j.Element; |
21 | 21 | import org.dom4j.io.SAXReader; |
22 | 22 | import org.springframework.beans.factory.annotation.Autowired; |
23 | -import org.thingsboard.server.transport.SIPSender; | |
23 | +import org.thingsboard.server.transport.cmd.SIPSender; | |
24 | 24 | import org.thingsboard.server.transport.util.TKSipUtils; |
25 | 25 | |
26 | 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 | 3 | import javax.sip.TimeoutEvent; |
4 | 4 | import javax.sip.header.CallIdHeader; |
... | ... | @@ -8,8 +8,6 @@ import org.springframework.beans.factory.InitializingBean; |
8 | 8 | import org.springframework.beans.factory.annotation.Autowired; |
9 | 9 | import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; |
10 | 10 | import org.springframework.stereotype.Component; |
11 | -import org.thingsboard.server.transport.gbt28181.ITimeoutProcessor; | |
12 | -import org.thingsboard.server.transport.SIPProcessorObserver; | |
13 | 11 | import org.thingsboard.server.transport.gbt28181.SipSubscribe; |
14 | 12 | |
15 | 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 | 13 | import lombok.Setter; |
14 | 14 | import lombok.extern.slf4j.Slf4j; |
15 | 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 | 19 | * @author Andrew Shvayka | ... | ... |
... | ... | @@ -10,10 +10,10 @@ import javax.sip.SipFactory; |
10 | 10 | import javax.sip.header.UserAgentHeader; |
11 | 11 | import org.apache.commons.lang3.RandomStringUtils; |
12 | 12 | import org.springframework.util.ObjectUtils; |
13 | -import org.thingsboard.server.common.data.yunteng.config.media.ThingsKitVersionConfig; | |
14 | 13 | import org.thingsboard.server.common.data.yunteng.dto.sip.PTZCmdDTO; |
15 | 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 | 18 | public class TKSipUtils { |
19 | 19 | public static String getNewMessageViaBranchTag() { |
... | ... | @@ -55,14 +55,14 @@ public class TKSipUtils { |
55 | 55 | builder.append(strTmp, 0, 2); |
56 | 56 | strTmp = String.format("%X", combineCode2); |
57 | 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 | 61 | strTmp = String.format("%02X", checkCode); |
61 | 62 | builder.append(strTmp, 0, 2); |
62 | 63 | return builder.toString(); |
63 | 64 | } |
64 | 65 | |
65 | - | |
66 | 66 | public static UserAgentHeader createUserAgentHeader(ThingsKitVersionConfig config) |
67 | 67 | throws PeerUnavailableException, ParseException { |
68 | 68 | List<String> agentParam = new ArrayList<>(); | ... | ... |
1 | 1 | /** |
2 | 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 | 12 | * limitations under the License. |
15 | 13 | */ |
16 | 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 | 19 | import org.thingsboard.server.common.data.DeviceProfile; |
19 | 20 | import org.thingsboard.server.common.data.DeviceTransportType; |
20 | 21 | import org.thingsboard.server.common.data.rpc.RpcStatus; |
... | ... | @@ -40,10 +41,11 @@ import org.thingsboard.server.gen.transport.TransportProtos.GetSnmpDevicesRespon |
40 | 41 | import org.thingsboard.server.gen.transport.TransportProtos.LwM2MRequestMsg; |
41 | 42 | import org.thingsboard.server.gen.transport.TransportProtos.LwM2MResponseMsg; |
42 | 43 | import org.thingsboard.server.gen.transport.TransportProtos.PostAttributeMsg; |
43 | -import org.thingsboard.server.gen.transport.TransportProtos.PostTelemetryMsg; | |
44 | 44 | import org.thingsboard.server.gen.transport.TransportProtos.PostEventMsg; |
45 | +import org.thingsboard.server.gen.transport.TransportProtos.PostTelemetryMsg; | |
45 | 46 | import org.thingsboard.server.gen.transport.TransportProtos.ProvisionDeviceRequestMsg; |
46 | 47 | import org.thingsboard.server.gen.transport.TransportProtos.ProvisionDeviceResponseMsg; |
48 | +import org.thingsboard.server.gen.transport.TransportProtos.ScriptProto; | |
47 | 49 | import org.thingsboard.server.gen.transport.TransportProtos.SessionEventMsg; |
48 | 50 | import org.thingsboard.server.gen.transport.TransportProtos.SessionInfoProto; |
49 | 51 | import org.thingsboard.server.gen.transport.TransportProtos.SubscribeToAttributeUpdatesMsg; |
... | ... | @@ -57,104 +59,140 @@ import org.thingsboard.server.gen.transport.TransportProtos.ValidateBasicMqttCre |
57 | 59 | import org.thingsboard.server.gen.transport.TransportProtos.ValidateDeviceLwM2MCredentialsRequestMsg; |
58 | 60 | import org.thingsboard.server.gen.transport.TransportProtos.ValidateDeviceTokenRequestMsg; |
59 | 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 | 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 | } | ... | ... |