|
@@ -660,9 +660,13 @@ void Service_Read_single(UA_Server *server, UA_Session *session,
|
|
case UA_ATTRIBUTEID_WRITEMASK:
|
|
case UA_ATTRIBUTEID_WRITEMASK:
|
|
forceVariantSetScalar(&v->value, &node->writeMask, &UA_TYPES[UA_TYPES_UINT32]);
|
|
forceVariantSetScalar(&v->value, &node->writeMask, &UA_TYPES[UA_TYPES_UINT32]);
|
|
break;
|
|
break;
|
|
- case UA_ATTRIBUTEID_USERWRITEMASK:
|
|
|
|
- forceVariantSetScalar(&v->value, &node->userWriteMask, &UA_TYPES[UA_TYPES_UINT32]);
|
|
|
|
- break;
|
|
|
|
|
|
+ case UA_ATTRIBUTEID_USERWRITEMASK: {
|
|
|
|
+ UA_UInt32 userWriteMask = node->writeMask;
|
|
|
|
+ userWriteMask &=
|
|
|
|
+ server->config.accessControl.getUserRightsMask(&session->sessionId,
|
|
|
|
+ session->sessionHandle, &id->nodeId);
|
|
|
|
+ forceVariantSetScalar(&v->value, &userWriteMask, &UA_TYPES[UA_TYPES_UINT32]);
|
|
|
|
+ break; }
|
|
case UA_ATTRIBUTEID_ISABSTRACT:
|
|
case UA_ATTRIBUTEID_ISABSTRACT:
|
|
retval = readIsAbstractAttribute(node, &v->value);
|
|
retval = readIsAbstractAttribute(node, &v->value);
|
|
break;
|
|
break;
|
|
@@ -710,11 +714,14 @@ void Service_Read_single(UA_Server *server, UA_Session *session,
|
|
forceVariantSetScalar(&v->value, &((const UA_VariableNode*)node)->accessLevel,
|
|
forceVariantSetScalar(&v->value, &((const UA_VariableNode*)node)->accessLevel,
|
|
&UA_TYPES[UA_TYPES_BYTE]);
|
|
&UA_TYPES[UA_TYPES_BYTE]);
|
|
break;
|
|
break;
|
|
- case UA_ATTRIBUTEID_USERACCESSLEVEL:
|
|
|
|
|
|
+ case UA_ATTRIBUTEID_USERACCESSLEVEL: {
|
|
CHECK_NODECLASS(UA_NODECLASS_VARIABLE);
|
|
CHECK_NODECLASS(UA_NODECLASS_VARIABLE);
|
|
- forceVariantSetScalar(&v->value, &((const UA_VariableNode*)node)->userAccessLevel,
|
|
|
|
- &UA_TYPES[UA_TYPES_BYTE]);
|
|
|
|
- break;
|
|
|
|
|
|
+ UA_Byte userAccessLevel = ((const UA_VariableNode*)node)->accessLevel;
|
|
|
|
+ userAccessLevel &=
|
|
|
|
+ server->config.accessControl.getUserAccessLevel(&session->sessionId,
|
|
|
|
+ session->sessionHandle, &id->nodeId);
|
|
|
|
+ forceVariantSetScalar(&v->value, &userAccessLevel, &UA_TYPES[UA_TYPES_BYTE]);
|
|
|
|
+ break; }
|
|
case UA_ATTRIBUTEID_MINIMUMSAMPLINGINTERVAL:
|
|
case UA_ATTRIBUTEID_MINIMUMSAMPLINGINTERVAL:
|
|
CHECK_NODECLASS(UA_NODECLASS_VARIABLE);
|
|
CHECK_NODECLASS(UA_NODECLASS_VARIABLE);
|
|
forceVariantSetScalar(&v->value, &((const UA_VariableNode*)node)->minimumSamplingInterval,
|
|
forceVariantSetScalar(&v->value, &((const UA_VariableNode*)node)->minimumSamplingInterval,
|
|
@@ -730,11 +737,14 @@ void Service_Read_single(UA_Server *server, UA_Session *session,
|
|
forceVariantSetScalar(&v->value, &((const UA_MethodNode*)node)->executable,
|
|
forceVariantSetScalar(&v->value, &((const UA_MethodNode*)node)->executable,
|
|
&UA_TYPES[UA_TYPES_BOOLEAN]);
|
|
&UA_TYPES[UA_TYPES_BOOLEAN]);
|
|
break;
|
|
break;
|
|
- case UA_ATTRIBUTEID_USEREXECUTABLE:
|
|
|
|
|
|
+ case UA_ATTRIBUTEID_USEREXECUTABLE: {
|
|
CHECK_NODECLASS(UA_NODECLASS_METHOD);
|
|
CHECK_NODECLASS(UA_NODECLASS_METHOD);
|
|
- forceVariantSetScalar(&v->value, &((const UA_MethodNode*)node)->userExecutable,
|
|
|
|
- &UA_TYPES[UA_TYPES_BOOLEAN]);
|
|
|
|
- break;
|
|
|
|
|
|
+ UA_Boolean userExecutable = ((const UA_MethodNode*)node)->executable;
|
|
|
|
+ userExecutable &=
|
|
|
|
+ server->config.accessControl.getUserExecutable(&session->sessionId,
|
|
|
|
+ session->sessionHandle, &id->nodeId);
|
|
|
|
+ forceVariantSetScalar(&v->value, &userExecutable, &UA_TYPES[UA_TYPES_BOOLEAN]);
|
|
|
|
+ break; }
|
|
default:
|
|
default:
|
|
retval = UA_STATUSCODE_BADATTRIBUTEIDINVALID;
|
|
retval = UA_STATUSCODE_BADATTRIBUTEIDINVALID;
|
|
}
|
|
}
|
|
@@ -964,6 +974,9 @@ CopyAttributeIntoNode(UA_Server *server, UA_Session *session,
|
|
switch(wvalue->attributeId) {
|
|
switch(wvalue->attributeId) {
|
|
case UA_ATTRIBUTEID_NODEID:
|
|
case UA_ATTRIBUTEID_NODEID:
|
|
case UA_ATTRIBUTEID_NODECLASS:
|
|
case UA_ATTRIBUTEID_NODECLASS:
|
|
|
|
+ case UA_ATTRIBUTEID_USERWRITEMASK:
|
|
|
|
+ case UA_ATTRIBUTEID_USERACCESSLEVEL:
|
|
|
|
+ case UA_ATTRIBUTEID_USEREXECUTABLE:
|
|
retval = UA_STATUSCODE_BADWRITENOTSUPPORTED;
|
|
retval = UA_STATUSCODE_BADWRITENOTSUPPORTED;
|
|
break;
|
|
break;
|
|
case UA_ATTRIBUTEID_BROWSENAME:
|
|
case UA_ATTRIBUTEID_BROWSENAME:
|
|
@@ -985,10 +998,6 @@ CopyAttributeIntoNode(UA_Server *server, UA_Session *session,
|
|
CHECK_DATATYPE_SCALAR(UINT32);
|
|
CHECK_DATATYPE_SCALAR(UINT32);
|
|
node->writeMask = *(const UA_UInt32*)value;
|
|
node->writeMask = *(const UA_UInt32*)value;
|
|
break;
|
|
break;
|
|
- case UA_ATTRIBUTEID_USERWRITEMASK:
|
|
|
|
- CHECK_DATATYPE_SCALAR(UINT32);
|
|
|
|
- node->userWriteMask = *(const UA_UInt32*)value;
|
|
|
|
- break;
|
|
|
|
case UA_ATTRIBUTEID_ISABSTRACT:
|
|
case UA_ATTRIBUTEID_ISABSTRACT:
|
|
CHECK_DATATYPE_SCALAR(BOOLEAN);
|
|
CHECK_DATATYPE_SCALAR(BOOLEAN);
|
|
retval = writeIsAbstractAttribute(node, *(const UA_Boolean*)value);
|
|
retval = writeIsAbstractAttribute(node, *(const UA_Boolean*)value);
|
|
@@ -1041,11 +1050,6 @@ CopyAttributeIntoNode(UA_Server *server, UA_Session *session,
|
|
CHECK_DATATYPE_SCALAR(BYTE);
|
|
CHECK_DATATYPE_SCALAR(BYTE);
|
|
((UA_VariableNode*)node)->accessLevel = *(const UA_Byte*)value;
|
|
((UA_VariableNode*)node)->accessLevel = *(const UA_Byte*)value;
|
|
break;
|
|
break;
|
|
- case UA_ATTRIBUTEID_USERACCESSLEVEL:
|
|
|
|
- CHECK_NODECLASS_WRITE(UA_NODECLASS_VARIABLE);
|
|
|
|
- CHECK_DATATYPE_SCALAR(BYTE);
|
|
|
|
- ((UA_VariableNode*)node)->userAccessLevel = *(const UA_Byte*)value;
|
|
|
|
- break;
|
|
|
|
case UA_ATTRIBUTEID_MINIMUMSAMPLINGINTERVAL:
|
|
case UA_ATTRIBUTEID_MINIMUMSAMPLINGINTERVAL:
|
|
CHECK_NODECLASS_WRITE(UA_NODECLASS_VARIABLE);
|
|
CHECK_NODECLASS_WRITE(UA_NODECLASS_VARIABLE);
|
|
CHECK_DATATYPE_SCALAR(DOUBLE);
|
|
CHECK_DATATYPE_SCALAR(DOUBLE);
|
|
@@ -1061,11 +1065,6 @@ CopyAttributeIntoNode(UA_Server *server, UA_Session *session,
|
|
CHECK_DATATYPE_SCALAR(BOOLEAN);
|
|
CHECK_DATATYPE_SCALAR(BOOLEAN);
|
|
((UA_MethodNode*)node)->executable = *(const UA_Boolean*)value;
|
|
((UA_MethodNode*)node)->executable = *(const UA_Boolean*)value;
|
|
break;
|
|
break;
|
|
- case UA_ATTRIBUTEID_USEREXECUTABLE:
|
|
|
|
- CHECK_NODECLASS_WRITE(UA_NODECLASS_METHOD);
|
|
|
|
- CHECK_DATATYPE_SCALAR(BOOLEAN);
|
|
|
|
- ((UA_MethodNode*)node)->userExecutable = *(const UA_Boolean*)value;
|
|
|
|
- break;
|
|
|
|
default:
|
|
default:
|
|
retval = UA_STATUSCODE_BADATTRIBUTEIDINVALID;
|
|
retval = UA_STATUSCODE_BADATTRIBUTEIDINVALID;
|
|
break;
|
|
break;
|