Merge pull request #6697 from jpfr/merge_14_master_21

Merge 1.4 to master
This commit is contained in:
Julius Pfrommer 2024-09-11 17:17:08 +02:00 committed by GitHub
commit c214e37aaa
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 94 additions and 8 deletions

View File

@ -1103,7 +1103,7 @@ typedef struct UA_DataTypeArray {
* If the member is an array, the offset points to the (size_t) length field.
* (The array pointer comes after the length field without any padding.) */
#ifdef UA_ENABLE_TYPEDESCRIPTION
UA_Boolean
UA_Boolean UA_EXPORT
UA_DataType_getStructMember(const UA_DataType *type,
const char *memberName,
size_t *outOffset,
@ -1114,7 +1114,7 @@ UA_DataType_getStructMember(const UA_DataType *type,
/* Test if the data type is a numeric builtin data type (via the typeKind field
* of UA_DataType). This includes integers and floating point numbers. Not
* included are Boolean, DateTime, StatusCode and Enums. */
UA_Boolean
UA_Boolean UA_EXPORT
UA_DataType_isNumeric(const UA_DataType *type);
/**

View File

@ -407,6 +407,8 @@ verifyCertificate(UA_CertificateGroup *certGroup, const UA_ByteString *certifica
opensslRet = X509_STORE_CTX_get_error(storeCtx);
if(opensslRet == X509_V_ERR_UNABLE_TO_GET_CRL) {
ret = UA_STATUSCODE_BADCERTIFICATEISSUERREVOCATIONUNKNOWN;
} else {
ret = UA_X509_Store_CTX_Error_To_UAError (opensslRet);
}
}
}

View File

@ -443,7 +443,7 @@ setDefaultConfig(UA_ServerConfig *conf, UA_UInt16 portNumber) {
conf->modellingRulesOnInstances = true;
/* Limits for SecureChannels */
conf->maxSecureChannels = 40;
conf->maxSecureChannels = 100;
conf->maxSecurityTokenLifetime = 10 * 60 * 1000; /* 10 minutes */
/* Limits for Sessions */

View File

@ -882,7 +882,12 @@ AttributeReadCallback(UA_Client *client, void *userdata,
/* Check the type. Try to adjust "in situ" if no match. */
if(!UA_Variant_hasScalarType(&dv->value, ctx->resultType)) {
/* Remember the old pointer, adjustType can "unwrap" a type but won't
* free the wrapper. Because the server code still keeps the wrapper. */
void *oldVal = dv->value.data;
adjustType(&dv->value, ctx->resultType);
if(dv->value.data != oldVal)
UA_free(oldVal);
if(!UA_Variant_hasScalarType(&dv->value, ctx->resultType)) {
res = UA_STATUSCODE_BADINTERNALERROR;
goto finish;

View File

@ -796,7 +796,7 @@ UA_Server_run_startup(UA_Server *server) {
/* Are there enough SecureChannels possible for the max number of sessions? */
if(config->maxSecureChannels != 0 &&
(config->maxSessions == 0 || config->maxSessions >= config->maxSecureChannels)) {
(config->maxSessions == 0 || config->maxSessions > config->maxSecureChannels)) {
UA_LOG_WARNING(config->logging, UA_LOGCATEGORY_SERVER,
"Maximum SecureChannels count not enough for the "
"maximum Sessions count");
@ -810,6 +810,7 @@ UA_Server_run_startup(UA_Server *server) {
"Could not create the server housekeeping task");
/* Ensure that the uri for ns1 is set up from the app description */
UA_String_clear(&server->namespaces[1]);
setupNs1Uri(server);
/* At least one endpoint has to be configured */

View File

@ -2053,7 +2053,7 @@ UA_Array_append(void **p, size_t *size, void *newElem,
return UA_STATUSCODE_GOOD;
}
UA_StatusCode UA_EXPORT
UA_StatusCode
UA_Array_appendCopy(void **p, size_t *size, const void *newElem,
const UA_DataType *type) {
char scratch[512];

View File

@ -78,8 +78,6 @@ adjustType(UA_Variant *value, const UA_DataType *targetType) {
value->type = &UA_TYPES[UA_TYPES_BYTE];
value->arrayLength = str->length;
value->data = str->data;
if(value->storageType != UA_VARIANT_DATA_NODELETE)
UA_free(str);
return;
}

View File

@ -28,7 +28,12 @@ _UA_BEGIN_DECLS
#define UA_MACRO_EXPAND(x) x
/* Try if the type of the value can be adjusted "in situ" to the target type.
* That can be done, for example, to map between int32 and an enum. */
* That can be done, for example, to map between int32 and an enum.
*
* This can also "unwrap" a type. For example: string -> array of bytes
*
* If value->data is changed during adjustType, free the pointer afterwards (if
* you did not keep the original variant for _clear). */
void
adjustType(UA_Variant *value, const UA_DataType *targetType);

View File

@ -15,6 +15,27 @@
#pragma clang diagnostic ignored "-Wincompatible-pointer-types-discards-qualifiers"
#endif
START_TEST(Server_Namespace1_check) {
UA_Server *server = UA_Server_new();
UA_ServerConfig *config = UA_Server_getConfig(server);
const char *namespace1 = "http://namespace1";
UA_String_clear(&config->applicationDescription.applicationUri);
config->applicationDescription.applicationUri = UA_STRING_ALLOC(namespace1);
UA_Server_run_startup(server);
UA_String out;
UA_StatusCode status = UA_Server_getNamespaceByIndex(server, 1, &out);
ck_assert(status == UA_STATUSCODE_GOOD);
ck_assert(UA_String_equal(&out, &config->applicationDescription.applicationUri));
UA_String_clear(&out);
UA_Server_run_shutdown(server);
UA_Server_delete(server);
}
END_TEST
START_TEST(Server_addNamespace_ShallWork) {
UA_Server *server = UA_Server_newForUnitTest();
@ -185,6 +206,7 @@ START_TEST(Server_forEachChildNodeCall) {
static Suite* testSuite_ServerUserspace(void) {
Suite *s = suite_create("ServerUserspace");
TCase *tc_core = tcase_create("Core");
tcase_add_test(tc_core, Server_Namespace1_check);
tcase_add_test(tc_core, Server_addNamespace_ShallWork);
tcase_add_test(tc_core, Server_addNamespace_writeService);
tcase_add_test(tc_core, Server_forEachChildNodeCall);

View File

@ -894,6 +894,58 @@ START_TEST(WriteSingleAttributeValueEnum) {
UA_DataValue_clear(&resp);
} END_TEST
/* Writing a ByteString into a byte array */
START_TEST(WriteSingleAttributeStringToByteArray) {
UA_WriteValue wValue;
UA_WriteValue_init(&wValue);
UA_VariableAttributes vattr = UA_VariableAttributes_default;
UA_Byte testArray[4] = {1,2,3,4};
UA_UInt32 testArrayDims[1] = {4};
UA_Variant_setArray(&vattr.value, testArray, 4, &UA_TYPES[UA_TYPES_BYTE]);
vattr.value.arrayDimensions = testArrayDims;
vattr.value.arrayDimensionsSize = 1;
vattr.description = UA_LOCALIZEDTEXT("locale","test array");
vattr.displayName = UA_LOCALIZEDTEXT("locale","test array");
vattr.valueRank = UA_VALUERANK_ONE_DIMENSION;
vattr.arrayDimensions = testArrayDims;
vattr.arrayDimensionsSize = 1;
vattr.dataType = UA_TYPES[UA_TYPES_BYTE].typeId;
UA_QualifiedName arrayName = UA_QUALIFIEDNAME(1, "test array");
UA_NodeId arrayNodeId = UA_NODEID_STRING(1, "test.array");
UA_NodeId parentNodeId = UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER);
UA_NodeId parentReferenceNodeId = UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES);
UA_StatusCode retval =
UA_Server_addVariableNode(server, arrayNodeId, parentNodeId,
parentReferenceNodeId, arrayName,
UA_NODEID_NUMERIC(0, UA_NS0ID_BASEDATAVARIABLETYPE),
vattr, NULL, NULL);
ck_assert_int_eq(retval, UA_STATUSCODE_GOOD);
UA_String testString = UA_STRING("open");
UA_Variant_setScalar(&wValue.value.value, &testString, &UA_TYPES[UA_TYPES_BYTESTRING]);
wValue.value.hasValue = true;
wValue.nodeId = UA_NODEID_STRING(1, "test.array");
wValue.attributeId = UA_ATTRIBUTEID_VALUE;
retval = UA_Server_write(server, &wValue);
ck_assert_int_eq(retval, UA_STATUSCODE_GOOD);
UA_ReadValueId rvi;
UA_ReadValueId_init(&rvi);
rvi.nodeId = UA_NODEID_STRING(1, "test.array");
rvi.attributeId = UA_ATTRIBUTEID_VALUE;
UA_DataValue resp = UA_Server_read(server, &rvi, UA_TIMESTAMPSTORETURN_NEITHER);
ck_assert_int_eq(resp.status, UA_STATUSCODE_GOOD);
ck_assert(resp.hasValue);
ck_assert(UA_Variant_hasArrayType(&resp.value, &UA_TYPES[UA_TYPES_BYTE]));
UA_Byte *arr = (UA_Byte*)resp.value.data;
arr[0] = 'o';
arr[1] = 'p';
UA_DataValue_clear(&resp);
} END_TEST
START_TEST(WriteSingleAttributeValueRangeFromScalar) {
UA_WriteValue wValue;
UA_WriteValue_init(&wValue);
@ -1179,6 +1231,7 @@ static Suite * testSuite_services_attributes(void) {
tcase_add_test(tc_writeSingleAttributes, WriteSingleAttributeValue);
tcase_add_test(tc_writeSingleAttributes, WriteSingleAttributeValueWithServerTimestamp);
tcase_add_test(tc_writeSingleAttributes, WriteSingleAttributeValueEnum);
tcase_add_test(tc_writeSingleAttributes, WriteSingleAttributeStringToByteArray);
tcase_add_test(tc_writeSingleAttributes, WriteSingleAttributeDataType);
tcase_add_test(tc_writeSingleAttributes, WriteSingleAttributeValueRangeFromScalar);
tcase_add_test(tc_writeSingleAttributes, WriteSingleAttributeValueRangeFromArray);