Commit 6478903dab0bf804a1c3d586c97d67e556f824f7

Authored by nickAS21
Committed by GitHub
1 parent cf744b07

RPC: fix bug UUID (#4636)

* RPC: six bug UUID

* RPC: optimized handleDeviceRPCRequest

* RPC: add json & fix bug test certificate
... ... @@ -18,8 +18,8 @@
18 18 "resources": [],
19 19 "templateHtml": "<div style=\"height: 100%; overflow-y: auto;\" id=\"device-terminal\"></div>",
20 20 "templateCss": ".cmd .cursor.blink {\n -webkit-animation-name: terminal-underline;\n -moz-animation-name: terminal-underline;\n -ms-animation-name: terminal-underline;\n animation-name: terminal-underline;\n}\n.terminal .inverted, .cmd .inverted {\n border-bottom-color: #aaa;\n}\n",
21   - "controllerScript": "var requestTimeout = 500;\n\nself.onInit = function() {\n var subscription = self.ctx.defaultSubscription;\n var rpcEnabled = subscription.rpcEnabled;\n var deviceName = 'Simulated';\n var prompt;\n if (subscription.targetDeviceName && subscription.targetDeviceName.length) {\n deviceName = subscription.targetDeviceName;\n }\n if (self.ctx.settings.requestTimeout) {\n requestTimeout = self.ctx.settings.requestTimeout;\n }\n var greetings = 'Welcome to ThingsBoard RPC debug terminal.\\n\\n';\n if (!rpcEnabled) {\n greetings += 'Target device is not set!\\n\\n';\n prompt = '';\n } else {\n greetings += 'Current target device for RPC commands: [[b;#fff;]' + deviceName + ']\\n\\n';\n greetings += 'Please type [[b;#fff;]\\'help\\'] to see usage.\\n';\n prompt = '[[b;#8bc34a;]' + deviceName +']> ';\n }\n \n var terminal = $('#device-terminal', self.ctx.$container).terminal(\n function(command) {\n if (command !== '') {\n try {\n var localCommand = command.trim();\n if (localCommand === 'help') {\n printUsage(this);\n } else {\n var cmdObj = $.terminal.parse_command(localCommand);\n if (cmdObj.args.length > 1) {\n this.error(\"Wrong number of arguments!\");\n this.echo(' ');\n } else {\n var params;\n if (cmdObj.args.length && cmdObj.args[0]) {\n try {\n params = JSON.parse(cmdObj.args[0]);\n } catch (e) {\n params = cmdObj.args[0];\n }\n }\n performRpc(this, cmdObj.name, params);\n }\n }\n } catch(e) {\n this.error(new String(e));\n }\n } else {\n this.echo('');\n }\n }, {\n greetings: greetings,\n prompt: prompt,\n enabled: rpcEnabled\n });\n \n \n \n if (!rpcEnabled) {\n terminal.error('No RPC target detected!').pause();\n }\n}\n\n\nfunction printUsage(terminal) {\n var commandsListText = '\\n[[b;#fff;]Usage:]\\n';\n commandsListText += ' <method> [params body]]\\n\\n';\n commandsListText += '[[b;#fff;]Example 1:]\\n'; \n commandsListText += ' myRemoteMethod1 myText\\n\\n'; \n commandsListText += '[[b;#fff;]Example 2:]\\n'; \n commandsListText += ' myOtherRemoteMethod \"{\\\\\"key1\\\\\": 2, \\\\\"key2\\\\\": \\\\\"myVal\\\\\"}\"\\n'; \n terminal.echo(new String(commandsListText));\n}\n\nfunction performRpc(terminal, method, params) {\n terminal.pause();\n self.ctx.controlApi.sendTwoWayCommand(method, params, requestTimeout).subscribe(\n function success(responseBody) {\n terminal.echo(JSON.stringify(responseBody));\n terminal.echo(' ');\n terminal.resume();\n },\n function fail() {\n var errorText = self.ctx.defaultSubscription.rpcErrorText;\n terminal.error(errorText);\n terminal.echo(' ');\n terminal.resume();\n }\n );\n}\n\n \nself.onDestroy = function() {\n}\n",
22   - "settingsSchema": "{\n \"schema\": {\n \"type\": \"object\",\n \"title\": \"Settings\",\n \"properties\": {\n \"requestTimeout\": {\n \"title\": \"RPC request timeout (ms)\",\n \"type\": \"number\",\n \"default\": 500\n }\n },\n \"required\": [\"requestTimeout\"]\n },\n \"form\": [\n \"requestTimeout\"\n ]\n}",
  21 + "controllerScript": "var requestTimeout = 500;\nvar multiParams = false;\n\nself.onInit = function() {\n var subscription = self.ctx.defaultSubscription;\n var utils = self.ctx.$scope.$injector.get(self.ctx.servicesMap.get('utils'));\n var rpcEnabled = subscription.rpcEnabled;\n var deviceName = 'Simulated';\n var prompt;\n if (subscription.targetDeviceName && subscription.targetDeviceName.length) {\n deviceName = subscription.targetDeviceName;\n }\n if (self.ctx.settings.requestTimeout) {\n requestTimeout = self.ctx.settings.requestTimeout;\n }\n if (self.ctx.settings.multiParams) {\n multiParams = self.ctx.settings.multiParams;\n }\n var greetings = 'Welcome to ThingsBoard RPC debug terminal.\\n\\n';\n if (!rpcEnabled) {\n greetings += 'Target device is not set!\\n\\n';\n prompt = '';\n } else {\n greetings += 'Current target device for RPC commands: [[b;#fff;]' + deviceName + ']\\n\\n';\n greetings += 'Please type [[b;#fff;]\\'help\\'] to see usage.\\n';\n prompt = '[[b;#8bc34a;]' + deviceName +']> ';\n }\n \n var terminal = $('#device-terminal', self.ctx.$container).terminal(\n function(command) {\n if (command !== '') {\n try {\n var localCommand = command.trim();\n var requestUUID = utils.guid();\n if (localCommand === 'help') {\n printUsage(this);\n } else {\n var cmdObj = $.terminal.parse_command(localCommand);\n if (cmdObj.args) {\n if (!multiParams && cmdObj.args.length > 1) {\n this.error(\"Wrong number of arguments!\");\n this.echo(' ');\n }\n else {\n if (cmdObj.args.length) {\n var params = getMultiParams(cmdObj.args);\n }\n performRpc(this, cmdObj.name, params, requestUUID);\n }\n }\n }\n } catch(e) {\n this.error(new String(e));\n }\n } else {\n this.echo('');\n }\n }, {\n greetings: greetings,\n prompt: prompt,\n enabled: rpcEnabled\n });\n \n \n \n if (!rpcEnabled) {\n terminal.error('No RPC target detected!').pause();\n }\n}\n\n\nfunction printUsage(terminal) {\n var commandsListText = '\\n[[b;#fff;]Usage:]\\n';\n commandsListText += ' <method> [params body]]\\n\\n';\n commandsListText += '[[b;#fff;]Example 1 (multiParams===false):]\\n'; \n commandsListText += ' myRemoteMethod1 myText\\n\\n'; \n commandsListText += '[[b;#fff;]Example 2 (multiParams===false):]\\n'; \n commandsListText += ' myOtherRemoteMethod \"{\\\\\"key1\\\\\":2,\\\\\"key2\\\\\":\\\\\"myVal\\\\\"}\"\\n\\n'; \n commandsListText += '[[b;#fff;]Example 3 (multiParams===true)]\\n'; \n commandsListText += ' <method> [params body] = \"all the string after the method, including spaces\"]\\n';\n commandsListText += ' myOtherRemoteMethod \"{\\\\\"key1\\\\\": \"battery level\", \\\\\"key2\\\\\": \\\\\"myVal\\\\\"}\"\\n'; \n terminal.echo(new String(commandsListText));\n}\n\nfunction performRpc(terminal, method, params, requestUUID) {\n terminal.pause();\n self.ctx.controlApi.sendTwoWayCommand(method, params, requestTimeout, requestUUID).subscribe(\n function success(responseBody) {\n terminal.echo(JSON.stringify(responseBody));\n terminal.echo(' ');\n terminal.resume();\n },\n function fail() {\n var errorText = self.ctx.defaultSubscription.rpcErrorText;\n terminal.error(errorText);\n terminal.echo(' ');\n terminal.resume();\n }\n );\n}\n\nfunction getMultiParams(cmdObj) {\n var params = \"\";\n cmdObj.forEach((element) => {\n try {\n params += \" \" + JSON.strigify(JSON.parse(element));\n } catch (e) {\n params += \" \" + element;\n }\n })\n return params.trim();\n}\n\n \nself.onDestroy = function() {\n}",
  22 + "settingsSchema": "{\n \"schema\": {\n \"type\": \"object\",\n \"title\": \"Settings\",\n \"properties\": {\n \"requestTimeout\": {\n \"title\": \"RPC request timeout (ms)\",\n \"type\": \"number\",\n \"default\": 500\n },\n \"multiParams\": {\n \"title\": \"RPC params All line\",\n \"type\": \"boolean\",\n \"default\": false\n }\n },\n \"required\": [\"requestTimeout\"]\n },\n \"form\": [\n \"requestTimeout\",\n \"multiParams\"\n ]\n}",
23 23 "dataKeySettingsSchema": "{}\n",
24 24 "defaultConfig": "{\"targetDeviceAliases\":[],\"showTitle\":true,\"backgroundColor\":\"#010101\",\"color\":\"rgba(255, 254, 254, 0.87)\",\"padding\":\"0px\",\"settings\":{\"parseGpioStatusFunction\":\"return body[pin] === true;\",\"gpioStatusChangeRequest\":{\"method\":\"setGpioStatus\",\"paramsBody\":\"{\\n \\\"pin\\\": \\\"{$pin}\\\",\\n \\\"enabled\\\": \\\"{$enabled}\\\"\\n}\"},\"requestTimeout\":500,\"switchPanelBackgroundColor\":\"#b71c1c\",\"gpioStatusRequest\":{\"method\":\"getGpioStatus\",\"paramsBody\":\"{}\"},\"gpioList\":[{\"pin\":1,\"label\":\"GPIO 1\",\"row\":0,\"col\":0,\"_uniqueKey\":0},{\"pin\":2,\"label\":\"GPIO 2\",\"row\":0,\"col\":1,\"_uniqueKey\":1},{\"pin\":3,\"label\":\"GPIO 3\",\"row\":1,\"col\":0,\"_uniqueKey\":2}]},\"title\":\"RPC debug terminal\",\"dropShadow\":true,\"enableFullscreen\":true,\"widgetStyle\":{},\"titleStyle\":{\"fontSize\":\"16px\",\"fontWeight\":400},\"useDashboardTimewindow\":true,\"showLegend\":false,\"actions\":{}}"
25 25 }
... ...
... ... @@ -25,8 +25,8 @@ import lombok.extern.slf4j.Slf4j;
25 25 import org.apache.commons.collections.CollectionUtils;
26 26 import org.thingsboard.rule.engine.api.RpcError;
27 27 import org.thingsboard.rule.engine.api.msg.DeviceAttributesEventNotificationMsg;
28   -import org.thingsboard.rule.engine.api.msg.DeviceEdgeUpdateMsg;
29 28 import org.thingsboard.rule.engine.api.msg.DeviceCredentialsUpdateNotificationMsg;
  29 +import org.thingsboard.rule.engine.api.msg.DeviceEdgeUpdateMsg;
30 30 import org.thingsboard.rule.engine.api.msg.DeviceNameOrTypeUpdateMsg;
31 31 import org.thingsboard.server.actors.ActorSystemContext;
32 32 import org.thingsboard.server.actors.TbActorCtx;
... ... @@ -73,7 +73,6 @@ import org.thingsboard.server.gen.transport.TransportProtos.ToDeviceRpcResponseM
73 73 import org.thingsboard.server.gen.transport.TransportProtos.ToServerRpcResponseMsg;
74 74 import org.thingsboard.server.gen.transport.TransportProtos.ToTransportMsg;
75 75 import org.thingsboard.server.gen.transport.TransportProtos.TransportToDeviceActorMsg;
76   -import org.thingsboard.server.gen.transport.TransportProtos.ToTransportUpdateCredentialsProto;
77 76 import org.thingsboard.server.gen.transport.TransportProtos.TsKvProto;
78 77 import org.thingsboard.server.service.rpc.FromDeviceRpcResponse;
79 78 import org.thingsboard.server.service.rpc.FromDeviceRpcResponseActorMsg;
... ... @@ -164,8 +163,14 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor {
164 163 void processRpcRequest(TbActorCtx context, ToDeviceRpcRequestActorMsg msg) {
165 164 ToDeviceRpcRequest request = msg.getMsg();
166 165 ToDeviceRpcRequestBody body = request.getBody();
167   - ToDeviceRpcRequestMsg rpcRequest = ToDeviceRpcRequestMsg.newBuilder().setRequestId(
168   - rpcSeq++).setMethodName(body.getMethod()).setParams(body.getParams()).build();
  166 + ToDeviceRpcRequestMsg rpcRequest = ToDeviceRpcRequestMsg.newBuilder()
  167 + .setRequestId(rpcSeq++)
  168 + .setMethodName(body.getMethod())
  169 + .setParams(body.getParams())
  170 + .setExpirationTime(request.getExpirationTime())
  171 + .setRequestIdMSB(request.getId().getMostSignificantBits())
  172 + .setRequestIdLSB(request.getId().getLeastSignificantBits())
  173 + .build();
169 174
170 175 long timeout = request.getExpirationTime() - System.currentTimeMillis();
171 176 if (timeout <= 0) {
... ... @@ -258,8 +263,14 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor {
258 263 sentOneWayIds.add(entry.getKey());
259 264 systemContext.getTbCoreDeviceRpcService().processRpcResponseFromDeviceActor(new FromDeviceRpcResponse(request.getId(), null, null));
260 265 }
261   - ToDeviceRpcRequestMsg rpcRequest = ToDeviceRpcRequestMsg.newBuilder().setRequestId(
262   - entry.getKey()).setMethodName(body.getMethod()).setParams(body.getParams()).build();
  266 + ToDeviceRpcRequestMsg rpcRequest = ToDeviceRpcRequestMsg.newBuilder()
  267 + .setRequestId(entry.getKey())
  268 + .setMethodName(body.getMethod())
  269 + .setParams(body.getParams())
  270 + .setExpirationTime(request.getExpirationTime())
  271 + .setRequestIdMSB(request.getId().getMostSignificantBits())
  272 + .setRequestIdLSB(request.getId().getLeastSignificantBits())
  273 + .build();
263 274 sendToTransport(rpcRequest, sessionId, nodeId);
264 275 };
265 276 }
... ...
... ... @@ -40,7 +40,6 @@ import org.thingsboard.server.common.data.id.DeviceId;
40 40 import org.thingsboard.server.common.data.id.EntityId;
41 41 import org.thingsboard.server.common.data.id.TenantId;
42 42 import org.thingsboard.server.common.data.id.UUIDBased;
43   -import org.thingsboard.server.common.data.rpc.RpcRequest;
44 43 import org.thingsboard.server.common.data.rpc.ToDeviceRpcRequestBody;
45 44 import org.thingsboard.server.common.msg.rpc.ToDeviceRpcRequest;
46 45 import org.thingsboard.server.queue.util.TbCoreComponent;
... ... @@ -97,22 +96,17 @@ public class RpcController extends BaseController {
97 96 private DeferredResult<ResponseEntity> handleDeviceRPCRequest(boolean oneWay, DeviceId deviceId, String requestBody) throws ThingsboardException {
98 97 try {
99 98 JsonNode rpcRequestBody = jsonMapper.readTree(requestBody);
100   - RpcRequest cmd = new RpcRequest(rpcRequestBody.get("method").asText(),
101   - jsonMapper.writeValueAsString(rpcRequestBody.get("params")));
102   -
103   - if (rpcRequestBody.has("timeout")) {
104   - cmd.setTimeout(rpcRequestBody.get("timeout").asLong());
105   - }
  99 + ToDeviceRpcRequestBody body = new ToDeviceRpcRequestBody(rpcRequestBody.get("method").asText(), jsonMapper.writeValueAsString(rpcRequestBody.get("params")));
106 100 SecurityUser currentUser = getCurrentUser();
107 101 TenantId tenantId = currentUser.getTenantId();
108 102 final DeferredResult<ResponseEntity> response = new DeferredResult<>();
109   - long timeout = cmd.getTimeout() != null ? cmd.getTimeout() : defaultTimeout;
  103 + long timeout = rpcRequestBody.has("timeout") ? rpcRequestBody.get("timeout").asLong() : defaultTimeout;
110 104 long expTime = System.currentTimeMillis() + Math.max(minTimeout, timeout);
111   - ToDeviceRpcRequestBody body = new ToDeviceRpcRequestBody(cmd.getMethodName(), cmd.getRequestData());
  105 + UUID rpcRequestUUID = rpcRequestBody.has("requestUUID") ? UUID.fromString(rpcRequestBody.get("requestUUID").asText()) : UUID.randomUUID();
112 106 accessValidator.validate(currentUser, Operation.RPC_CALL, deviceId, new HttpValidationCallback(response, new FutureCallback<DeferredResult<ResponseEntity>>() {
113 107 @Override
114 108 public void onSuccess(@Nullable DeferredResult<ResponseEntity> result) {
115   - ToDeviceRpcRequest rpcRequest = new ToDeviceRpcRequest(UUID.randomUUID(),
  109 + ToDeviceRpcRequest rpcRequest = new ToDeviceRpcRequest(rpcRequestUUID,
116 110 tenantId,
117 111 deviceId,
118 112 oneWay,
... ...
1 1 transport.lwm2m.security.key_store=lwm2m/credentials/serverKeyStore.jks
2 2 transport.lwm2m.security.key_store_password=server
3   -edges.enabled=true
\ No newline at end of file
  3 +edges.enabled=true
  4 +transport.lwm2m.bootstrap.security.alias=server
\ No newline at end of file
... ...
1   -/**
2   - * Copyright © 2016-2021 The Thingsboard Authors
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
7   - *
8   - * http://www.apache.org/licenses/LICENSE-2.0
9   - *
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.common.data.rpc;
17   -
18   -import lombok.Data;
19   -
20   -/**
21   - * @author Andrew Shvayka
22   - */
23   -@Data
24   -public class RpcRequest {
25   - private final String methodName;
26   - private final String requestData;
27   - private Long timeout;
28   -}
... ... @@ -318,6 +318,9 @@ message ToDeviceRpcRequestMsg {
318 318 int32 requestId = 1;
319 319 string methodName = 2;
320 320 string params = 3;
  321 + int64 expirationTime = 4;
  322 + int64 requestIdMSB = 5;
  323 + int64 requestIdLSB = 6;
321 324 }
322 325
323 326 message ToDeviceRpcResponseMsg {
... ...
... ... @@ -69,8 +69,8 @@ export interface WidgetSubscriptionApi {
69 69 }
70 70
71 71 export interface RpcApi {
72   - sendOneWayCommand: (method: string, params?: any, timeout?: number) => Observable<any>;
73   - sendTwoWayCommand: (method: string, params?: any, timeout?: number) => Observable<any>;
  72 + sendOneWayCommand: (method: string, params?: any, timeout?: number, requestUUID?: string) => Observable<any>;
  73 + sendTwoWayCommand: (method: string, params?: any, timeout?: number, requestUUID?: string) => Observable<any>;
74 74 }
75 75
76 76 export interface IWidgetUtils {
... ... @@ -298,8 +298,8 @@ export interface IWidgetSubscription {
298 298 onResetTimewindow(): void;
299 299 updateTimewindowConfig(newTimewindow: Timewindow): void;
300 300
301   - sendOneWayCommand(method: string, params?: any, timeout?: number): Observable<any>;
302   - sendTwoWayCommand(method: string, params?: any, timeout?: number): Observable<any>;
  301 + sendOneWayCommand(method: string, params?: any, timeout?: number, requestUUID?: string): Observable<any>;
  302 + sendTwoWayCommand(method: string, params?: any, timeout?: number, requestUUID?: string): Observable<any>;
303 303 clearRpcError(): void;
304 304
305 305 subscribe(): void;
... ...
... ... @@ -38,12 +38,14 @@ import {
38 38 import { HttpErrorResponse } from '@angular/common/http';
39 39 import {
40 40 calculateIntervalStartEndTime,
41   - calculateTsOffset, ComparisonDuration,
  41 + calculateTsOffset,
  42 + ComparisonDuration,
42 43 createSubscriptionTimewindow,
43 44 createTimewindowForComparison,
44 45 isHistoryTypeTimewindow,
45 46 SubscriptionTimewindow,
46   - Timewindow, timewindowTypeChanged,
  47 + Timewindow,
  48 + timewindowTypeChanged,
47 49 toHistoryTimewindow,
48 50 WidgetTimewindow
49 51 } from '@app/shared/models/time/time.models';
... ... @@ -642,12 +644,12 @@ export class WidgetSubscription implements IWidgetSubscription {
642 644 }
643 645 }
644 646
645   - sendOneWayCommand(method: string, params?: any, timeout?: number): Observable<any> {
646   - return this.sendCommand(true, method, params, timeout);
  647 + sendOneWayCommand(method: string, params?: any, timeout?: number, requestUUID?: string): Observable<any> {
  648 + return this.sendCommand(true, method, params, timeout, requestUUID);
647 649 }
648 650
649   - sendTwoWayCommand(method: string, params?: any, timeout?: number): Observable<any> {
650   - return this.sendCommand(false, method, params, timeout);
  651 + sendTwoWayCommand(method: string, params?: any, timeout?: number, requestUUID?: string): Observable<any> {
  652 + return this.sendCommand(false, method, params, timeout, requestUUID);
651 653 }
652 654
653 655 clearRpcError(): void {
... ... @@ -656,7 +658,7 @@ export class WidgetSubscription implements IWidgetSubscription {
656 658 this.callbacks.onRpcErrorCleared(this);
657 659 }
658 660
659   - sendCommand(oneWayElseTwoWay: boolean, method: string, params?: any, timeout?: number): Observable<any> {
  661 + sendCommand(oneWayElseTwoWay: boolean, method: string, params?: any, timeout?: number, requestUUID?: string): Observable<any> {
660 662 if (!this.rpcEnabled) {
661 663 return throwError(new Error('Rpc disabled!'));
662 664 } else {
... ... @@ -667,7 +669,8 @@ export class WidgetSubscription implements IWidgetSubscription {
667 669 }
668 670 const requestBody: any = {
669 671 method,
670   - params
  672 + params,
  673 + requestUUID
671 674 };
672 675 if (timeout && timeout > 0) {
673 676 requestBody.timeout = timeout;
... ...
... ... @@ -32,12 +32,7 @@ import {
32 32 import { UtilsService } from '@core/services/utils.service';
33 33 import { TranslateService } from '@ngx-translate/core';
34 34 import { ResourcesService } from '../services/resources.service';
35   -import {
36   - toWidgetInfo,
37   - toWidgetType,
38   - toWidgetTypeDetails,
39   - WidgetInfo
40   -} from '@app/modules/home/models/widget-component.models';
  35 +import { toWidgetInfo, toWidgetTypeDetails, WidgetInfo } from '@app/modules/home/models/widget-component.models';
41 36 import { filter, map, mergeMap, tap } from 'rxjs/operators';
42 37 import { WidgetTypeId } from '@shared/models/id/widget-type-id';
43 38 import { NULL_UUID } from '@shared/models/id/has-uuid';
... ...
... ... @@ -27,7 +27,8 @@ import {
27 27 WidgetControllerDescriptor,
28 28 WidgetType,
29 29 widgetType,
30   - WidgetTypeDescriptor, WidgetTypeDetails,
  30 + WidgetTypeDescriptor,
  31 + WidgetTypeDetails,
31 32 WidgetTypeParameters
32 33 } from '@shared/models/widget.models';
33 34 import { Timewindow, WidgetTimewindow } from '@shared/models/time/time.models';
... ... @@ -188,16 +189,16 @@ export class WidgetContext {
188 189 };
189 190
190 191 controlApi: RpcApi = {
191   - sendOneWayCommand: (method, params, timeout) => {
  192 + sendOneWayCommand: (method, params, timeout, requestUUID) => {
192 193 if (this.defaultSubscription) {
193   - return this.defaultSubscription.sendOneWayCommand(method, params, timeout);
  194 + return this.defaultSubscription.sendOneWayCommand(method, params, timeout, requestUUID);
194 195 } else {
195 196 return of(null);
196 197 }
197 198 },
198   - sendTwoWayCommand: (method, params, timeout) => {
  199 + sendTwoWayCommand: (method, params, timeout, requestUUID) => {
199 200 if (this.defaultSubscription) {
200   - return this.defaultSubscription.sendTwoWayCommand(method, params, timeout);
  201 + return this.defaultSubscription.sendTwoWayCommand(method, params, timeout, requestUUID);
201 202 } else {
202 203 return of(null);
203 204 }
... ...