Check-in [5c2593aec3]
Not logged in

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: 5c2593aec3f08f3ce9e77a4cac68325bde1e7aa2
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
Unified Diff Ignore Whitespace Patch
Changes to jni/topcua/library/topcua.tcl.
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
	append bsd "</opc:TypeDictionary>\n"
	# store *.bsd type defs into node
	write $handle $tt ByteString $bsd
    }

    # Make some procs visible in opcua ensemble.

    proc _init {} {
	set cmds [::namespace ensemble configure ::opcua -subcommands]
	lappend cmds tree ptree children parent genstubs gentypes deftypes
	::namespace ensemble configure ::opcua -subcommands $cmds
    }

    _init
    rename _init {}

}







|
|

|
<
|
<
<


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
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-13 00:47:16.000000000 +0200
+++ open62541.c	2020-06-15 19:11:09.002897842 +0200
@@ -23263,7 +23263,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.
@@ -43921,7 +43921,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. */
@@ -44023,13 +44023,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;
     }
@@ -58823,7 +58826,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);
@@ -59927,3 +59930,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-13 00:47:16.000000000 +0200
+++ open62541.h	2020-06-15 14:50:39.464840135 +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
@@ -31410,6 +31410,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
 





|
|
|








|








|

















|








|

















|
|


















|











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
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-rc1-51-gea228200
 */

/*
 * 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


|







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
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-a7d97b31-af9e-45b1-a415-33385e803877 by user travis at 2020-06-12 10:28:00 */


#ifdef UA_ENABLE_AMALGAMATION
#else
#endif









|







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
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-a7d97b31-af9e-45b1-a415-33385e803877 by user travis at 2020-06-12 10:28:00 */


#ifdef UA_ENABLE_AMALGAMATION
#else

#endif








|







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
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-a7d97b31-af9e-45b1-a415-33385e803877 by user travis at 2020-06-12 10:28:00 */



_UA_BEGIN_DECLS

#if defined(__GNUC__) && __GNUC__ >= 4 && __GNUC_MINOR__ >= 6
# pragma GCC diagnostic push







|







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
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-a7d97b31-af9e-45b1-a415-33385e803877 by user travis at 2020-06-12 10:28:00 */


#ifdef UA_ENABLE_AMALGAMATION
#else
#endif









|







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
4529

4530
4531
4532
4533
4534
4535
4536
4537
4538
4539
4540
4541
4542
4543
4544
4545
4546
4547
4548
4549
4550
    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 {
    UA_SecureChannelState   state;

    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 nextSecurityToken; /* Only used by the server. The next token
                                                * is put here when sending the OPN
                                                * response. */

    /* 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 */







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

|
>
|
|








|
|
<
|







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
4599
4600
4601
4602
4603
4604
4605
4606
4607
4608
4609
4610
4611
4612
4613
4614
4615
4616
4617
                                   const UA_SecurityPolicy *securityPolicy,
                                   const UA_ByteString *remoteCertificate);

/* Remove (partially) received unprocessed chunks */
void
UA_SecureChannel_deleteBuffered(UA_SecureChannel *channel);

/* Generates new keys and sets them in the channel context */
UA_StatusCode
UA_SecureChannel_generateNewKeys(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_revolveTokens(UA_SecureChannel *channel);

/**
 * Sending Messages
 * ---------------- */

UA_StatusCode
UA_SecureChannel_sendAsymmetricOPNMessage(UA_SecureChannel *channel, UA_UInt32 requestId,







<
<
<
<







|







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
7409
7410
7411
7412
7413
7414
7415
7416
    UA_StatusCode connectStatus;

    /* Old status to notify only changes */
    UA_SecureChannelState oldChannelState;
    UA_SessionState oldSessionState;
    UA_StatusCode oldConnectStatus;

    UA_Boolean secureChannelHandshake; /* Ongoing RenewSecureChannel */
    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 */








<







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
10911
10912
10913
10914
10915
10916
10917
10918
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-a7d97b31-af9e-45b1-a415-33385e803877 by user travis at 2020-06-12 10:28:00 */


/* Boolean */
#define Boolean_members NULL

/* SByte */
#define SByte_members NULL







|







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
18864
18865
18866
18867
18868
18869
18870
18871
},
};


/*********************************** 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-a7d97b31-af9e-45b1-a415-33385e803877 by user travis at 2020-06-12 10:28:00 */


/* TcpHelloMessage */
static UA_DataTypeMember TcpHelloMessage_members[6] = {
{
    UA_TYPENAME("ProtocolVersion") /* .memberName */
    UA_TYPES_UINT32, /* .memberTypeIndex */







|







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
20380
20381
20382
20383
20384
20385
20386
20387
20388
20389
20390
20391
    if(channel->securityPolicy) {
        channel->securityPolicy->channelModule.deleteContext(channel->channelContext);
        channel->securityPolicy = NULL;
        channel->channelContext = NULL;
    }

    /* Delete members */
    UA_ByteString_deleteMembers(&channel->remoteCertificate);
    UA_ByteString_deleteMembers(&channel->localNonce);
    UA_ByteString_deleteMembers(&channel->remoteNonce);
    UA_ChannelSecurityToken_deleteMembers(&channel->securityToken);
    UA_ChannelSecurityToken_deleteMembers(&channel->nextSecurityToken);
    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 */







|
|
|
|
|







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
20532
20533
20534
20535
20536
20537
20538
20539
20540
20541
20542
20543
20544
20545
20546
20547
20548
20549
20550
20551
20552
20553
20554
20555
    header.messageTypeAndChunkType = messageContext->messageType;
    header.messageSize = (UA_UInt32)totalLength;
    if(messageContext->final)
        header.messageTypeAndChunkType += UA_CHUNKTYPE_FINAL;
    else
        header.messageTypeAndChunkType += UA_CHUNKTYPE_INTERMEDIATE;

    UA_UInt32 tokenId = channel->securityToken.tokenId;
    /* This is a server SecureChannel and we have sent out the OPN response but
     * not gotten a request with the new token. So send with nextSecurityToken
     * and still allow to receive with the old one. */
    if(channel->nextSecurityToken.tokenId != 0)
        tokenId = channel->nextSecurityToken.tokenId;

    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(&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







<
<
<
<
<
<
<









|







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
21214
21215
21216



21217

21218
21219
21220
21221
21222
21223
21224
        if(retval != UA_STATUSCODE_GOOD)
            return retval;
    }

    return sp->symmetricModule.generateNonce(sp, &channel->localNonce);
}

static UA_StatusCode
generateLocalKeys(const UA_SecureChannel *channel,
                  const UA_SecurityPolicy *sp) {



    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;







|
|
|
>
>
>

>







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
21251
21252



21253

21254
21255
21256
21257
21258
21259
21260
    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) {



    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;







|
|
>
>
>

>







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
21286
21287
21288
21289
21290
21291
21292
21293
21294
21295
21296
21297
21298
21299
21300
21301
21302
21303
21304
21305
21306
21307
21308
21309
21310
21311
21312
21313
21314
21315
21316
21317
21318
21319
21320
21321
21322
21323
21324
21325
21326
21327
21328
21329
21330
21331
21332
21333
    retval |= cm->setRemoteSymSigningKey(cc, &remoteSigningKey);
    retval |= cm->setRemoteSymEncryptingKey(cc, &remoteEncryptingKey);
    retval |= cm->setRemoteSymIv(cc, &remoteIv);
    UA_ByteString_clear(&buf);
    return retval;
}

UA_StatusCode
UA_SecureChannel_generateNewKeys(UA_SecureChannel *channel) {
    const UA_SecurityPolicy *sp = channel->securityPolicy;
    if(!sp)
        return UA_STATUSCODE_BADINTERNALERROR;
    UA_LOG_DEBUG_CHANNEL(sp->logger, channel, "Generating SecureChannel keys");

    UA_StatusCode retval = generateLocalKeys(channel, sp);
    if(retval != UA_STATUSCODE_GOOD) {
        UA_LOG_ERROR(sp->logger, UA_LOGCATEGORY_SECURECHANNEL,
                     "Could not generate a local key");
        return retval;
    }

    retval = generateRemoteKeys(channel, sp);
    if(retval != UA_STATUSCODE_GOOD) {
        UA_LOG_ERROR(sp->logger, UA_LOGCATEGORY_SECURECHANNEL,
                     "Could not generate a remote key");
        return retval;
    }

    return retval;
}

UA_StatusCode
UA_SecureChannel_revolveTokens(UA_SecureChannel *channel) {
    const UA_SecurityPolicy *sp = channel->securityPolicy;
    if(!sp)
        return UA_STATUSCODE_BADINTERNALERROR;

    if(channel->nextSecurityToken.tokenId == 0) /* no next security token issued */
        return UA_STATUSCODE_BADSECURECHANNELTOKENUNKNOWN;

    UA_ChannelSecurityToken_clear(&channel->securityToken);
    channel->securityToken = channel->nextSecurityToken;
    UA_ChannelSecurityToken_init(&channel->nextSecurityToken);

    /* remote keys are generated later on */
    return generateLocalKeys(channel, sp);
}

/***************************/
/* Send Asymmetric Message */
/***************************/

size_t
calculateAsymAlgSecurityHeaderLength(const UA_SecureChannel *channel) {
    const UA_SecurityPolicy *sp = channel->securityPolicy;







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







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









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
    /* 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 the message uses a different token, check if it is the next token. */


    if(tokenId != channel->securityToken.tokenId) {



















        if(tokenId != channel->nextSecurityToken.tokenId) {






            UA_LOG_WARNING_CHANNEL(channel->securityPolicy->logger, channel,
                                 "Received an unknown SecurityToken");
            return UA_STATUSCODE_BADSECURECHANNELTOKENUNKNOWN;
        }

        UA_LOG_DEBUG_CHANNEL(channel->securityPolicy->logger, channel,
                             "Revolving to the next SecurityToken");

        /* If the token is indeed the next token, revolve the tokens */
        UA_StatusCode retval = UA_SecureChannel_revolveTokens(channel);
        if(retval != UA_STATUSCODE_GOOD) {
            UA_LOG_WARNING_CHANNEL(channel->securityPolicy->logger, channel,
                                   "Revolving to the next SecurityToken failed");
            return retval;
        }

        /* If the message now uses the currently active token also generate
         * new remote keys to correctly decrypt. */
        retval = generateRemoteKeys(channel, channel->securityPolicy);
        if(retval != UA_STATUSCODE_GOOD) {
            UA_LOG_WARNING_CHANNEL(channel->securityPolicy->logger, channel,
                                   "Could not generate new remote keys");
            return retval;
        }
    }

    UA_DateTime timeout = channel->securityToken.createdAt +
        (channel->securityToken.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;
    }







>
>
>
>
>
>
>
>
>
|
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>

|



|
<
|
|
<
<
|
|
|
|

<
<
<
|
<
<
|
|
<
<
<
|







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
22792
22793
22794

22795
22796

22797
22798
22799
22800


22801
22802
22803

22804
22805
22806
22807
22808
22809
22810
#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);








<
|
|
>

|
>
|

|
<
>
>
|
|
|
>







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
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
    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
UA_Server_getNamespaceByName(UA_Server *server, const UA_String namespaceUri,
                             size_t* foundIndex) {
    UA_LOCK(server->serviceMutex);

    /* ensure that the uri for ns1 is set up from the app description */
    setupNs1Uri(server);

    for(size_t idx = 0; idx < server->namespacesSize; idx++) {
        if(!UA_String_equal(&server->namespaces[idx], &namespaceUri))
            continue;
        (*foundIndex) = idx;
        UA_UNLOCK(server->serviceMutex);
        return UA_STATUSCODE_GOOD;

    }









    UA_UNLOCK(server->serviceMutex);
    return UA_STATUSCODE_BADNOTFOUND;
}

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);







|
<

|
<




|
|
<
<


|

|
<
|
<
|
>
|
>
>
>
>
>
>
>
>
>

|







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
33699
33700
33701
33702
33703
33704
33705
33706
33707
         * 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 = UA_Server_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 */







|
<







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
38476
38477
38478
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
    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_now();

    /* 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;

    /* Set the nonces and generate the keys */
    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;

    retval = UA_SecureChannel_generateNewKeys(channel);
    if(retval != UA_STATUSCODE_GOOD)
        return retval;

    /* Set the response */

    retval = UA_ByteString_copy(&channel->localNonce, &response->serverNonce);
    if(retval != UA_STATUSCODE_GOOD)
        return retval;

    retval = UA_ChannelSecurityToken_copy(&channel->securityToken, &response->securityToken);
    if(retval != UA_STATUSCODE_GOOD)
        return retval;

    response->responseHeader.timestamp = UA_DateTime_now();
    response->responseHeader.requestHandle = request->requestHeader.requestHandle;

    /* The channel is open */
    channel->state = UA_SECURECHANNELSTATE_OPEN;

    /* Reset the internal creation date to the monotonic clock */


    channel->securityToken.createdAt = UA_DateTime_nowMonotonic();

    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;
    }








    /* If no security token is already issued */
    if(channel->nextSecurityToken.tokenId == 0) {

        channel->nextSecurityToken.channelId = channel->securityToken.channelId;
        channel->nextSecurityToken.tokenId = server->lastTokenId++;
        channel->nextSecurityToken.createdAt = UA_DateTime_now();
        channel->nextSecurityToken.revisedLifetime =
            (request->requestedLifetime > server->config.maxSecurityTokenLifetime) ?
            server->config.maxSecurityTokenLifetime : request->requestedLifetime;
        if(channel->nextSecurityToken.revisedLifetime == 0) /* lifetime 0 -> return the max lifetime */
            channel->nextSecurityToken.revisedLifetime = server->config.maxSecurityTokenLifetime;
    }

    /* Replace the nonces */
    UA_ByteString_deleteMembers(&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->responseHeader.requestHandle = request->requestHeader.requestHandle;
    retval = UA_ByteString_copy(&channel->localNonce, &response->serverNonce);
    if(retval != UA_STATUSCODE_GOOD)
        return retval;

    retval = UA_ChannelSecurityToken_copy(&channel->nextSecurityToken, &response->securityToken);
    if(retval != UA_STATUSCODE_GOOD)
        return retval;

    /* Reset the internal creation date to the monotonic clock */
    channel->nextSecurityToken.createdAt = UA_DateTime_nowMonotonic();
    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);







|








<




>
>




|
|
|
|
|
>




<
<
<
<
<
<
<



|
>
>
|
<













>
>
>
>
>
>
>
|
|
>
|
|
|
|
|
|
|
|
|
<

|









>
>





<
<
<
|
<
<







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
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
    /* 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);

    /* Replace the token. On the client side we don't use NextSecurityToken. */
    UA_ChannelSecurityToken_clear(&client->channel.securityToken);
    client->channel.securityToken = response.securityToken;
    UA_ChannelSecurityToken_init(&response.securityToken);

    /* 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); /* the other members were moved */




    retval = UA_SecureChannel_generateNewKeys(&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) {
    client->secureChannelHandshake = false;

    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;







>
>
>
>
>
>
>
>
>
>
>








<
<
<
<
<




>

>
>
>
|
>

>
>
|



















<
<







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
42722
42723
42724
42725
42726
42727
42728
42729
42730
42731
42732
42733
42734
42735
42736
42737
42738
42739
42740
        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->secureChannelHandshake = true;
    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->secureChannelHandshake ||
       client->nextChannelRenewal > UA_DateTime_nowMonotonic())
        return;
    sendOPNAsync(client, true);
}

static void
responseActivateSession(UA_Client *client, void *userdata, UA_UInt32 requestId,







|










|







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
43164
43165
43166
43167
43168
43169
43170
43171
43172
43173
43174
43175
43176
43177
43178
43179
43180
        }

        client->connectStatus =
            UA_SecureChannel_setSecurityPolicy(&client->channel, sp,
                                               &client->config.endpoint.serverCertificate);
        if(client->connectStatus != UA_STATUSCODE_GOOD)
            return client->connectStatus;

        client->connectStatus = UA_SecureChannel_generateLocalNonce(&client->channel);
        if(client->connectStatus != UA_STATUSCODE_GOOD)
            return client->connectStatus;

        if (client->channel.remoteNonce.length != 0) {
            client->connectStatus = UA_SecureChannel_generateNewKeys(&client->channel);
            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) {







<
<
<
<
<
<
<
<
<
<







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
43264
43265
43266
43267
43268
43269
43270
43271
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;
    client->secureChannelHandshake = false;
    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);







>
>
>
>
>
>






|







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
43360
43361
43362
43363
43364
43365
43366
43367
        request.requestHeader.authenticationToken = client->authenticationToken;
        UA_SecureChannel_sendSymmetricMessage(&client->channel, ++client->requestId,
                                              UA_MESSAGETYPE_CLO, &request,
                                              &UA_TYPES[UA_TYPES_CLOSESECURECHANNELREQUEST]);
    }

    /* Clean up */
    client->secureChannelHandshake = false;
    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;







|







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
44574
44575
44576
44577
44578
44579
44580
44581
44582
44583
44584
44585
44586
44587
44588
44589


44590
44591
44592
44593
44594
44595
44596
44597
44598
44599
44600
44601
44602
44603
44604
44605
44606
44607
}
#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) {

    UA_BrowsePath browsePath;
    UA_BrowsePath_init(&browsePath);
    browsePath.startingNode = UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER);
    browsePath.relativePath.elements = (UA_RelativePathElement*) UA_Array_new(
            pathSize, &UA_TYPES[UA_TYPES_RELATIVEPATHELEMENT]);
    if (!browsePath.relativePath.elements)
        return UA_STATUSCODE_BADOUTOFMEMORY;
    browsePath.relativePath.elementsSize = pathSize;

    UA_TranslateBrowsePathsToNodeIdsRequest request;
    UA_TranslateBrowsePathsToNodeIdsRequest_init(&request);
    request.browsePaths = &browsePath;
    request.browsePathsSize = 1;

    UA_StatusCode retval = __UA_Client_AsyncService(client, &request,


            &UA_TYPES[UA_TYPES_TRANSLATEBROWSEPATHSTONODEIDSREQUEST], callback,
            &UA_TYPES[UA_TYPES_TRANSLATEBROWSEPATHSTONODEIDSRESPONSE], userdata,
            reqId);
    if (retval != UA_STATUSCODE_GOOD) {
        UA_Array_delete(browsePath.relativePath.elements,
                browsePath.relativePath.elementsSize,
                &UA_TYPES[UA_TYPES_RELATIVEPATHELEMENT]);
        return retval;
    }
    UA_BrowsePath_clear(&browsePath);
    return retval;
}

/*********************************** 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/. 







<
<
<
<
<
<
<
|
<
|
<
<
<
<

|
>
>
|
<
|
|
<
<
<
<
<
<
<







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
59485
59486
59487
59488
59489
59490
59491
59492

    return nl;
}

typedef struct TCPClientConnection {
    struct addrinfo hints, *server;
    UA_DateTime connStart;
    char* endpointURL;
    UA_UInt32 timeout;
} TCPClientConnection;

/***************************/
/* Client NetworkLayer TCP */
/***************************/








|







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
59571


59572
59573
59574
59575
59576
59577
59578
    /* 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  failed with error: %s", 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;







|
>
>







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
59628


59629
59630
59631
59632
59633
59634
59635
                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 failed with error: %s",


                                   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







|
>
>







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
59674
59675
59676
59677
59678
59679
59680
59681
59682
59683

59684
59685
59686
59687
59688
59689
59690
59691
59692
59693
    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_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;
    }







|
|








>

|
|







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
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-rc1-51-gea228200
 */

/*
 * 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


|







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
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 0
#define UA_OPEN62541_VER_LABEL "-rc1-51-gea228200" /* Release candidate label, etc. */
#define UA_OPEN62541_VER_COMMIT "v1.1-rc1-51-gea228200"

/**
 * Feature Options
 * ---------------
 * Changing the feature options has no effect on a pre-compiled library. */

#define UA_LOGLEVEL 300







|
|
|







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
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-a7d97b31-af9e-45b1-a415-33385e803877 by user travis at 2020-06-12 10:28:00 */


#ifdef UA_ENABLE_AMALGAMATION
#else

#endif








|







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
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-a7d97b31-af9e-45b1-a415-33385e803877 by user travis at 2020-06-12 10:28:00 */



_UA_BEGIN_DECLS

#if defined(__GNUC__) && __GNUC__ >= 4 && __GNUC_MINOR__ >= 6
# pragma GCC diagnostic push







|







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
30196
30197
30198
30199
30200
30201
30202
30203
30204
30205
30206
30207
30208
30209
30210
30211
30212
30213
30214
30215
30216
30217
30218
30219
30220
30221
        (UA_ClientAsyncServiceCallback)callback, userdata, reqId);
}

/**
 * Misc Functionalities
 * ^^^^^^^^^^^^^^^^^^^^ */

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);

static UA_INLINE 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_Client_translateBrowsePathsToNodeIds_async(
        client, paths, ids, pathSize, (UA_ClientAsyncServiceCallback)callback, userdata,
        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.







|









|



|
<
<
<
<







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