@ -5,7 +5,7 @@
* you may not use this file except in compliance with the License .
* You may obtain a copy of the License at
*
* http : //www.apache.org/licenses/LICENSE-2.0
* http : //www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing , software
* distributed under the License is distributed on an "AS IS" BASIS ,
@ -29,8 +29,27 @@ import org.thingsboard.server.transport.lwm2m.server.LwM2mOperationType;
import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClient ;
import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClientContext ;
import org.thingsboard.server.transport.lwm2m.server.downlink.LwM2mDownlinkMsgHandler ;
import org.thingsboard.server.transport.lwm2m.server.downlink.TbLwM2MCancelAllObserveCallback ;
import org.thingsboard.server.transport.lwm2m.server.downlink.TbLwM2MCancelAllRequest ;
import org.thingsboard.server.transport.lwm2m.server.downlink.TbLwM2MCancelObserveCallback ;
import org.thingsboard.server.transport.lwm2m.server.downlink.TbLwM2MCancelObserveRequest ;
import org.thingsboard.server.transport.lwm2m.server.downlink.TbLwM2MDeleteCallback ;
import org.thingsboard.server.transport.lwm2m.server.downlink.TbLwM2MDeleteRequest ;
import org.thingsboard.server.transport.lwm2m.server.downlink.TbLwM2MDiscoverAllRequest ;
import org.thingsboard.server.transport.lwm2m.server.downlink.TbLwM2MDiscoverCallback ;
import org.thingsboard.server.transport.lwm2m.server.downlink.TbLwM2MDiscoverRequest ;
import org.thingsboard.server.transport.lwm2m.server.downlink.TbLwM2MExecuteCallback ;
import org.thingsboard.server.transport.lwm2m.server.downlink.TbLwM2MExecuteRequest ;
import org.thingsboard.server.transport.lwm2m.server.downlink.TbLwM2MObserveAllRequest ;
import org.thingsboard.server.transport.lwm2m.server.downlink.TbLwM2MObserveCallback ;
import org.thingsboard.server.transport.lwm2m.server.downlink.TbLwM2MObserveRequest ;
import org.thingsboard.server.transport.lwm2m.server.downlink.TbLwM2MReadCallback ;
import org.thingsboard.server.transport.lwm2m.server.downlink.TbLwM2MReadRequest ;
import org.thingsboard.server.transport.lwm2m.server.downlink.TbLwM2MWriteAttributesCallback ;
import org.thingsboard.server.transport.lwm2m.server.downlink.TbLwM2MWriteAttributesRequest ;
import org.thingsboard.server.transport.lwm2m.server.downlink.TbLwM2MWriteReplaceRequest ;
import org.thingsboard.server.transport.lwm2m.server.downlink.TbLwM2MWriteResponseCallback ;
import org.thingsboard.server.transport.lwm2m.server.downlink.TbLwM2MWriteUpdateRequest ;
import org.thingsboard.server.transport.lwm2m.server.uplink.LwM2mUplinkMsgHandler ;
import java.util.Map ;
@ -57,62 +76,167 @@ public class DefaultLwM2MRpcRequestHandler implements LwM2MRpcRequestHandler {
private final LwM2mDownlinkMsgHandler downlinkHandler ;
private final Map < UUID , Long > rpcSubscriptions = new ConcurrentHashMap < > ( ) ;
@Override
public void onToDeviceRpcRequest ( TransportProtos . ToDeviceRpcRequestMsg rpcRequst , TransportProtos . SessionInfoProto sessionInfo ) {
this . cleanupOldSessions ( ) ;
UUID requestUUID = new UUID ( rpcRequst . getRequestIdMSB ( ) , rpcRequst . getRequestIdLSB ( ) ) ;
log . warn ( "Received params: {}" , rpcRequst . getParams ( ) ) ;
// TODO: We use this map to protect from browser issue that the same command is sent twice. This is probably not the best place and should be moved to DeviceActor
// We use this map to protect from browser issue that the same command is sent twice.
// TODO: This is probably not the best place and should be moved to DeviceActor
if ( ! this . rpcSubscriptions . containsKey ( requestUUID ) ) {
LwM2mOperationType operationType = LwM2mOperationType . fromType ( rpcRequst . getMethodName ( ) ) ;
if ( operationType = = null ) {
this . sendErrorRpcResponse ( sessionInfo , rpcRequst . getRequestId ( ) , ResponseCode . METHOD_NOT_ALLOWED . getName ( ) , "Unsupported operation type: " + rpcRequst . getMethodName ( ) ) ;
return ;
}
LwM2mClient client = clientContext . getClientBySessionInfo ( sessionInfo ) ;
if ( client . getRegistration ( ) = = null ) {
this . sendErrorRpcResponse ( sessionInfo , rpcRequst . getRequestId ( ) , ResponseCode . INTERNAL_SERVER_ERROR . getName ( ) , "Registration is empty" ) ;
return ;
}
switch ( operationType ) {
case READ :
sendReadRequest ( client , rpcRequst ) ;
break ;
try {
if ( operationType . isHasObjectId ( ) ) {
String objectId = getIdFromParameters ( client , rpcRequst ) ;
switch ( operationType ) {
case READ :
sendReadRequest ( client , rpcRequst , objectId ) ;
break ;
case OBSERVE :
sendObserveRequest ( client , rpcRequst , objectId ) ;
break ;
case DISCOVER :
sendDiscoverRequest ( client , rpcRequst , objectId ) ;
break ;
case EXECUTE :
sendExecuteRequest ( client , rpcRequst , objectId ) ;
break ;
case WRITE_ATTRIBUTES :
sendWriteAttributesRequest ( client , rpcRequst , objectId ) ;
break ;
case OBSERVE_CANCEL :
sendCancelObserveRequest ( client , rpcRequst , objectId ) ;
break ;
case DELETE :
sendDeleteRequest ( client , rpcRequst , objectId ) ;
break ;
case WRITE_UPDATE :
sendWriteUpdateRequest ( client , rpcRequst , objectId ) ;
break ;
case WRITE_REPLACE :
sendWriteReplaceRequest ( client , rpcRequst , objectId ) ;
break ;
default :
throw new IllegalArgumentException ( "Unsupported operation: " + operationType . name ( ) ) ;
}
} else {
switch ( operationType ) {
case OBSERVE_CANCEL_ALL :
sendCancelAllObserveRequest ( client , rpcRequst ) ;
break ;
case OBSERVE_READ_ALL :
sendObserveAllRequest ( client , rpcRequst ) ;
break ;
case DISCOVER_ALL :
sendDiscoverAllRequest ( client , rpcRequst ) ;
break ;
case FW_UPDATE :
//TODO: implement and add break statement
default :
throw new IllegalArgumentException ( "Unsupported operation: " + operationType . name ( ) ) ;
}
}
} catch ( IllegalArgumentException e ) {
this . sendErrorRpcResponse ( sessionInfo , rpcRequst . getRequestId ( ) , ResponseCode . BAD_REQUEST . getName ( ) , e . getMessage ( ) ) ;
}
}
}
private void sendReadRequest ( LwM2mClient client , TransportProtos . ToDeviceRpcRequestMsg requestMsg , String versionedId ) {
TbLwM2MReadRequest request = TbLwM2MReadRequest . builder ( ) . versionedId ( versionedId ) . timeout ( this . config . getTimeout ( ) ) . build ( ) ;
var mainCallback = new TbLwM2MReadCallback ( uplinkHandler , client , versionedId ) ;
var rpcCallback = new RpcReadResponseCallback < > ( transportService , client , requestMsg , versionedId , mainCallback ) ;
downlinkHandler . sendReadRequest ( client , request , rpcCallback ) ;
}
// log.warn("4) rpcRequst: [{}], sessionUUID: [{}]", rpcRequst, new UUID(sessionInfo.getSessionIdMSB(), sessionInfo.getSessionIdLSB()));
// String bodyParams = StringUtils.trimToNull(rpcRequst.getParams()) != null ? rpcRequst.getParams() : "null";
// LwM2mOperationType lwM2mTypeOper = setValidTypeOper(rpcRequst.getMethodName());
// this.rpcSubscriptions.put(requestUUID, rpcRequst.getExpirationTime());
// LwM2mClientRpcRequest lwm2mClientRpcRequest = null;
// try {
// LwM2mClient client = clientContext.getClientBySessionInfo(sessionInfo);
// Registration registration = client.getRegistration();
// if (registration != null) {
// lwm2mClientRpcRequest = new LwM2mClientRpcRequest(lwM2mTypeOper, bodyParams, rpcRequst.getRequestId(), sessionInfo, registration, uplinkHandler);
// if (lwm2mClientRpcRequest.getErrorMsg() != null) {
// lwm2mClientRpcRequest.setResponseCode(BAD_REQUEST.name());
// this.onToDeviceRpcResponse(lwm2mClientRpcRequest.getDeviceRpcResponseResultMsg(), sessionInfo);
// } else {
// //TODO: use different methods and RPC callback wrapper.
//// defaultLwM2MDownlinkMsgHandler.sendAllRequest(client, lwm2mClientRpcRequest.getTargetIdVer(), lwm2mClientRpcRequest.getTypeOper(),
//// null,
//// lwm2mClientRpcRequest.getValue() == null ? lwm2mClientRpcRequest.getParams() : lwm2mClientRpcRequest.getValue(),
//// this.config.getTimeout(), lwm2mClientRpcRequest);
// }
// } else {
// this.sendErrorRpcResponse(lwm2mClientRpcRequest, "registration == null", sessionInfo);
// }
// } catch (Exception e) {
// this.sendErrorRpcResponse(lwm2mClientRpcRequest, e.getMessage(), sessionInfo);
// }
}
private void sendObserveRequest ( LwM2mClient client , TransportProtos . ToDeviceRpcRequestMsg requestMsg , String versionedId ) {
TbLwM2MObserveRequest request = TbLwM2MObserveRequest . builder ( ) . versionedId ( versionedId ) . timeout ( this . config . getTimeout ( ) ) . build ( ) ;
var mainCallback = new TbLwM2MObserveCallback ( uplinkHandler , client , versionedId ) ;
var rpcCallback = new RpcReadResponseCallback < > ( transportService , client , requestMsg , versionedId , mainCallback ) ;
downlinkHandler . sendObserveRequest ( client , request , rpcCallback ) ;
}
private void sendObserveAllRequest ( LwM2mClient client , TransportProtos . ToDeviceRpcRequestMsg requestMsg ) {
TbLwM2MObserveAllRequest request = TbLwM2MObserveAllRequest . builder ( ) . timeout ( this . config . getTimeout ( ) ) . build ( ) ;
downlinkHandler . sendObserveAllRequest ( client , request , new RpcLinkSetCallback ( transportService , client , requestMsg , null ) ) ;
}
private void sendDiscoverAllRequest ( LwM2mClient client , TransportProtos . ToDeviceRpcRequestMsg requestMsg ) {
TbLwM2MDiscoverAllRequest request = TbLwM2MDiscoverAllRequest . builder ( ) . timeout ( this . config . getTimeout ( ) ) . build ( ) ;
downlinkHandler . sendDiscoverAllRequest ( client , request , new RpcLinkSetCallback ( transportService , client , requestMsg , null ) ) ;
}
private void sendDiscoverRequest ( LwM2mClient client , TransportProtos . ToDeviceRpcRequestMsg requestMsg , String versionedId ) {
TbLwM2MDiscoverRequest request = TbLwM2MDiscoverRequest . builder ( ) . versionedId ( versionedId ) . timeout ( this . config . getTimeout ( ) ) . build ( ) ;
var mainCallback = new TbLwM2MDiscoverCallback ( uplinkHandler , client , versionedId ) ;
var rpcCallback = new RpcDiscoverCallback ( transportService , client , requestMsg , mainCallback ) ;
downlinkHandler . sendDiscoverRequest ( client , request , rpcCallback ) ;
}
private void sendExecuteRequest ( LwM2mClient client , TransportProtos . ToDeviceRpcRequestMsg requestMsg , String versionedId ) {
TbLwM2MExecuteRequest downlink = TbLwM2MExecuteRequest . builder ( ) . versionedId ( versionedId ) . timeout ( this . config . getTimeout ( ) ) . build ( ) ;
var mainCallback = new TbLwM2MExecuteCallback ( uplinkHandler , client , versionedId ) ;
var rpcCallback = new RpcEmptyResponseCallback < > ( transportService , client , requestMsg , mainCallback ) ;
downlinkHandler . sendExecuteRequest ( client , downlink , rpcCallback ) ;
}
private void sendWriteAttributesRequest ( LwM2mClient client , TransportProtos . ToDeviceRpcRequestMsg requestMsg , String versionedId ) {
RpcWriteAttributesRequest requestBody = JacksonUtil . fromString ( requestMsg . getParams ( ) , RpcWriteAttributesRequest . class ) ;
TbLwM2MWriteAttributesRequest request = TbLwM2MWriteAttributesRequest . builder ( ) . versionedId ( versionedId )
. attributes ( requestBody . getAttributes ( ) )
. timeout ( this . config . getTimeout ( ) ) . build ( ) ;
var mainCallback = new TbLwM2MWriteAttributesCallback ( uplinkHandler , client , versionedId ) ;
var rpcCallback = new RpcEmptyResponseCallback < > ( transportService , client , requestMsg , mainCallback ) ;
downlinkHandler . sendWriteAttributesRequest ( client , request , rpcCallback ) ;
}
private void sendWriteUpdateRequest ( LwM2mClient client , TransportProtos . ToDeviceRpcRequestMsg requestMsg , String versionedId ) {
RpcWriteUpdateRequest requestBody = JacksonUtil . fromString ( requestMsg . getParams ( ) , RpcWriteUpdateRequest . class ) ;
TbLwM2MWriteUpdateRequest . TbLwM2MWriteUpdateRequestBuilder builder = TbLwM2MWriteUpdateRequest . builder ( ) . versionedId ( versionedId ) ;
builder . value ( requestBody . getValue ( ) ) . timeout ( this . config . getTimeout ( ) ) ;
var mainCallback = new TbLwM2MWriteResponseCallback ( uplinkHandler , client , versionedId ) ;
var rpcCallback = new RpcEmptyResponseCallback < > ( transportService , client , requestMsg , mainCallback ) ;
downlinkHandler . sendWriteUpdateRequest ( client , builder . build ( ) , rpcCallback ) ;
}
private void sendWriteReplaceRequest ( LwM2mClient client , TransportProtos . ToDeviceRpcRequestMsg requestMsg , String versionedId ) {
RpcWriteUpdateRequest requestBody = JacksonUtil . fromString ( requestMsg . getParams ( ) , RpcWriteUpdateRequest . class ) ;
TbLwM2MWriteReplaceRequest request = TbLwM2MWriteReplaceRequest . builder ( ) . versionedId ( versionedId )
. value ( requestBody . getValue ( ) )
. timeout ( this . config . getTimeout ( ) ) . build ( ) ;
var mainCallback = new TbLwM2MWriteResponseCallback ( uplinkHandler , client , versionedId ) ;
var rpcCallback = new RpcEmptyResponseCallback < > ( transportService , client , requestMsg , mainCallback ) ;
downlinkHandler . sendWriteReplaceRequest ( client , request , rpcCallback ) ;
}
private void sendCancelObserveRequest ( LwM2mClient client , TransportProtos . ToDeviceRpcRequestMsg requestMsg , String versionedId ) {
TbLwM2MCancelObserveRequest downlink = TbLwM2MCancelObserveRequest . builder ( ) . versionedId ( versionedId ) . timeout ( this . config . getTimeout ( ) ) . build ( ) ;
var mainCallback = new TbLwM2MCancelObserveCallback ( uplinkHandler , client , versionedId ) ;
var rpcCallback = new RpcCancelObserveCallback ( transportService , client , requestMsg , mainCallback ) ;
downlinkHandler . sendCancelObserveRequest ( client , downlink , rpcCallback ) ;
}
private void sendDeleteRequest ( LwM2mClient client , TransportProtos . ToDeviceRpcRequestMsg requestMsg , String versionedId ) {
TbLwM2MDeleteRequest downlink = TbLwM2MDeleteRequest . builder ( ) . versionedId ( versionedId ) . timeout ( this . config . getTimeout ( ) ) . build ( ) ;
var mainCallback = new TbLwM2MDeleteCallback ( uplinkHandler , client , versionedId ) ;
var rpcCallback = new RpcEmptyResponseCallback < > ( transportService , client , requestMsg , mainCallback ) ;
downlinkHandler . sendDeleteRequest ( client , downlink , rpcCallback ) ;
}
private void sendReadRequest ( LwM2mClient client , TransportProtos . ToDeviceRpcRequestMsg rpcRequst ) {
String id = getIdFromParameters ( client , rpcRequst ) ;
TbLwM2MReadRequest request = TbLwM2MReadRequest . builder ( ) . versionedId ( id ) . timeout ( this . config . getTimeout ( ) ) . build ( ) ;
downlinkHandler . sendReadRequest ( client , request , new TbLwM2MReadCallback ( uplinkHandler , client , id ) ) ;
private void sendCancelAllObserveRequest ( LwM2mClient client , TransportProtos . ToDeviceRpcRequestMsg requestMsg ) {
TbLwM2MCancelAllRequest downlink = TbLwM2MCancelAllRequest . builder ( ) . timeout ( this . config . getTimeout ( ) ) . build ( ) ;
var mainCallback = new TbLwM2MCancelAllObserveCallback ( uplinkHandler , client ) ;
var rpcCallback = new RpcCancelObserveCallback ( transportService , client , requestMsg , mainCallback ) ;
downlinkHandler . sendCancelAllRequest ( client , downlink , rpcCallback ) ;
}
private String getIdFromParameters ( LwM2mClient client , TransportProtos . ToDeviceRpcRequestMsg rpcRequst ) {