Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | update open62541 in topcua to version 1.1.1 |
---|---|
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
5c2593aec3f08f3ce9e77a4cac68325b |
User & Date: | chw 2020-06-26 04:03:38.704 |
Context
2020-06-26
| ||
17:08 | add tklib upstream changes check-in: 3b7f05717f user: chw tags: trunk | |
04:04 | merge with trunk check-in: 850f4434c6 user: chw tags: wtf-8-experiment | |
04:03 | update open62541 in topcua to version 1.1.1 check-in: 5c2593aec3 user: chw tags: trunk | |
2020-06-25
| ||
15:23 | add selected tclx upstream changes check-in: c48d702f1a user: chw tags: trunk | |
Changes
Changes to jni/topcua/library/topcua.tcl.
︙ | ︙ | |||
731 732 733 734 735 736 737 | append bsd "</opc:TypeDictionary>\n" # store *.bsd type defs into node write $handle $tt ByteString $bsd } # Make some procs visible in opcua ensemble. | | | | < | < < | 731 732 733 734 735 736 737 738 739 740 741 742 743 744 | append bsd "</opc:TypeDictionary>\n" # store *.bsd type defs into node write $handle $tt ByteString $bsd } # Make some procs visible in opcua ensemble. apply [list ns { set cmds [::namespace ensemble configure $ns -subcommands] lappend cmds tree ptree children parent genstubs gentypes deftypes ::namespace ensemble configure $ns -subcommands $cmds } [::namespace current]] [::namespace current] } |
Changes to jni/topcua/open62541/chw.patch.
1 2 3 4 5 | The following patch relaxes type checking on attribute R/W functions. This simplifies the "opcua read ..." and "opcua write ..." logic. It changes the default timeout to 10 milliseconds and adds some functions to set the custom data type array on client and server. | | | | | | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 | The following patch relaxes type checking on attribute R/W functions. This simplifies the "opcua read ..." and "opcua write ..." logic. It changes the default timeout to 10 milliseconds and adds some functions to set the custom data type array on client and server. --- open62541.c.orig 2020-06-25 01:20:20.000000000 +0200 +++ open62541.c 2020-06-25 19:24:48.807730720 +0200 @@ -23272,7 +23272,7 @@ /* Main Server Loop */ /********************/ -#define UA_MAXTIMEOUT 50 /* Max timeout in ms between main-loop iterations */ +#define UA_MAXTIMEOUT 10 /* Max timeout in ms between main-loop iterations */ /* Start: Spin up the workers and the network layer and sample the server's * start time. @@ -43938,7 +43938,7 @@ UA_WriteValue_init(&wValue); wValue.nodeId = *nodeId; wValue.attributeId = attributeId; - if(attributeId == UA_ATTRIBUTEID_VALUE) + if(attributeId == UA_ATTRIBUTEID_VALUE && inDataType == &UA_TYPES[UA_TYPES_VARIANT]) wValue.value.value = *(const UA_Variant*)in; else /* hack. is never written into. */ @@ -44040,13 +44040,16 @@ if(attributeId == UA_ATTRIBUTEID_VALUE) { memcpy(out, &res->value, sizeof(UA_Variant)); UA_Variant_init(&res->value); - } else if(attributeId == UA_ATTRIBUTEID_NODECLASS) { + } else if(attributeId == UA_ATTRIBUTEID_NODECLASS && outDataType != &UA_TYPES[UA_TYPES_VARIANT]) { memcpy(out, (UA_NodeClass*)res->value.data, sizeof(UA_NodeClass)); } else if(UA_Variant_isScalar(&res->value) && res->value.type == outDataType) { memcpy(out, res->value.data, res->value.type->memSize); UA_free(res->value.data); res->value.data = NULL; + } else if(UA_Variant_isScalar(&res->value) && outDataType == &UA_TYPES[UA_TYPES_VARIANT]) { + memcpy(out, &res->value, sizeof(UA_Variant)); + UA_Variant_init(&res->value); } else { retval = UA_STATUSCODE_BADUNEXPECTEDERROR; } @@ -58822,7 +58825,7 @@ time_t gmt, rawtime = time(NULL); struct tm ptm; - gmtime_s(&ptm, &rawtime); + ptm = *gmtime(&rawtime); // Request that mktime() looksup dst in timezone database ptm.tm_isdst = -1; gmt = mktime(&ptm); @@ -59932,3 +59935,17 @@ return connection; } + +UA_StatusCode +UA_Client_setCustomDataTypes(UA_Client *client, const UA_DataTypeArray *types) { + client->config.customDataTypes = types; + + return UA_STATUSCODE_GOOD; +} + +UA_StatusCode +UA_Server_setCustomDataTypes(UA_Server *server, const UA_DataTypeArray *types) { + server->config.customDataTypes = types; + + return UA_STATUSCODE_GOOD; +} --- open62541.h.orig 2020-06-25 01:20:20.000000000 +0200 +++ open62541.h 2020-06-25 19:18:59.274333038 +0200 @@ -102,7 +102,7 @@ * On Win32: Define ``UA_DYNAMIC_LINKING`` and ``UA_DYNAMIC_LINKING_EXPORT`` in * order to export symbols for a DLL. Define ``UA_DYNAMIC_LINKING`` only to * import symbols from a DLL.*/ -#define UA_DYNAMIC_LINKING +/* #undef UA_DYNAMIC_LINKING */ /* Shortcuts for extern "C" declarations */ #if !defined(_UA_BEGIN_DECLS) @@ -23459,7 +23459,7 @@ * @param server The server object. * @param waitInternal Should we wait for messages in the networklayer? * Otherwise, the timouts for the networklayers are set to zero. - * The default max wait time is 50millisec. + * The default max wait time is 10millisec. * @return Returns how long we can wait until the next scheduled * callback (in ms) */ UA_UInt16 UA_EXPORT @@ -31406,6 +31406,11 @@ #define UA_fileExists(X) ( UA_access(X, 0) == 0) #endif +UA_StatusCode UA_EXPORT +UA_Client_setCustomDataTypes(UA_Client *client, const UA_DataTypeArray *types); + +UA_StatusCode UA_EXPORT +UA_Server_setCustomDataTypes(UA_Server *server, const UA_DataTypeArray *types); _UA_END_DECLS |
Changes to jni/topcua/open62541/open62541.c.
1 2 | /* THIS IS A SINGLE-FILE DISTRIBUTION CONCATENATED FROM THE OPEN62541 SOURCES * visit http://open62541.org/ for information about this software | | | 1 2 3 4 5 6 7 8 9 10 | /* THIS IS A SINGLE-FILE DISTRIBUTION CONCATENATED FROM THE OPEN62541 SOURCES * visit http://open62541.org/ for information about this software * Git-Revision: v1.1.1 */ /* * Copyright (C) 2014-2018 the contributors as stated in the AUTHORS file * * This file is part of open62541. open62541 is free software: you can * redistribute it and/or modify it under the terms of the Mozilla Public |
︙ | ︙ | |||
1004 1005 1006 1007 1008 1009 1010 | _UA_END_DECLS /*********************************** amalgamated original file "/home/travis/build/open62541/open62541/build/src_generated/open62541/types_generated_encoding_binary.h" ***********************************/ /* Generated from Opc.Ua.Types.bsd with script /home/travis/build/open62541/open62541/tools/generate_datatypes.py | | | 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 | _UA_END_DECLS /*********************************** amalgamated original file "/home/travis/build/open62541/open62541/build/src_generated/open62541/types_generated_encoding_binary.h" ***********************************/ /* Generated from Opc.Ua.Types.bsd with script /home/travis/build/open62541/open62541/tools/generate_datatypes.py * on host travis-job-5b5ec811-e61d-442b-8cf7-c7ae1921c1d9 by user travis at 2020-06-24 10:59:21 */ #ifdef UA_ENABLE_AMALGAMATION #else #endif |
︙ | ︙ | |||
3915 3916 3917 3918 3919 3920 3921 | return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_READEVENTDETAILS], NULL); } /*********************************** amalgamated original file "/home/travis/build/open62541/open62541/build/src_generated/open62541/transport_generated.h" ***********************************/ /* Generated from Opc.Ua.Types.bsd, Custom.Opc.Ua.Transport.bsd with script /home/travis/build/open62541/open62541/tools/generate_datatypes.py | | | 3915 3916 3917 3918 3919 3920 3921 3922 3923 3924 3925 3926 3927 3928 3929 | return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_READEVENTDETAILS], NULL); } /*********************************** amalgamated original file "/home/travis/build/open62541/open62541/build/src_generated/open62541/transport_generated.h" ***********************************/ /* Generated from Opc.Ua.Types.bsd, Custom.Opc.Ua.Transport.bsd with script /home/travis/build/open62541/open62541/tools/generate_datatypes.py * on host travis-job-5b5ec811-e61d-442b-8cf7-c7ae1921c1d9 by user travis at 2020-06-24 10:59:21 */ #ifdef UA_ENABLE_AMALGAMATION #else #endif |
︙ | ︙ | |||
4045 4046 4047 4048 4049 4050 4051 | _UA_END_DECLS /*********************************** amalgamated original file "/home/travis/build/open62541/open62541/build/src_generated/open62541/transport_generated_handling.h" ***********************************/ /* Generated from Opc.Ua.Types.bsd, Custom.Opc.Ua.Transport.bsd with script /home/travis/build/open62541/open62541/tools/generate_datatypes.py | | | 4045 4046 4047 4048 4049 4050 4051 4052 4053 4054 4055 4056 4057 4058 4059 | _UA_END_DECLS /*********************************** amalgamated original file "/home/travis/build/open62541/open62541/build/src_generated/open62541/transport_generated_handling.h" ***********************************/ /* Generated from Opc.Ua.Types.bsd, Custom.Opc.Ua.Transport.bsd with script /home/travis/build/open62541/open62541/tools/generate_datatypes.py * on host travis-job-5b5ec811-e61d-442b-8cf7-c7ae1921c1d9 by user travis at 2020-06-24 10:59:21 */ _UA_BEGIN_DECLS #if defined(__GNUC__) && __GNUC__ >= 4 && __GNUC_MINOR__ >= 6 # pragma GCC diagnostic push |
︙ | ︙ | |||
4316 4317 4318 4319 4320 4321 4322 | _UA_END_DECLS /*********************************** amalgamated original file "/home/travis/build/open62541/open62541/build/src_generated/open62541/transport_generated_encoding_binary.h" ***********************************/ /* Generated from Opc.Ua.Types.bsd, Custom.Opc.Ua.Transport.bsd with script /home/travis/build/open62541/open62541/tools/generate_datatypes.py | | | 4316 4317 4318 4319 4320 4321 4322 4323 4324 4325 4326 4327 4328 4329 4330 | _UA_END_DECLS /*********************************** amalgamated original file "/home/travis/build/open62541/open62541/build/src_generated/open62541/transport_generated_encoding_binary.h" ***********************************/ /* Generated from Opc.Ua.Types.bsd, Custom.Opc.Ua.Transport.bsd with script /home/travis/build/open62541/open62541/tools/generate_datatypes.py * on host travis-job-5b5ec811-e61d-442b-8cf7-c7ae1921c1d9 by user travis at 2020-06-24 10:59:21 */ #ifdef UA_ENABLE_AMALGAMATION #else #endif |
︙ | ︙ | |||
4521 4522 4523 4524 4525 4526 4527 4528 | UA_Boolean copied; /* Do the bytes point to a buffer from the network or was * memory allocated for the chunk separately */ UA_Boolean decrypted; /* The chunk has been decrypted */ } UA_Chunk; typedef SIMPLEQ_HEAD(UA_ChunkQueue, UA_Chunk) UA_ChunkQueue; struct UA_SecureChannel { | > > > > > > > > > > > > > > > > > > | > | | | | < | | 4521 4522 4523 4524 4525 4526 4527 4528 4529 4530 4531 4532 4533 4534 4535 4536 4537 4538 4539 4540 4541 4542 4543 4544 4545 4546 4547 4548 4549 4550 4551 4552 4553 4554 4555 4556 4557 4558 4559 4560 4561 4562 4563 4564 4565 4566 4567 4568 | UA_Boolean copied; /* Do the bytes point to a buffer from the network or was * memory allocated for the chunk separately */ UA_Boolean decrypted; /* The chunk has been decrypted */ } UA_Chunk; typedef SIMPLEQ_HEAD(UA_ChunkQueue, UA_Chunk) UA_ChunkQueue; typedef enum { UA_SECURECHANNELRENEWSTATE_NORMAL, /* Client has sent an OPN, but not received a response so far. */ UA_SECURECHANNELRENEWSTATE_SENT, /* The server waits for the first request with the new token for the rollover. * The new token is stored in the altSecurityToken. The configured local and * remote symmetric encryption keys are the old ones. */ UA_SECURECHANNELRENEWSTATE_NEWTOKEN_SERVER, /* The client already uses the new token. But he waits for the server to respond * with the new token to complete the rollover. The old token is stored in * altSecurityToken. The local symmetric encryption key is new. The remote * encryption key is the old one. */ UA_SECURECHANNELRENEWSTATE_NEWTOKEN_CLIENT } UA_SecureChannelRenewState; struct UA_SecureChannel { UA_SecureChannelState state; UA_SecureChannelRenewState renewState; UA_MessageSecurityMode securityMode; UA_ConnectionConfig config; /* Rules for revolving the token with a renew OPN request: The client is * allowed to accept messages with the old token until the OPN response has * arrived. The server accepts the old token until one message secured with * the new token has arrived. * * We recognize whether nextSecurityToken contains a valid next token if the * ChannelId is not 0. */ UA_ChannelSecurityToken securityToken; /* Also contains the channelId */ UA_ChannelSecurityToken altSecurityToken; /* Alternative token for the rollover. * See the renewState. */ /* The endpoint and context of the channel */ const UA_SecurityPolicy *securityPolicy; void *channelContext; /* For interaction with the security policy */ UA_Connection *connection; /* Asymmetric encryption info */ |
︙ | ︙ | |||
4592 4593 4594 4595 4596 4597 4598 | const UA_SecurityPolicy *securityPolicy, const UA_ByteString *remoteCertificate); /* Remove (partially) received unprocessed chunks */ void UA_SecureChannel_deleteBuffered(UA_SecureChannel *channel); | < < < < | | 4610 4611 4612 4613 4614 4615 4616 4617 4618 4619 4620 4621 4622 4623 4624 4625 4626 4627 4628 4629 4630 4631 | const UA_SecurityPolicy *securityPolicy, const UA_ByteString *remoteCertificate); /* Remove (partially) received unprocessed chunks */ void UA_SecureChannel_deleteBuffered(UA_SecureChannel *channel); /* Wrapper function for generating a local nonce for the supplied channel. Uses * the random generator of the channels security policy to allocate and generate * a nonce with the specified length. */ UA_StatusCode UA_SecureChannel_generateLocalNonce(UA_SecureChannel *channel); UA_StatusCode UA_SecureChannel_generateLocalKeys(const UA_SecureChannel *channel); /** * Sending Messages * ---------------- */ UA_StatusCode UA_SecureChannel_sendAsymmetricOPNMessage(UA_SecureChannel *channel, UA_UInt32 requestId, |
︙ | ︙ | |||
6445 6446 6447 6448 6449 6450 6451 6452 6453 6454 6455 6456 6457 6458 | UA_Server_closeSecureChannel(UA_Server *server, UA_SecureChannel *channel, UA_DiagnosticEvent event); /********************/ /* Session Handling */ /********************/ UA_StatusCode getBoundSession(UA_Server *server, const UA_SecureChannel *channel, const UA_NodeId *token, UA_Session **session); UA_StatusCode UA_Server_createSession(UA_Server *server, UA_SecureChannel *channel, const UA_CreateSessionRequest *request, UA_Session **session); | > > > > | 6459 6460 6461 6462 6463 6464 6465 6466 6467 6468 6469 6470 6471 6472 6473 6474 6475 6476 | UA_Server_closeSecureChannel(UA_Server *server, UA_SecureChannel *channel, UA_DiagnosticEvent event); /********************/ /* Session Handling */ /********************/ UA_StatusCode getNamespaceByName(UA_Server *server, const UA_String namespaceUri, size_t *foundIndex); UA_StatusCode getBoundSession(UA_Server *server, const UA_SecureChannel *channel, const UA_NodeId *token, UA_Session **session); UA_StatusCode UA_Server_createSession(UA_Server *server, UA_SecureChannel *channel, const UA_CreateSessionRequest *request, UA_Session **session); |
︙ | ︙ | |||
7402 7403 7404 7405 7406 7407 7408 | UA_StatusCode connectStatus; /* Old status to notify only changes */ UA_SecureChannelState oldChannelState; UA_SessionState oldSessionState; UA_StatusCode oldConnectStatus; | < | 7420 7421 7422 7423 7424 7425 7426 7427 7428 7429 7430 7431 7432 7433 | UA_StatusCode connectStatus; /* Old status to notify only changes */ UA_SecureChannelState oldChannelState; UA_SessionState oldSessionState; UA_StatusCode oldConnectStatus; UA_Boolean endpointsHandshake; /* Ongoing GetEndpoints */ UA_Boolean noSession; /* Don't open a session */ /* Connection */ UA_Connection connection; UA_String endpointUrl; /* Only for the async connect */ |
︙ | ︙ | |||
10904 10905 10906 10907 10908 10909 10910 | UA_calcSizeBinary(const void *p, const UA_DataType *type) { return calcSizeBinaryJumpTable[type->typeKind](p, type); } /*********************************** amalgamated original file "/home/travis/build/open62541/open62541/build/src_generated/open62541/types_generated.c" ***********************************/ /* Generated from Opc.Ua.Types.bsd with script /home/travis/build/open62541/open62541/tools/generate_datatypes.py | | | 10921 10922 10923 10924 10925 10926 10927 10928 10929 10930 10931 10932 10933 10934 10935 | UA_calcSizeBinary(const void *p, const UA_DataType *type) { return calcSizeBinaryJumpTable[type->typeKind](p, type); } /*********************************** amalgamated original file "/home/travis/build/open62541/open62541/build/src_generated/open62541/types_generated.c" ***********************************/ /* Generated from Opc.Ua.Types.bsd with script /home/travis/build/open62541/open62541/tools/generate_datatypes.py * on host travis-job-5b5ec811-e61d-442b-8cf7-c7ae1921c1d9 by user travis at 2020-06-24 10:59:21 */ /* Boolean */ #define Boolean_members NULL /* SByte */ #define SByte_members NULL |
︙ | ︙ | |||
18857 18858 18859 18860 18861 18862 18863 | }, }; /*********************************** amalgamated original file "/home/travis/build/open62541/open62541/build/src_generated/open62541/transport_generated.c" ***********************************/ /* Generated from Opc.Ua.Types.bsd, Custom.Opc.Ua.Transport.bsd with script /home/travis/build/open62541/open62541/tools/generate_datatypes.py | | | 18874 18875 18876 18877 18878 18879 18880 18881 18882 18883 18884 18885 18886 18887 18888 | }, }; /*********************************** amalgamated original file "/home/travis/build/open62541/open62541/build/src_generated/open62541/transport_generated.c" ***********************************/ /* Generated from Opc.Ua.Types.bsd, Custom.Opc.Ua.Transport.bsd with script /home/travis/build/open62541/open62541/tools/generate_datatypes.py * on host travis-job-5b5ec811-e61d-442b-8cf7-c7ae1921c1d9 by user travis at 2020-06-24 10:59:21 */ /* TcpHelloMessage */ static UA_DataTypeMember TcpHelloMessage_members[6] = { { UA_TYPENAME("ProtocolVersion") /* .memberName */ UA_TYPES_UINT32, /* .memberTypeIndex */ |
︙ | ︙ | |||
20373 20374 20375 20376 20377 20378 20379 | if(channel->securityPolicy) { channel->securityPolicy->channelModule.deleteContext(channel->channelContext); channel->securityPolicy = NULL; channel->channelContext = NULL; } /* Delete members */ | | | | | | | 20390 20391 20392 20393 20394 20395 20396 20397 20398 20399 20400 20401 20402 20403 20404 20405 20406 20407 20408 | if(channel->securityPolicy) { channel->securityPolicy->channelModule.deleteContext(channel->channelContext); channel->securityPolicy = NULL; channel->channelContext = NULL; } /* Delete members */ UA_ByteString_clear(&channel->remoteCertificate); UA_ByteString_clear(&channel->localNonce); UA_ByteString_clear(&channel->remoteNonce); UA_ChannelSecurityToken_clear(&channel->securityToken); UA_ChannelSecurityToken_clear(&channel->altSecurityToken); UA_SecureChannel_deleteBuffered(channel); } UA_StatusCode UA_SecureChannel_processHELACK(UA_SecureChannel *channel, const UA_TcpAcknowledgeMessage *remoteConfig) { /* The lowest common version is used by both sides */ |
︙ | ︙ | |||
20525 20526 20527 20528 20529 20530 20531 | header.messageTypeAndChunkType = messageContext->messageType; header.messageSize = (UA_UInt32)totalLength; if(messageContext->final) header.messageTypeAndChunkType += UA_CHUNKTYPE_FINAL; else header.messageTypeAndChunkType += UA_CHUNKTYPE_INTERMEDIATE; | < < < < < < < | | 20542 20543 20544 20545 20546 20547 20548 20549 20550 20551 20552 20553 20554 20555 20556 20557 20558 20559 20560 20561 20562 20563 20564 20565 | header.messageTypeAndChunkType = messageContext->messageType; header.messageSize = (UA_UInt32)totalLength; if(messageContext->final) header.messageTypeAndChunkType += UA_CHUNKTYPE_FINAL; else header.messageTypeAndChunkType += UA_CHUNKTYPE_INTERMEDIATE; UA_SequenceHeader seqHeader; seqHeader.requestId = messageContext->requestId; seqHeader.sequenceNumber = UA_atomic_addUInt32(&channel->sendSequenceNumber, 1); UA_StatusCode res = UA_STATUSCODE_GOOD; res |= UA_encodeBinary(&header, &UA_TRANSPORT[UA_TRANSPORT_TCPMESSAGEHEADER], &header_pos, &messageContext->buf_end, NULL, NULL); res |= UA_encodeBinary(&channel->securityToken.channelId, &UA_TYPES[UA_TYPES_UINT32], &header_pos, &messageContext->buf_end, NULL, NULL); res |= UA_encodeBinary(&channel->securityToken.tokenId, &UA_TYPES[UA_TYPES_UINT32], &header_pos, &messageContext->buf_end, NULL, NULL); res |= UA_encodeBinary(&seqHeader, &UA_TRANSPORT[UA_TRANSPORT_SEQUENCEHEADER], &header_pos, &messageContext->buf_end, NULL, NULL); return res; } static UA_StatusCode |
︙ | ︙ | |||
21207 21208 21209 21210 21211 21212 21213 | if(retval != UA_STATUSCODE_GOOD) return retval; } return sp->symmetricModule.generateNonce(sp, &channel->localNonce); } | | | | > > > > | 21217 21218 21219 21220 21221 21222 21223 21224 21225 21226 21227 21228 21229 21230 21231 21232 21233 21234 21235 21236 21237 21238 | if(retval != UA_STATUSCODE_GOOD) return retval; } return sp->symmetricModule.generateNonce(sp, &channel->localNonce); } UA_StatusCode UA_SecureChannel_generateLocalKeys(const UA_SecureChannel *channel) { const UA_SecurityPolicy *sp = channel->securityPolicy; if(!sp) return UA_STATUSCODE_BADINTERNALERROR; UA_LOG_TRACE_CHANNEL(sp->logger, channel, "Generating new local keys"); void *cc = channel->channelContext; const UA_SecurityPolicyChannelModule *cm = &sp->channelModule; const UA_SecurityPolicySymmetricModule *sm = &sp->symmetricModule; const UA_SecurityPolicyCryptoModule *crm = &sm->cryptoModule; /* Generate symmetric key buffer of the required length */ UA_ByteString buf; |
︙ | ︙ | |||
21244 21245 21246 21247 21248 21249 21250 | retval |= cm->setLocalSymEncryptingKey(cc, &localEncryptingKey); retval |= cm->setLocalSymIv(cc, &localIv); UA_ByteString_clear(&buf); return retval; } static UA_StatusCode | | | > > > > | 21258 21259 21260 21261 21262 21263 21264 21265 21266 21267 21268 21269 21270 21271 21272 21273 21274 21275 21276 21277 21278 | retval |= cm->setLocalSymEncryptingKey(cc, &localEncryptingKey); retval |= cm->setLocalSymIv(cc, &localIv); UA_ByteString_clear(&buf); return retval; } static UA_StatusCode generateRemoteKeys(const UA_SecureChannel *channel) { const UA_SecurityPolicy *sp = channel->securityPolicy; if(!sp) return UA_STATUSCODE_BADINTERNALERROR; UA_LOG_TRACE_CHANNEL(sp->logger, channel, "Generating new remote keys"); void *cc = channel->channelContext; const UA_SecurityPolicyChannelModule *cm = &sp->channelModule; const UA_SecurityPolicySymmetricModule *sm = &sp->symmetricModule; const UA_SecurityPolicyCryptoModule *crm = &sm->cryptoModule; /* Generate symmetric key buffer of the required length */ UA_ByteString buf; |
︙ | ︙ | |||
21279 21280 21281 21282 21283 21284 21285 | retval |= cm->setRemoteSymSigningKey(cc, &remoteSigningKey); retval |= cm->setRemoteSymEncryptingKey(cc, &remoteEncryptingKey); retval |= cm->setRemoteSymIv(cc, &remoteIv); UA_ByteString_clear(&buf); return retval; } | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 21297 21298 21299 21300 21301 21302 21303 21304 21305 21306 21307 21308 21309 21310 | retval |= cm->setRemoteSymSigningKey(cc, &remoteSigningKey); retval |= cm->setRemoteSymEncryptingKey(cc, &remoteEncryptingKey); retval |= cm->setRemoteSymIv(cc, &remoteIv); UA_ByteString_clear(&buf); return retval; } /***************************/ /* Send Asymmetric Message */ /***************************/ size_t calculateAsymAlgSecurityHeaderLength(const UA_SecureChannel *channel) { const UA_SecurityPolicy *sp = channel->securityPolicy; |
︙ | ︙ | |||
21752 21753 21754 21755 21756 21757 21758 | /* The certificate in the header is verified via the configured PKI plugin * as certificateVerification.verifyCertificate(...). We cannot do it here * because the client/server context is needed. */ } UA_StatusCode checkSymHeader(UA_SecureChannel *channel, UA_UInt32 tokenId) { | > > > > > > > > > | > > | > > > > > > > > > > > > > > > > > > > | > > > > > > | | < | | < < | | | | < < < | < < | | < < < | | 21729 21730 21731 21732 21733 21734 21735 21736 21737 21738 21739 21740 21741 21742 21743 21744 21745 21746 21747 21748 21749 21750 21751 21752 21753 21754 21755 21756 21757 21758 21759 21760 21761 21762 21763 21764 21765 21766 21767 21768 21769 21770 21771 21772 21773 21774 21775 21776 21777 21778 21779 21780 21781 21782 21783 21784 21785 21786 21787 21788 21789 21790 21791 21792 21793 21794 21795 21796 21797 21798 | /* The certificate in the header is verified via the configured PKI plugin * as certificateVerification.verifyCertificate(...). We cannot do it here * because the client/server context is needed. */ } UA_StatusCode checkSymHeader(UA_SecureChannel *channel, UA_UInt32 tokenId) { /* If no match, try to revolve to the next token after a * RenewSecureChannel */ UA_StatusCode retval = UA_STATUSCODE_GOOD; UA_ChannelSecurityToken *token = &channel->securityToken; switch(channel->renewState) { case UA_SECURECHANNELRENEWSTATE_NORMAL: case UA_SECURECHANNELRENEWSTATE_SENT: default: break; case UA_SECURECHANNELRENEWSTATE_NEWTOKEN_SERVER: /* Old token still in use */ if(tokenId == channel->securityToken.tokenId) break; /* Not the new token */ if(tokenId != channel->altSecurityToken.tokenId) { UA_LOG_WARNING_CHANNEL(channel->securityPolicy->logger, channel, "Unknown SecurityToken"); return UA_STATUSCODE_BADSECURECHANNELTOKENUNKNOWN; } /* Roll over to the new token, generate new local and remote keys */ channel->renewState = UA_SECURECHANNELRENEWSTATE_NORMAL; channel->securityToken = channel->altSecurityToken; UA_ChannelSecurityToken_init(&channel->altSecurityToken); retval = UA_SecureChannel_generateLocalKeys(channel); retval |= generateRemoteKeys(channel); break; case UA_SECURECHANNELRENEWSTATE_NEWTOKEN_CLIENT: /* The server is still using the old token. That's okay. */ if(tokenId == channel->altSecurityToken.tokenId) { token = &channel->altSecurityToken; break; } /* Not the new token */ if(tokenId != channel->securityToken.tokenId) { UA_LOG_WARNING_CHANNEL(channel->securityPolicy->logger, channel, "Unknown SecurityToken"); return UA_STATUSCODE_BADSECURECHANNELTOKENUNKNOWN; } /* The remote server uses the new token for the first time. Delete the * old token and roll the remote key over. The local key already uses * the nonce pair from the last OPN exchange. */ channel->renewState = UA_SECURECHANNELRENEWSTATE_NORMAL; UA_ChannelSecurityToken_init(&channel->altSecurityToken); retval = generateRemoteKeys(channel); } if(retval != UA_STATUSCODE_GOOD) return retval; UA_DateTime timeout = token->createdAt + (token->revisedLifetime * UA_DATETIME_MSEC); if(channel->state == UA_SECURECHANNELSTATE_OPEN && timeout < UA_DateTime_nowMonotonic()) { UA_LOG_WARNING_CHANNEL(channel->securityPolicy->logger, channel, "SecurityToken timed out"); UA_SecureChannel_close(channel); return UA_STATUSCODE_BADSECURECHANNELCLOSED; } |
︙ | ︙ | |||
22785 22786 22787 22788 22789 22790 22791 | #define STARTCHANNELID 1 #define STARTTOKENID 1 /**********************/ /* Namespace Handling */ /**********************/ | < | | > | > | | < > > | | | > | 22787 22788 22789 22790 22791 22792 22793 22794 22795 22796 22797 22798 22799 22800 22801 22802 22803 22804 22805 22806 22807 22808 22809 22810 22811 22812 22813 22814 22815 | #define STARTCHANNELID 1 #define STARTTOKENID 1 /**********************/ /* Namespace Handling */ /**********************/ /* The NS1 Uri can be changed by the user to some custom string. This method is * called to initialize the NS1 Uri if it is not set before to the default * Application URI. * * This is done as soon as the Namespace Array is read or written via node value * read / write services, or UA_Server_addNamespace, * UA_Server_getNamespaceByName or UA_Server_run_startup is called. * * Therefore one has to set the custom NS1 URI before one of the previously * mentioned steps. */ void setupNs1Uri(UA_Server *server) { if(!server->namespaces[1].data) { UA_String_copy(&server->config.applicationDescription.applicationUri, &server->namespaces[1]); } } UA_UInt16 addNamespace(UA_Server *server, const UA_String name) { /* ensure that the uri for ns1 is set up from the app description */ setupNs1Uri(server); |
︙ | ︙ | |||
22839 22840 22841 22842 22843 22844 22845 | UA_LOCK(server->serviceMutex); UA_UInt16 retVal = addNamespace(server, nameString); UA_UNLOCK(server->serviceMutex); return retVal; } UA_ServerConfig* | | < | < | | < < | | < | < | > | > > > > > > > > > | | 22844 22845 22846 22847 22848 22849 22850 22851 22852 22853 22854 22855 22856 22857 22858 22859 22860 22861 22862 22863 22864 22865 22866 22867 22868 22869 22870 22871 22872 22873 22874 22875 22876 22877 22878 22879 22880 22881 22882 22883 22884 22885 22886 | UA_LOCK(server->serviceMutex); UA_UInt16 retVal = addNamespace(server, nameString); UA_UNLOCK(server->serviceMutex); return retVal; } UA_ServerConfig* UA_Server_getConfig(UA_Server *server) { if(!server) return NULL; return &server->config; } UA_StatusCode getNamespaceByName(UA_Server *server, const UA_String namespaceUri, size_t *foundIndex) { /* ensure that the uri for ns1 is set up from the app description */ setupNs1Uri(server); UA_StatusCode res = UA_STATUSCODE_BADNOTFOUND; for(size_t idx = 0; idx < server->namespacesSize; idx++) { if(UA_String_equal(&server->namespaces[idx], &namespaceUri)) { (*foundIndex) = idx; res = UA_STATUSCODE_GOOD; break; } } return res; } UA_StatusCode UA_Server_getNamespaceByName(UA_Server *server, const UA_String namespaceUri, size_t *foundIndex) { UA_LOCK(server->serviceMutex); UA_StatusCode res = getNamespaceByName(server, namespaceUri, foundIndex); UA_UNLOCK(server->serviceMutex); return res; } UA_StatusCode UA_Server_forEachChildNodeCall(UA_Server *server, UA_NodeId parentNodeId, UA_NodeIteratorCallback callback, void *handle) { UA_LOCK(server->serviceMutex); const UA_Node *parent = UA_NODESTORE_GET(server, &parentNodeId); |
︙ | ︙ | |||
33692 33693 33694 33695 33696 33697 33698 | * organize the Parameters and Methods from the complete set (named * ParameterSet and MethodSet) in (Functional) groups for instance * Configuration or Identification. The same Property, Parameter or * Method can be referenced from more than one FunctionalGroup. */ /* Check whether the DI namespace is available */ size_t foundNamespace = 0; | | < | 33701 33702 33703 33704 33705 33706 33707 33708 33709 33710 33711 33712 33713 33714 33715 | * organize the Parameters and Methods from the complete set (named * ParameterSet and MethodSet) in (Functional) groups for instance * Configuration or Identification. The same Property, Parameter or * Method can be referenced from more than one FunctionalGroup. */ /* Check whether the DI namespace is available */ size_t foundNamespace = 0; UA_StatusCode res = getNamespaceByName(server, namespaceDiModel, &foundNamespace); if(res != UA_STATUSCODE_GOOD) { result->statusCode = UA_STATUSCODE_BADMETHODINVALID; return; } functionGroupNodeId.namespaceIndex = (UA_UInt16)foundNamespace; /* Search for a HasTypeDefinition (or sub-) reference in the parent object */ |
︙ | ︙ | |||
35523 35524 35525 35526 35527 35528 35529 35530 35531 35532 35533 35534 35535 35536 | switch(valueRank) { case UA_VALUERANK_SCALAR_OR_ONE_DIMENSION: /* The value can be a scalar or a one dimensional array */ return (arrayDims <= 1); case UA_VALUERANK_ANY: /* The value can be a scalar or an array with any number of dimensions */ return true; case UA_VALUERANK_SCALAR: /* The value is a scalar */ return (arrayDims == 0); default: break; } UA_assert(valueRank >= UA_VALUERANK_ONE_OR_MORE_DIMENSIONS); /* case 0: the value is an array with one or more dimensions */ | > > | 35531 35532 35533 35534 35535 35536 35537 35538 35539 35540 35541 35542 35543 35544 35545 35546 | switch(valueRank) { case UA_VALUERANK_SCALAR_OR_ONE_DIMENSION: /* The value can be a scalar or a one dimensional array */ return (arrayDims <= 1); case UA_VALUERANK_ANY: /* The value can be a scalar or an array with any number of dimensions */ return true; case UA_VALUERANK_SCALAR: /* The value is a scalar */ return (arrayDims == 0); case UA_VALUERANK_ONE_OR_MORE_DIMENSIONS: return (arrayDims >= 1); default: break; } UA_assert(valueRank >= UA_VALUERANK_ONE_OR_MORE_DIMENSIONS); /* case 0: the value is an array with one or more dimensions */ |
︙ | ︙ | |||
38469 38470 38471 38472 38473 38474 38475 | if(request->securityMode != UA_MESSAGESECURITYMODE_NONE && UA_ByteString_equal(&channel->securityPolicy->policyUri, &UA_SECURITY_POLICY_NONE_URI)) { return UA_STATUSCODE_BADSECURITYMODEREJECTED; } channel->securityMode = request->securityMode; channel->securityToken.channelId = server->lastChannelId++; | | < > > | | | | | > < < < < < < < | > > | < > > > > > > > | | > | | | | | | | | | < | > > < < < | < < | 38479 38480 38481 38482 38483 38484 38485 38486 38487 38488 38489 38490 38491 38492 38493 38494 38495 38496 38497 38498 38499 38500 38501 38502 38503 38504 38505 38506 38507 38508 38509 38510 38511 38512 38513 38514 38515 38516 38517 38518 38519 38520 38521 38522 38523 38524 38525 38526 38527 38528 38529 38530 38531 38532 38533 38534 38535 38536 38537 38538 38539 38540 38541 38542 38543 38544 38545 38546 38547 38548 38549 38550 38551 38552 38553 38554 38555 38556 38557 38558 38559 38560 38561 38562 38563 38564 38565 38566 38567 38568 38569 38570 38571 38572 38573 38574 38575 38576 38577 38578 38579 | if(request->securityMode != UA_MESSAGESECURITYMODE_NONE && UA_ByteString_equal(&channel->securityPolicy->policyUri, &UA_SECURITY_POLICY_NONE_URI)) { return UA_STATUSCODE_BADSECURITYMODEREJECTED; } channel->securityMode = request->securityMode; channel->securityToken.channelId = server->lastChannelId++; channel->securityToken.createdAt = UA_DateTime_nowMonotonic(); /* Set the lifetime. Lifetime 0 -> set the maximum possible */ channel->securityToken.revisedLifetime = (request->requestedLifetime > server->config.maxSecurityTokenLifetime) ? server->config.maxSecurityTokenLifetime : request->requestedLifetime; if(channel->securityToken.revisedLifetime == 0) channel->securityToken.revisedLifetime = server->config.maxSecurityTokenLifetime; UA_StatusCode retval = UA_ByteString_copy(&request->clientNonce, &channel->remoteNonce); if(retval != UA_STATUSCODE_GOOD) return retval; /* Generate the nonce. The syymmetric encryption keys are generated when the * first symmetric message is received */ retval = UA_SecureChannel_generateLocalNonce(channel); if(retval != UA_STATUSCODE_GOOD) return retval; /* Set the response. The token will be revolved to the new token when the * first symmetric messages is received. */ response->securityToken = channel->securityToken; response->securityToken.createdAt = UA_DateTime_now(); /* Only for sending */ response->responseHeader.timestamp = UA_DateTime_now(); response->responseHeader.requestHandle = request->requestHeader.requestHandle; retval = UA_ByteString_copy(&channel->localNonce, &response->serverNonce); if(retval != UA_STATUSCODE_GOOD) return retval; /* The channel is open */ channel->state = UA_SECURECHANNELSTATE_OPEN; /* For the first revolve */ channel->renewState = UA_SECURECHANNELRENEWSTATE_NEWTOKEN_SERVER; channel->altSecurityToken = channel->securityToken; channel->securityToken.tokenId = 0; return UA_STATUSCODE_GOOD; } static UA_StatusCode UA_SecureChannelManager_renew(UA_Server *server, UA_SecureChannel *channel, const UA_OpenSecureChannelRequest *request, UA_OpenSecureChannelResponse *response) { if(channel->state != UA_SECURECHANNELSTATE_OPEN) { UA_LOG_ERROR_CHANNEL(&server->config.logger, channel, "Called renew on channel which is not open"); return UA_STATUSCODE_BADINTERNALERROR; } /* Check whether the nonce was reused */ if(channel->securityMode != UA_MESSAGESECURITYMODE_NONE && UA_ByteString_equal(&channel->remoteNonce, &request->clientNonce)) { UA_LOG_ERROR_CHANNEL(&server->config.logger, channel, "The client reused the last nonce"); return UA_STATUSCODE_BADSECURITYCHECKSFAILED; } /* Create a new SecurityToken. Will be switched over when the first message * is received. */ channel->altSecurityToken = channel->securityToken; channel->altSecurityToken.tokenId = server->lastTokenId++; channel->altSecurityToken.createdAt = UA_DateTime_nowMonotonic(); channel->altSecurityToken.revisedLifetime = (request->requestedLifetime > server->config.maxSecurityTokenLifetime) ? server->config.maxSecurityTokenLifetime : request->requestedLifetime; if(channel->altSecurityToken.revisedLifetime == 0) /* lifetime 0 -> return the max lifetime */ channel->altSecurityToken.revisedLifetime = server->config.maxSecurityTokenLifetime; /* Replace the nonces */ UA_ByteString_clear(&channel->remoteNonce); UA_StatusCode retval = UA_ByteString_copy(&request->clientNonce, &channel->remoteNonce); if(retval != UA_STATUSCODE_GOOD) return retval; retval = UA_SecureChannel_generateLocalNonce(channel); if(retval != UA_STATUSCODE_GOOD) return retval; /* Set the response */ response->securityToken = channel->altSecurityToken; response->securityToken.createdAt = UA_DateTime_now(); /* Only for sending */ response->responseHeader.requestHandle = request->requestHeader.requestHandle; retval = UA_ByteString_copy(&channel->localNonce, &response->serverNonce); if(retval != UA_STATUSCODE_GOOD) return retval; channel->renewState = UA_SECURECHANNELRENEWSTATE_NEWTOKEN_SERVER; return UA_STATUSCODE_GOOD; } void UA_Server_closeSecureChannel(UA_Server *server, UA_SecureChannel *channel, UA_DiagnosticEvent event) { removeSecureChannel(server, container_of(channel, channel_entry, channel), event); |
︙ | ︙ | |||
42552 42553 42554 42555 42556 42557 42558 42559 42560 42561 42562 42563 42564 42565 42566 | /* Decode the response */ UA_OpenSecureChannelResponse response; retval = UA_OpenSecureChannelResponse_decodeBinary(message, &offset, &response); if(retval != UA_STATUSCODE_GOOD) { closeSecureChannel(client); return; } /* Response.securityToken.revisedLifetime is UInt32 we need to cast it to * DateTime=Int64 we take 75% of lifetime to start renewing as described in * standard */ client->nextChannelRenewal = UA_DateTime_nowMonotonic() + (UA_DateTime) (response.securityToken.revisedLifetime * (UA_Double) UA_DATETIME_MSEC * 0.75); | > > > > > > > > > > > < < < < < > > > > | > > > | < < | 42562 42563 42564 42565 42566 42567 42568 42569 42570 42571 42572 42573 42574 42575 42576 42577 42578 42579 42580 42581 42582 42583 42584 42585 42586 42587 42588 42589 42590 42591 42592 42593 42594 42595 42596 42597 42598 42599 42600 42601 42602 42603 42604 42605 42606 42607 42608 42609 42610 42611 42612 42613 42614 42615 42616 42617 42618 42619 42620 42621 42622 42623 42624 42625 42626 42627 42628 | /* Decode the response */ UA_OpenSecureChannelResponse response; retval = UA_OpenSecureChannelResponse_decodeBinary(message, &offset, &response); if(retval != UA_STATUSCODE_GOOD) { closeSecureChannel(client); return; } /* Check whether the nonce was reused */ if(client->channel.securityMode != UA_MESSAGESECURITYMODE_NONE && UA_ByteString_equal(&client->channel.remoteNonce, &response.serverNonce)) { UA_LOG_ERROR_CHANNEL(&client->config.logger, &client->channel, "The server reused the last nonce"); client->connectStatus = UA_STATUSCODE_BADSECURITYCHECKSFAILED; closeSecureChannel(client); return; } /* Response.securityToken.revisedLifetime is UInt32 we need to cast it to * DateTime=Int64 we take 75% of lifetime to start renewing as described in * standard */ client->nextChannelRenewal = UA_DateTime_nowMonotonic() + (UA_DateTime) (response.securityToken.revisedLifetime * (UA_Double) UA_DATETIME_MSEC * 0.75); /* Move the nonce out of the response */ UA_ByteString_clear(&client->channel.remoteNonce); client->channel.remoteNonce = response.serverNonce; UA_ByteString_init(&response.serverNonce); UA_ResponseHeader_clear(&response.responseHeader); /* Replace the token. Keep the current token as the old token. Messages * might still arrive for the old token. */ client->channel.altSecurityToken = client->channel.securityToken; client->channel.securityToken = response.securityToken; client->channel.renewState = UA_SECURECHANNELRENEWSTATE_NEWTOKEN_CLIENT; /* Compute the new local keys. The remote keys are updated when a message * with the new SecurityToken is received. */ retval = UA_SecureChannel_generateLocalKeys(&client->channel); if(retval != UA_STATUSCODE_GOOD) { closeSecureChannel(client); return; } UA_Boolean renew = (client->channel.state == UA_SECURECHANNELSTATE_OPEN); if(renew) UA_LOG_INFO_CHANNEL(&client->config.logger, &client->channel, "SecureChannel renewed"); else UA_LOG_INFO_CHANNEL(&client->config.logger, &client->channel, "Opened SecureChannel with SecurityPolicy %.*s", (int)client->channel.securityPolicy->policyUri.length, client->channel.securityPolicy->policyUri.data); client->channel.state = UA_SECURECHANNELSTATE_OPEN; } void processOPNResponse(UA_Client *client, UA_ByteString *chunk) { UA_SecureChannel *channel = &client->channel; if(channel->state != UA_SECURECHANNELSTATE_OPN_SENT && channel->state != UA_SECURECHANNELSTATE_OPEN) { UA_LOG_ERROR_CHANNEL(&client->config.logger, channel, "Received an unexpected OPN response"); channel->state = UA_SECURECHANNELSTATE_CLOSING; return; |
︙ | ︙ | |||
42715 42716 42717 42718 42719 42720 42721 | UA_LOG_ERROR(&client->config.logger, UA_LOGCATEGORY_SECURECHANNEL, "Sending OPN message failed with error %s", UA_StatusCode_name(retval)); closeSecureChannel(client); return retval; } | | | | 42736 42737 42738 42739 42740 42741 42742 42743 42744 42745 42746 42747 42748 42749 42750 42751 42752 42753 42754 42755 42756 42757 42758 42759 42760 42761 | UA_LOG_ERROR(&client->config.logger, UA_LOGCATEGORY_SECURECHANNEL, "Sending OPN message failed with error %s", UA_StatusCode_name(retval)); closeSecureChannel(client); return retval; } client->channel.renewState = UA_SECURECHANNELRENEWSTATE_SENT; if(client->channel.state < UA_SECURECHANNELSTATE_OPN_SENT) client->channel.state = UA_SECURECHANNELSTATE_OPN_SENT; UA_LOG_DEBUG(&client->config.logger, UA_LOGCATEGORY_SECURECHANNEL, "OPN message sent"); return UA_STATUSCODE_GOOD; } void renewSecureChannel(UA_Client *client) { /* Check if OPN has been sent or the SecureChannel is still valid */ if(client->channel.state != UA_SECURECHANNELSTATE_OPEN || client->channel.renewState != UA_SECURECHANNELRENEWSTATE_NORMAL || client->nextChannelRenewal > UA_DateTime_nowMonotonic()) return; sendOPNAsync(client, true); } static void responseActivateSession(UA_Client *client, void *userdata, UA_UInt32 requestId, |
︙ | ︙ | |||
43157 43158 43159 43160 43161 43162 43163 | } client->connectStatus = UA_SecureChannel_setSecurityPolicy(&client->channel, sp, &client->config.endpoint.serverCertificate); if(client->connectStatus != UA_STATUSCODE_GOOD) return client->connectStatus; | < < < < < < < < < < | 43178 43179 43180 43181 43182 43183 43184 43185 43186 43187 43188 43189 43190 43191 | } client->connectStatus = UA_SecureChannel_setSecurityPolicy(&client->channel, sp, &client->config.endpoint.serverCertificate); if(client->connectStatus != UA_STATUSCODE_GOOD) return client->connectStatus; } /* Open the SecureChannel */ switch(client->channel.state) { case UA_SECURECHANNELSTATE_CLOSED: client->connectStatus = sendHELMessage(client); if(client->connectStatus == UA_STATUSCODE_GOOD) { |
︙ | ︙ | |||
43251 43252 43253 43254 43255 43256 43257 43258 43259 43260 43261 43262 43263 | static UA_StatusCode initConnect(UA_Client *client, const char *endpointUrl) { if(client->connection.state > UA_CONNECTIONSTATE_CLOSED) { UA_LOG_WARNING(&client->config.logger, UA_LOGCATEGORY_CLIENT, "Client already connected"); return UA_STATUSCODE_GOOD; } /* Consistency check the client's own ApplicationURI */ verifyClientApplicationURI(client); /* Reset the connect status */ client->connectStatus = UA_STATUSCODE_GOOD; | > > > > > > | | 43262 43263 43264 43265 43266 43267 43268 43269 43270 43271 43272 43273 43274 43275 43276 43277 43278 43279 43280 43281 43282 43283 43284 43285 43286 43287 43288 | static UA_StatusCode initConnect(UA_Client *client, const char *endpointUrl) { if(client->connection.state > UA_CONNECTIONSTATE_CLOSED) { UA_LOG_WARNING(&client->config.logger, UA_LOGCATEGORY_CLIENT, "Client already connected"); return UA_STATUSCODE_GOOD; } if(client->config.initConnectionFunc == NULL) { UA_LOG_ERROR(&client->config.logger, UA_LOGCATEGORY_CLIENT, "Client connection not configured"); return UA_STATUSCODE_BADINTERNALERROR; } /* Consistency check the client's own ApplicationURI */ verifyClientApplicationURI(client); /* Reset the connect status */ client->connectStatus = UA_STATUSCODE_GOOD; client->channel.renewState = UA_SECURECHANNELRENEWSTATE_NORMAL; client->endpointsHandshake = false; /* Initialize the SecureChannel */ UA_SecureChannel_init(&client->channel, &client->config.localConnectionConfig); /* Set the endpoint URL the client connects to */ UA_String_clear(&client->endpointUrl); |
︙ | ︙ | |||
43353 43354 43355 43356 43357 43358 43359 | request.requestHeader.authenticationToken = client->authenticationToken; UA_SecureChannel_sendSymmetricMessage(&client->channel, ++client->requestId, UA_MESSAGETYPE_CLO, &request, &UA_TYPES[UA_TYPES_CLOSESECURECHANNELREQUEST]); } /* Clean up */ | | | 43370 43371 43372 43373 43374 43375 43376 43377 43378 43379 43380 43381 43382 43383 43384 | request.requestHeader.authenticationToken = client->authenticationToken; UA_SecureChannel_sendSymmetricMessage(&client->channel, ++client->requestId, UA_MESSAGETYPE_CLO, &request, &UA_TYPES[UA_TYPES_CLOSESECURECHANNELREQUEST]); } /* Clean up */ client->channel.renewState = UA_SECURECHANNELRENEWSTATE_NORMAL; UA_SecureChannel_close(&client->channel); if(client->connection.free) client->connection.free(&client->connection); /* Set the Session to "Created" if it was "Activated" */ if(client->sessionState > UA_SESSIONSTATE_CREATED) client->sessionState = UA_SESSIONSTATE_CREATED; |
︙ | ︙ | |||
44567 44568 44569 44570 44571 44572 44573 | } #endif UA_StatusCode __UA_Client_translateBrowsePathsToNodeIds_async(UA_Client *client, char *paths[], UA_UInt32 ids[], size_t pathSize, UA_ClientAsyncServiceCallback callback, void *userdata, UA_UInt32 *reqId) { | < < < < < < < | < | < < < < | > > | < | | < < < < < < < | 44584 44585 44586 44587 44588 44589 44590 44591 44592 44593 44594 44595 44596 44597 44598 44599 44600 44601 44602 44603 44604 44605 44606 | } #endif UA_StatusCode __UA_Client_translateBrowsePathsToNodeIds_async(UA_Client *client, char *paths[], UA_UInt32 ids[], size_t pathSize, UA_ClientAsyncServiceCallback callback, void *userdata, UA_UInt32 *reqId) { return UA_STATUSCODE_BADNOTIMPLEMENTED; } UA_StatusCode UA_Cient_translateBrowsePathsToNodeIds_async(UA_Client *client, char **paths, UA_UInt32 *ids, size_t pathSize, UA_ClientAsyncTranslateCallback callback, void *userdata, UA_UInt32 *reqId) { return UA_STATUSCODE_BADNOTIMPLEMENTED; } /*********************************** amalgamated original file "/home/travis/build/open62541/open62541/src/client/ua_client_subscriptions.c" ***********************************/ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. |
︙ | ︙ | |||
59478 59479 59480 59481 59482 59483 59484 | return nl; } typedef struct TCPClientConnection { struct addrinfo hints, *server; UA_DateTime connStart; | | | 59477 59478 59479 59480 59481 59482 59483 59484 59485 59486 59487 59488 59489 59490 59491 | return nl; } typedef struct TCPClientConnection { struct addrinfo hints, *server; UA_DateTime connStart; UA_String endpointUrl; UA_UInt32 timeout; } TCPClientConnection; /***************************/ /* Client NetworkLayer TCP */ /***************************/ |
︙ | ︙ | |||
59506 59507 59508 59509 59510 59511 59512 59513 59514 59515 59516 59517 59518 59519 | ClientNetworkLayerTCP_free(UA_Connection *connection) { if(!connection->handle) return; TCPClientConnection *tcpConnection = (TCPClientConnection *)connection->handle; if(tcpConnection->server) UA_freeaddrinfo(tcpConnection->server); UA_free(tcpConnection); connection->handle = NULL; } UA_StatusCode UA_ClientConnectionTCP_poll(UA_Client *client, void *data, UA_UInt32 timeout) { UA_Connection *connection = (UA_Connection*) data; | > | 59505 59506 59507 59508 59509 59510 59511 59512 59513 59514 59515 59516 59517 59518 59519 | ClientNetworkLayerTCP_free(UA_Connection *connection) { if(!connection->handle) return; TCPClientConnection *tcpConnection = (TCPClientConnection *)connection->handle; if(tcpConnection->server) UA_freeaddrinfo(tcpConnection->server); UA_String_clear(&tcpConnection->endpointUrl); UA_free(tcpConnection); connection->handle = NULL; } UA_StatusCode UA_ClientConnectionTCP_poll(UA_Client *client, void *data, UA_UInt32 timeout) { UA_Connection *connection = (UA_Connection*) data; |
︙ | ︙ | |||
59564 59565 59566 59567 59568 59569 59570 | /* Non blocking connect */ int error = UA_connect(clientsockfd, tcpConnection->server->ai_addr, tcpConnection->server->ai_addrlen); if((error == -1) && (UA_ERRNO != UA_ERR_CONNECTION_PROGRESS)) { ClientNetworkLayerTCP_close(connection); UA_LOG_WARNING(&config->logger, UA_LOGCATEGORY_NETWORK, | | > > | 59564 59565 59566 59567 59568 59569 59570 59571 59572 59573 59574 59575 59576 59577 59578 59579 59580 | /* Non blocking connect */ int error = UA_connect(clientsockfd, tcpConnection->server->ai_addr, tcpConnection->server->ai_addrlen); if((error == -1) && (UA_ERRNO != UA_ERR_CONNECTION_PROGRESS)) { ClientNetworkLayerTCP_close(connection); UA_LOG_WARNING(&config->logger, UA_LOGCATEGORY_NETWORK, "Connection to %.*s failed with error: %s", (int)tcpConnection->endpointUrl.length, tcpConnection->endpointUrl.data, strerror(UA_ERRNO)); return UA_STATUSCODE_BADDISCONNECT; } /* Use select to wait and check if connected */ if(error == -1 && (UA_ERRNO == UA_ERR_CONNECTION_PROGRESS)) { /* connection in progress. Wait until connected using select */ UA_UInt32 timeout_usec = timeout * 1000; |
︙ | ︙ | |||
59621 59622 59623 59624 59625 59626 59627 | connection->state = UA_CONNECTIONSTATE_ESTABLISHED; return UA_STATUSCODE_GOOD; } else { if(so_error != ECONNREFUSED) { /* General error */ ClientNetworkLayerTCP_close(connection); UA_LOG_WARNING(&config->logger, UA_LOGCATEGORY_NETWORK, | | > > | 59623 59624 59625 59626 59627 59628 59629 59630 59631 59632 59633 59634 59635 59636 59637 59638 59639 | connection->state = UA_CONNECTIONSTATE_ESTABLISHED; return UA_STATUSCODE_GOOD; } else { if(so_error != ECONNREFUSED) { /* General error */ ClientNetworkLayerTCP_close(connection); UA_LOG_WARNING(&config->logger, UA_LOGCATEGORY_NETWORK, "Connection to %.*s failed with error: %s", (int)tcpConnection->endpointUrl.length, tcpConnection->endpointUrl.data, strerror(ret == 0 ? so_error : UA_ERRNO)); return UA_STATUSCODE_BADDISCONNECT; } /* On connection refused we should still try to connect. * Connection refused happens on localhost or local ip without * timeout. Wait until we try a again. Do not make this too |
︙ | ︙ | |||
59667 59668 59669 59670 59671 59672 59673 | connection.recv = connection_recv; connection.close = ClientNetworkLayerTCP_close; connection.free = ClientNetworkLayerTCP_free; connection.getSendBuffer = connection_getsendbuffer; connection.releaseSendBuffer = connection_releasesendbuffer; connection.releaseRecvBuffer = connection_releaserecvbuffer; | | | > | | | 59671 59672 59673 59674 59675 59676 59677 59678 59679 59680 59681 59682 59683 59684 59685 59686 59687 59688 59689 59690 59691 59692 59693 59694 59695 59696 59697 59698 | connection.recv = connection_recv; connection.close = ClientNetworkLayerTCP_close; connection.free = ClientNetworkLayerTCP_free; connection.getSendBuffer = connection_getsendbuffer; connection.releaseSendBuffer = connection_releasesendbuffer; connection.releaseRecvBuffer = connection_releaserecvbuffer; TCPClientConnection *tcpClientConnection = (TCPClientConnection*) UA_malloc(sizeof(TCPClientConnection)); memset(tcpClientConnection, 0, sizeof(TCPClientConnection)); connection.handle = (void*) tcpClientConnection; tcpClientConnection->timeout = timeout; UA_String hostnameString = UA_STRING_NULL; UA_String pathString = UA_STRING_NULL; UA_UInt16 port = 0; char hostname[512]; tcpClientConnection->connStart = UA_DateTime_nowMonotonic(); UA_String_copy(&endpointUrl, &tcpClientConnection->endpointUrl); UA_StatusCode parse_retval = UA_parseEndpointUrl(&endpointUrl, &hostnameString, &port, &pathString); if(parse_retval != UA_STATUSCODE_GOOD || hostnameString.length > 511) { UA_LOG_WARNING(logger, UA_LOGCATEGORY_NETWORK, "Server url is invalid: %.*s", (int)endpointUrl.length, endpointUrl.data); connection.state = UA_CONNECTIONSTATE_CLOSED; return connection; } |
︙ | ︙ |
Changes to jni/topcua/open62541/open62541.h.
1 2 | /* THIS IS A SINGLE-FILE DISTRIBUTION CONCATENATED FROM THE OPEN62541 SOURCES * visit http://open62541.org/ for information about this software | | | 1 2 3 4 5 6 7 8 9 10 | /* THIS IS A SINGLE-FILE DISTRIBUTION CONCATENATED FROM THE OPEN62541 SOURCES * visit http://open62541.org/ for information about this software * Git-Revision: v1.1.1 */ /* * Copyright (C) 2014-2018 the contributors as stated in the AUTHORS file * * This file is part of open62541. open62541 is free software: you can * redistribute it and/or modify it under the terms of the Mozilla Public |
︙ | ︙ | |||
26 27 28 29 30 31 32 | /** * open62541 Version * ----------------- */ #define UA_OPEN62541_VER_MAJOR 1 #define UA_OPEN62541_VER_MINOR 1 | | | | | 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | /** * open62541 Version * ----------------- */ #define UA_OPEN62541_VER_MAJOR 1 #define UA_OPEN62541_VER_MINOR 1 #define UA_OPEN62541_VER_PATCH 1 #define UA_OPEN62541_VER_LABEL "" /* Release candidate label, etc. */ #define UA_OPEN62541_VER_COMMIT "v1.1.1" /** * Feature Options * --------------- * Changing the feature options has no effect on a pre-compiled library. */ #define UA_LOGLEVEL 300 |
︙ | ︙ | |||
14096 14097 14098 14099 14100 14101 14102 | _UA_END_DECLS /*********************************** amalgamated original file "/home/travis/build/open62541/open62541/build/src_generated/open62541/types_generated.h" ***********************************/ /* Generated from Opc.Ua.Types.bsd with script /home/travis/build/open62541/open62541/tools/generate_datatypes.py | | | 14096 14097 14098 14099 14100 14101 14102 14103 14104 14105 14106 14107 14108 14109 14110 | _UA_END_DECLS /*********************************** amalgamated original file "/home/travis/build/open62541/open62541/build/src_generated/open62541/types_generated.h" ***********************************/ /* Generated from Opc.Ua.Types.bsd with script /home/travis/build/open62541/open62541/tools/generate_datatypes.py * on host travis-job-5b5ec811-e61d-442b-8cf7-c7ae1921c1d9 by user travis at 2020-06-24 10:59:21 */ #ifdef UA_ENABLE_AMALGAMATION #else #endif |
︙ | ︙ | |||
16775 16776 16777 16778 16779 16780 16781 | _UA_END_DECLS /*********************************** amalgamated original file "/home/travis/build/open62541/open62541/build/src_generated/open62541/types_generated_handling.h" ***********************************/ /* Generated from Opc.Ua.Types.bsd with script /home/travis/build/open62541/open62541/tools/generate_datatypes.py | | | 16775 16776 16777 16778 16779 16780 16781 16782 16783 16784 16785 16786 16787 16788 16789 | _UA_END_DECLS /*********************************** amalgamated original file "/home/travis/build/open62541/open62541/build/src_generated/open62541/types_generated_handling.h" ***********************************/ /* Generated from Opc.Ua.Types.bsd with script /home/travis/build/open62541/open62541/tools/generate_datatypes.py * on host travis-job-5b5ec811-e61d-442b-8cf7-c7ae1921c1d9 by user travis at 2020-06-24 10:59:21 */ _UA_BEGIN_DECLS #if defined(__GNUC__) && __GNUC__ >= 4 && __GNUC_MINOR__ >= 6 # pragma GCC diagnostic push |
︙ | ︙ | |||
30189 30190 30191 30192 30193 30194 30195 | (UA_ClientAsyncServiceCallback)callback, userdata, reqId); } /** * Misc Functionalities * ^^^^^^^^^^^^^^^^^^^^ */ | | | | < < < < | 30189 30190 30191 30192 30193 30194 30195 30196 30197 30198 30199 30200 30201 30202 30203 30204 30205 30206 30207 30208 30209 30210 30211 30212 30213 30214 30215 30216 30217 | (UA_ClientAsyncServiceCallback)callback, userdata, reqId); } /** * Misc Functionalities * ^^^^^^^^^^^^^^^^^^^^ */ UA_DEPRECATED UA_StatusCode UA_EXPORT __UA_Client_translateBrowsePathsToNodeIds_async(UA_Client *client, char *paths[], UA_UInt32 ids[], size_t pathSize, UA_ClientAsyncServiceCallback callback, void *userdata, UA_UInt32 *reqId); typedef void (*UA_ClientAsyncTranslateCallback)( UA_Client *client, void *userdata, UA_UInt32 requestId, UA_TranslateBrowsePathsToNodeIdsResponse *tr); UA_DEPRECATED UA_StatusCode UA_EXPORT UA_Cient_translateBrowsePathsToNodeIds_async(UA_Client *client, char **paths, UA_UInt32 *ids, size_t pathSize, UA_ClientAsyncTranslateCallback callback, void *userdata, UA_UInt32 *reqId); _UA_END_DECLS /*********************************** amalgamated original file "/home/travis/build/open62541/open62541/plugins/include/open62541/plugin/accesscontrol_default.h" ***********************************/ /* This work is licensed under a Creative Commons CCZero 1.0 Universal License. |
︙ | ︙ |
Changes to jni/topcua/open62541/open62541.pdf.
cannot compute difference between binary files