opc source code

This commit is contained in:
flower_linux
2026-06-09 17:27:24 +08:00
parent 70f675a48b
commit f0da5cb3c3
2002 changed files with 269812 additions and 7 deletions

View File

@@ -0,0 +1,598 @@
#ifndef OPEN62541_CERTIFICATES_H
#define OPEN62541_CERTIFICATES_H
#include <open62541/types.h>
_UA_BEGIN_DECLS
#define CLIENT_CERT_DER_LENGTH 1030
UA_Byte CLIENT_CERT_DER_DATA[CLIENT_CERT_DER_LENGTH] = {
0x30, 0x82, 0x04, 0x02, 0x30, 0x82, 0x02, 0xea, 0xa0, 0x03, 0x02, 0x01,
0x02, 0x02, 0x14, 0x36, 0xbb, 0x70, 0x44, 0x14, 0xdf, 0x1f, 0xad, 0xe7,
0xe7, 0xc8, 0x69, 0x52, 0x60, 0x0e, 0xcb, 0x46, 0x73, 0xcb, 0x7a, 0x30,
0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b,
0x05, 0x00, 0x30, 0x54, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04,
0x06, 0x13, 0x02, 0x44, 0x45, 0x31, 0x0d, 0x30, 0x0b, 0x06, 0x03, 0x55,
0x04, 0x07, 0x0c, 0x04, 0x48, 0x65, 0x72, 0x65, 0x31, 0x12, 0x30, 0x10,
0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x09, 0x6f, 0x70, 0x65, 0x6e, 0x36,
0x32, 0x35, 0x34, 0x31, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04,
0x03, 0x0c, 0x19, 0x6f, 0x70, 0x65, 0x6e, 0x36, 0x32, 0x35, 0x34, 0x31,
0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x40, 0x6c, 0x6f, 0x63, 0x61, 0x6c,
0x68, 0x6f, 0x73, 0x74, 0x30, 0x1e, 0x17, 0x0d, 0x32, 0x33, 0x31, 0x31,
0x30, 0x38, 0x31, 0x35, 0x31, 0x33, 0x33, 0x32, 0x5a, 0x17, 0x0d, 0x33,
0x33, 0x31, 0x31, 0x30, 0x35, 0x31, 0x35, 0x31, 0x33, 0x33, 0x32, 0x5a,
0x30, 0x54, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
0x02, 0x44, 0x45, 0x31, 0x0d, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x04, 0x07,
0x0c, 0x04, 0x48, 0x65, 0x72, 0x65, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03,
0x55, 0x04, 0x0a, 0x0c, 0x09, 0x6f, 0x70, 0x65, 0x6e, 0x36, 0x32, 0x35,
0x34, 0x31, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c,
0x19, 0x6f, 0x70, 0x65, 0x6e, 0x36, 0x32, 0x35, 0x34, 0x31, 0x53, 0x65,
0x72, 0x76, 0x65, 0x72, 0x40, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f,
0x73, 0x74, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01,
0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xcf,
0xe9, 0xd9, 0x66, 0x9a, 0x06, 0xa1, 0x6d, 0x87, 0x90, 0x44, 0xca, 0xdc,
0xff, 0x4a, 0xe4, 0x1c, 0x0a, 0x5e, 0xe9, 0x62, 0xe4, 0x08, 0x6b, 0x83,
0x23, 0xdc, 0x76, 0xe3, 0xe1, 0xbe, 0x73, 0x0a, 0xb6, 0x1a, 0x07, 0x8b,
0x80, 0x7f, 0xe2, 0x87, 0x6f, 0x8f, 0xf2, 0xe3, 0xf5, 0x64, 0x83, 0xe5,
0x6f, 0x83, 0x2b, 0xb4, 0x9d, 0xd6, 0xf2, 0x6f, 0xa2, 0x2a, 0x78, 0x6c,
0xcf, 0xba, 0x9d, 0xd1, 0xca, 0xad, 0xa2, 0xed, 0xd0, 0x52, 0x53, 0x6c,
0x09, 0x72, 0xe8, 0xcc, 0xb5, 0xb6, 0x99, 0xea, 0xf9, 0x04, 0x04, 0xee,
0x42, 0x12, 0x18, 0x8a, 0x20, 0xbb, 0x05, 0xce, 0xe1, 0x32, 0x54, 0x5a,
0x99, 0x9d, 0x27, 0xe6, 0xae, 0xd5, 0x4a, 0xa4, 0xf2, 0x6b, 0x96, 0xee,
0x5a, 0x27, 0x7e, 0xbf, 0x3d, 0x19, 0xd0, 0xcd, 0x2e, 0xa3, 0xc9, 0xe3,
0x64, 0x67, 0x23, 0x94, 0x07, 0xb7, 0x20, 0x22, 0x9d, 0xd4, 0x13, 0x76,
0xec, 0x76, 0xc2, 0xe2, 0xbe, 0xfe, 0x99, 0x1a, 0x37, 0x28, 0x56, 0x8d,
0x10, 0x46, 0xd7, 0xb3, 0x62, 0xa8, 0x86, 0x46, 0x16, 0xf4, 0x7d, 0x07,
0x20, 0x6f, 0xd4, 0xa2, 0x7a, 0xd8, 0xd0, 0xf1, 0x90, 0xd7, 0xd2, 0xa7,
0x58, 0x69, 0xdd, 0x49, 0x44, 0xe3, 0x97, 0xd7, 0x25, 0x6a, 0x67, 0x70,
0x3c, 0xc7, 0xaa, 0xfd, 0xb6, 0xe4, 0x14, 0xb9, 0x76, 0x55, 0x34, 0x7d,
0x45, 0x66, 0xfb, 0xf9, 0x3a, 0x0b, 0x47, 0xb3, 0xca, 0x66, 0xed, 0xe7,
0xa6, 0x68, 0x38, 0x57, 0xd1, 0x6b, 0xc2, 0x4e, 0x70, 0x25, 0xf9, 0xcd,
0x76, 0x00, 0x5c, 0x54, 0x63, 0xa2, 0xa5, 0x74, 0x4b, 0xde, 0xc1, 0xa7,
0x43, 0x1a, 0x0e, 0x9e, 0x80, 0x07, 0x2b, 0x5b, 0x4f, 0x7c, 0xd3, 0xb6,
0x8e, 0xd7, 0x3a, 0x59, 0xcd, 0x16, 0xd8, 0xf2, 0xeb, 0xc3, 0x56, 0x1f,
0xde, 0x2e, 0x5d, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x81, 0xcb, 0x30,
0x81, 0xc8, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04,
0x14, 0x03, 0x6f, 0x5c, 0x80, 0x4d, 0x2a, 0x06, 0xe3, 0x3b, 0x60, 0xf4,
0x1c, 0xe5, 0xcc, 0xa2, 0xeb, 0xe7, 0xcf, 0x20, 0x19, 0x30, 0x1f, 0x06,
0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x03, 0x6f,
0x5c, 0x80, 0x4d, 0x2a, 0x06, 0xe3, 0x3b, 0x60, 0xf4, 0x1c, 0xe5, 0xcc,
0xa2, 0xeb, 0xe7, 0xcf, 0x20, 0x19, 0x30, 0x09, 0x06, 0x03, 0x55, 0x1d,
0x13, 0x04, 0x02, 0x30, 0x00, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x1d, 0x0f,
0x04, 0x04, 0x03, 0x02, 0x02, 0xf4, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d,
0x25, 0x04, 0x16, 0x30, 0x14, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05,
0x07, 0x03, 0x01, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03,
0x02, 0x30, 0x4f, 0x06, 0x03, 0x55, 0x1d, 0x11, 0x04, 0x48, 0x30, 0x46,
0x82, 0x0a, 0x76, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x62, 0x6f, 0x78,
0x82, 0x0a, 0x76, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x62, 0x6f, 0x78,
0x87, 0x04, 0x0a, 0x00, 0x02, 0x0f, 0x87, 0x04, 0xc0, 0xa8, 0x38, 0x65,
0x86, 0x20, 0x75, 0x72, 0x6e, 0x3a, 0x6f, 0x70, 0x65, 0x6e, 0x36, 0x32,
0x35, 0x34, 0x31, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x61,
0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x30, 0x0d,
0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05,
0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0xc4, 0xb5, 0xd3, 0x3f, 0xaa, 0x26,
0x9a, 0xb2, 0xc3, 0x9a, 0xaf, 0xcf, 0xd2, 0x9b, 0xf0, 0x83, 0x39, 0x95,
0x91, 0x1b, 0x72, 0xcc, 0x2f, 0xa7, 0x3e, 0x08, 0x19, 0xbf, 0x9b, 0xbe,
0xd3, 0x45, 0xea, 0x50, 0xb2, 0x5d, 0xab, 0x19, 0x57, 0x61, 0x55, 0x0a,
0x59, 0x0b, 0x46, 0xbd, 0x88, 0xa2, 0x5a, 0xd1, 0xb7, 0x55, 0x8e, 0x27,
0xb6, 0xff, 0x75, 0x09, 0x43, 0x25, 0x83, 0x82, 0x23, 0xa9, 0xc1, 0x98,
0x0b, 0x0b, 0xd5, 0xe7, 0x36, 0xbb, 0xe8, 0xf9, 0xf7, 0x2c, 0xd1, 0x1f,
0x19, 0x9a, 0x87, 0x82, 0x5f, 0xb8, 0x95, 0xe0, 0x60, 0xcd, 0xf1, 0xdf,
0x66, 0xb8, 0xbe, 0xae, 0xc8, 0x1f, 0x94, 0x34, 0x9f, 0x87, 0x80, 0x29,
0xbd, 0x08, 0x19, 0x7a, 0x47, 0x4d, 0x5c, 0xdb, 0x00, 0x5d, 0xee, 0x87,
0x8e, 0xc2, 0x3d, 0xb0, 0x72, 0xfb, 0xbf, 0x1a, 0xf9, 0xde, 0x76, 0xf1,
0xba, 0x3f, 0xed, 0x97, 0x17, 0xc5, 0xc7, 0x4b, 0x94, 0x03, 0x8a, 0x63,
0x66, 0xd3, 0x49, 0x35, 0x30, 0x97, 0x1c, 0x37, 0x83, 0x08, 0xb3, 0x9f,
0x5d, 0xf7, 0xd4, 0x40, 0x63, 0xc5, 0xc2, 0x54, 0x9a, 0x87, 0x59, 0x17,
0x7f, 0x78, 0x02, 0xa4, 0xcb, 0x0b, 0x18, 0x32, 0xc0, 0x74, 0x94, 0xbe,
0x07, 0x29, 0x18, 0x1e, 0x65, 0x9f, 0x3c, 0x6a, 0x9a, 0x7b, 0xce, 0xff,
0x21, 0x79, 0x40, 0x03, 0x79, 0xd5, 0xa5, 0xb9, 0xbf, 0xc9, 0xba, 0x29,
0x18, 0xc9, 0xf8, 0x93, 0x69, 0xb1, 0x86, 0xc9, 0x32, 0x1a, 0x67, 0x2f,
0x60, 0xaa, 0xdd, 0x0e, 0xb0, 0xb4, 0x1d, 0x44, 0x71, 0xc3, 0x89, 0x48,
0xab, 0xc7, 0x36, 0xf8, 0xfc, 0xf2, 0x95, 0x07, 0xd1, 0x68, 0x2b, 0xe4,
0x16, 0x82, 0x63, 0x90, 0x58, 0xf1, 0x10, 0xf4, 0x33, 0xf8, 0xb8, 0x5d,
0x29, 0x95, 0x73, 0xf7, 0xc9, 0x97, 0xdb, 0x23, 0x6c, 0x01
};
#define CLIENT_KEY_DER_LENGTH 1218
UA_Byte CLIENT_KEY_DER_DATA[CLIENT_KEY_DER_LENGTH] = {
0x30, 0x82, 0x04, 0xbe, 0x02, 0x01, 0x00, 0x30, 0x0d, 0x06, 0x09, 0x2a,
0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82,
0x04, 0xa8, 0x30, 0x82, 0x04, 0xa4, 0x02, 0x01, 0x00, 0x02, 0x82, 0x01,
0x01, 0x00, 0xcf, 0xe9, 0xd9, 0x66, 0x9a, 0x06, 0xa1, 0x6d, 0x87, 0x90,
0x44, 0xca, 0xdc, 0xff, 0x4a, 0xe4, 0x1c, 0x0a, 0x5e, 0xe9, 0x62, 0xe4,
0x08, 0x6b, 0x83, 0x23, 0xdc, 0x76, 0xe3, 0xe1, 0xbe, 0x73, 0x0a, 0xb6,
0x1a, 0x07, 0x8b, 0x80, 0x7f, 0xe2, 0x87, 0x6f, 0x8f, 0xf2, 0xe3, 0xf5,
0x64, 0x83, 0xe5, 0x6f, 0x83, 0x2b, 0xb4, 0x9d, 0xd6, 0xf2, 0x6f, 0xa2,
0x2a, 0x78, 0x6c, 0xcf, 0xba, 0x9d, 0xd1, 0xca, 0xad, 0xa2, 0xed, 0xd0,
0x52, 0x53, 0x6c, 0x09, 0x72, 0xe8, 0xcc, 0xb5, 0xb6, 0x99, 0xea, 0xf9,
0x04, 0x04, 0xee, 0x42, 0x12, 0x18, 0x8a, 0x20, 0xbb, 0x05, 0xce, 0xe1,
0x32, 0x54, 0x5a, 0x99, 0x9d, 0x27, 0xe6, 0xae, 0xd5, 0x4a, 0xa4, 0xf2,
0x6b, 0x96, 0xee, 0x5a, 0x27, 0x7e, 0xbf, 0x3d, 0x19, 0xd0, 0xcd, 0x2e,
0xa3, 0xc9, 0xe3, 0x64, 0x67, 0x23, 0x94, 0x07, 0xb7, 0x20, 0x22, 0x9d,
0xd4, 0x13, 0x76, 0xec, 0x76, 0xc2, 0xe2, 0xbe, 0xfe, 0x99, 0x1a, 0x37,
0x28, 0x56, 0x8d, 0x10, 0x46, 0xd7, 0xb3, 0x62, 0xa8, 0x86, 0x46, 0x16,
0xf4, 0x7d, 0x07, 0x20, 0x6f, 0xd4, 0xa2, 0x7a, 0xd8, 0xd0, 0xf1, 0x90,
0xd7, 0xd2, 0xa7, 0x58, 0x69, 0xdd, 0x49, 0x44, 0xe3, 0x97, 0xd7, 0x25,
0x6a, 0x67, 0x70, 0x3c, 0xc7, 0xaa, 0xfd, 0xb6, 0xe4, 0x14, 0xb9, 0x76,
0x55, 0x34, 0x7d, 0x45, 0x66, 0xfb, 0xf9, 0x3a, 0x0b, 0x47, 0xb3, 0xca,
0x66, 0xed, 0xe7, 0xa6, 0x68, 0x38, 0x57, 0xd1, 0x6b, 0xc2, 0x4e, 0x70,
0x25, 0xf9, 0xcd, 0x76, 0x00, 0x5c, 0x54, 0x63, 0xa2, 0xa5, 0x74, 0x4b,
0xde, 0xc1, 0xa7, 0x43, 0x1a, 0x0e, 0x9e, 0x80, 0x07, 0x2b, 0x5b, 0x4f,
0x7c, 0xd3, 0xb6, 0x8e, 0xd7, 0x3a, 0x59, 0xcd, 0x16, 0xd8, 0xf2, 0xeb,
0xc3, 0x56, 0x1f, 0xde, 0x2e, 0x5d, 0x02, 0x03, 0x01, 0x00, 0x01, 0x02,
0x82, 0x01, 0x00, 0x16, 0x6a, 0xa6, 0x2f, 0xf3, 0xc7, 0x67, 0x3c, 0x41,
0xf3, 0x82, 0x17, 0x45, 0x40, 0x99, 0x38, 0x82, 0xf5, 0x73, 0x4a, 0x42,
0x89, 0x47, 0x87, 0x1f, 0xfa, 0x8b, 0xd8, 0x9d, 0xb5, 0x47, 0x2d, 0x6c,
0x28, 0x3a, 0x22, 0x3a, 0x1e, 0x3e, 0xab, 0x93, 0xe2, 0xa9, 0x68, 0x8c,
0xbf, 0x76, 0x78, 0xea, 0x11, 0xdd, 0xd8, 0xa6, 0x7e, 0xa6, 0x20, 0x39,
0x7d, 0x08, 0x8b, 0x37, 0x60, 0x26, 0x44, 0xc1, 0xcb, 0xd2, 0x70, 0xd0,
0xa7, 0x37, 0x59, 0x1b, 0x3a, 0xe1, 0x92, 0xcc, 0x0f, 0x83, 0x82, 0x90,
0xdd, 0x0c, 0x5b, 0xe3, 0xbc, 0x67, 0xeb, 0x11, 0x69, 0x7a, 0x00, 0xa4,
0x4f, 0x8f, 0x77, 0x9c, 0xd5, 0x17, 0x26, 0xa8, 0x2e, 0x8d, 0x7c, 0xa0,
0xd0, 0x2a, 0x5d, 0x79, 0x91, 0x6a, 0xd4, 0xb5, 0x95, 0xc6, 0xe4, 0xc6,
0x5a, 0x92, 0xfa, 0x3f, 0x74, 0x21, 0xd2, 0xaa, 0x31, 0x32, 0xc3, 0x28,
0x70, 0xd9, 0x86, 0x7f, 0x85, 0x6b, 0x1b, 0xa8, 0x7c, 0x8a, 0x1f, 0xb6,
0x4c, 0xe2, 0xb6, 0x55, 0xd1, 0x61, 0x10, 0xc0, 0x8e, 0x39, 0x6f, 0x9f,
0xac, 0xde, 0x0f, 0xb0, 0x4d, 0x9a, 0x29, 0x60, 0x8c, 0x2a, 0xfb, 0x44,
0x08, 0x5a, 0x04, 0xc3, 0x03, 0x75, 0xb0, 0x9f, 0xb0, 0x25, 0xe1, 0xda,
0x1f, 0x2f, 0xd8, 0xe6, 0xb5, 0x09, 0x93, 0x1a, 0xb5, 0x0f, 0xdd, 0xbd,
0xa1, 0xab, 0x48, 0x85, 0x94, 0xe8, 0x9c, 0x70, 0x8d, 0xfc, 0xf8, 0xf1,
0xa9, 0xe2, 0x16, 0x6c, 0x27, 0xba, 0x39, 0xe5, 0x06, 0x96, 0xf4, 0x46,
0x6f, 0x0d, 0x08, 0xc9, 0xeb, 0xd1, 0x24, 0x01, 0x07, 0x08, 0xa6, 0x0e,
0xee, 0xeb, 0xeb, 0x6e, 0xc7, 0xaf, 0x90, 0x8a, 0x8b, 0xf1, 0x0f, 0x75,
0xcd, 0xef, 0xec, 0x6c, 0xaf, 0x7e, 0xf1, 0x64, 0xb8, 0x9d, 0x57, 0xd2,
0x58, 0xb3, 0x73, 0xa9, 0x0c, 0xe3, 0x81, 0x02, 0x81, 0x81, 0x00, 0xee,
0xde, 0xc3, 0x6d, 0x83, 0xf3, 0xe3, 0x69, 0x31, 0x27, 0xbb, 0x62, 0x9d,
0xd6, 0xfb, 0xc4, 0x3b, 0x55, 0x5c, 0xf4, 0x2a, 0xcb, 0xdb, 0x99, 0x14,
0x18, 0xe7, 0xa6, 0x2c, 0xee, 0x98, 0x89, 0x4f, 0x8a, 0xe6, 0xc7, 0xf6,
0x66, 0x65, 0x89, 0x05, 0x24, 0xd5, 0x68, 0x1f, 0x61, 0x09, 0x26, 0xc8,
0xc2, 0x2b, 0x9d, 0x9d, 0xb7, 0x34, 0x65, 0x05, 0x1b, 0x86, 0xbd, 0xe9,
0x44, 0x3a, 0x44, 0x62, 0x98, 0x84, 0xe4, 0x09, 0x95, 0xc4, 0x18, 0x42,
0x74, 0xb5, 0xb3, 0x62, 0xaa, 0x7d, 0x70, 0x85, 0x6e, 0x57, 0x38, 0x58,
0x96, 0x67, 0x93, 0x71, 0x9a, 0xc6, 0x71, 0x08, 0xcf, 0x43, 0x59, 0x5f,
0x7b, 0x5a, 0x78, 0x89, 0x40, 0x71, 0xd3, 0x8f, 0xe0, 0xd7, 0xfb, 0x9b,
0xf4, 0x70, 0x5c, 0x87, 0x48, 0x7b, 0x77, 0xf5, 0x1a, 0xa2, 0xde, 0x21,
0xa6, 0x90, 0xcc, 0x2f, 0x4f, 0x1d, 0x8d, 0x02, 0x81, 0x81, 0x00, 0xde,
0xd2, 0xc6, 0x79, 0x21, 0x90, 0xca, 0x61, 0x76, 0x2a, 0xb2, 0x23, 0xb4,
0x13, 0x54, 0x86, 0x6a, 0xaa, 0xa6, 0x91, 0xaa, 0xf8, 0xd6, 0xb6, 0xcf,
0x6d, 0xef, 0xfa, 0xec, 0x8d, 0x7c, 0x52, 0x66, 0x3a, 0x60, 0xeb, 0x3c,
0x64, 0xb3, 0xc0, 0x36, 0x72, 0x28, 0xda, 0x1f, 0x5a, 0xfe, 0x17, 0x7e,
0xf3, 0xcd, 0xac, 0xf6, 0x9b, 0xe1, 0xf5, 0x9a, 0x67, 0x3e, 0xcd, 0xf4,
0x84, 0xf7, 0x47, 0xe4, 0xdb, 0xc1, 0xf1, 0xec, 0xcc, 0xdf, 0x63, 0xa9,
0xc0, 0x37, 0x8e, 0xc8, 0x00, 0xf9, 0xb8, 0x8f, 0x58, 0x23, 0xb9, 0x5f,
0x03, 0x92, 0x7e, 0xbe, 0x3c, 0x10, 0xfc, 0x63, 0xbe, 0x56, 0x8f, 0xfd,
0xbc, 0xa1, 0xc3, 0x8c, 0x78, 0x89, 0x5a, 0xca, 0x58, 0xe9, 0xa5, 0x9b,
0xa7, 0xa5, 0xfe, 0x96, 0xf7, 0xae, 0x42, 0x39, 0x70, 0x38, 0xfb, 0x55,
0xff, 0x5a, 0x86, 0x02, 0x38, 0x18, 0x11, 0x02, 0x81, 0x80, 0x7a, 0x09,
0x20, 0xfa, 0xb0, 0x71, 0x47, 0x7b, 0x94, 0x7b, 0x62, 0x06, 0x8d, 0xf1,
0x29, 0x8b, 0x25, 0x6d, 0x05, 0x22, 0x51, 0x42, 0xf9, 0x1c, 0x09, 0xe2,
0x77, 0x66, 0xb4, 0x89, 0xe9, 0x30, 0x2d, 0x8d, 0x1f, 0x3e, 0x85, 0xa9,
0xe6, 0xb1, 0xcc, 0x08, 0xf7, 0x66, 0x4c, 0xb1, 0xbc, 0x85, 0x2e, 0x07,
0xd5, 0x54, 0x9f, 0x20, 0xdc, 0x09, 0xc8, 0x44, 0x39, 0xe0, 0x88, 0x6e,
0x2c, 0xfe, 0x87, 0x08, 0xb8, 0xcb, 0xf0, 0x01, 0xad, 0xbf, 0x5f, 0x24,
0x55, 0x38, 0x22, 0x6e, 0x4b, 0xcb, 0xd2, 0xbf, 0x7e, 0x9b, 0xf0, 0xd6,
0x56, 0x70, 0x43, 0x97, 0xf9, 0x4e, 0x02, 0x5c, 0x31, 0x62, 0x55, 0x9f,
0xa5, 0xa6, 0xf3, 0x28, 0x13, 0x7f, 0x2c, 0x80, 0x88, 0x97, 0xa9, 0x23,
0x86, 0xcc, 0x1e, 0xe9, 0x6e, 0xfa, 0xe8, 0x24, 0x05, 0x95, 0x4a, 0xc7,
0xd8, 0x2e, 0x18, 0xf5, 0x68, 0x79, 0x02, 0x81, 0x81, 0x00, 0xcb, 0xe5,
0x4f, 0xdc, 0x94, 0x0c, 0x6c, 0x44, 0xd6, 0xde, 0xa6, 0xf7, 0xe8, 0xd6,
0x2f, 0x68, 0x78, 0xbf, 0x03, 0x81, 0x14, 0x54, 0x74, 0x16, 0x00, 0xa5,
0xf7, 0x0d, 0x43, 0xdd, 0x0c, 0x40, 0x52, 0x6f, 0x65, 0x34, 0x9c, 0xa5,
0x01, 0x9f, 0x07, 0xb3, 0x5b, 0x12, 0x8d, 0xd2, 0xb3, 0xe4, 0x48, 0x35,
0x4c, 0xa5, 0xd3, 0x5c, 0x3d, 0x5e, 0x83, 0x15, 0xaa, 0xf0, 0xc7, 0xa9,
0xcc, 0xa5, 0xab, 0x14, 0x34, 0xda, 0xed, 0xf7, 0x63, 0x0b, 0x4d, 0xd0,
0x28, 0x86, 0xad, 0x19, 0xc7, 0x69, 0x4d, 0x32, 0x38, 0x2e, 0x6e, 0x75,
0x54, 0x5e, 0x4a, 0x31, 0xa8, 0xd1, 0x6b, 0x6c, 0x46, 0xc5, 0xa8, 0x48,
0x2e, 0x36, 0x44, 0x9a, 0x20, 0x06, 0x46, 0x57, 0x2a, 0x26, 0x72, 0xd2,
0xec, 0x20, 0x95, 0x80, 0xbb, 0xa2, 0xb9, 0xf0, 0xa9, 0x13, 0xc4, 0x53,
0xd0, 0x40, 0x04, 0x53, 0xd4, 0x21, 0x02, 0x81, 0x81, 0x00, 0xc7, 0xf4,
0x63, 0x08, 0x30, 0xb6, 0x34, 0x62, 0xdd, 0xf1, 0x99, 0x40, 0xa4, 0xc3,
0x86, 0xe0, 0x58, 0xb9, 0xc2, 0x77, 0x0c, 0x48, 0x8d, 0x86, 0x73, 0x27,
0xa3, 0x8c, 0xe8, 0x90, 0xed, 0x34, 0x40, 0x03, 0x3b, 0x47, 0x10, 0x40,
0xe6, 0x2d, 0xb6, 0xa1, 0x86, 0x71, 0xbc, 0x0a, 0xd2, 0x79, 0x0f, 0xe4,
0xaa, 0x71, 0xc2, 0xee, 0x7f, 0xf7, 0x89, 0x2f, 0xf2, 0xee, 0x79, 0x40,
0x6c, 0xa2, 0x30, 0x41, 0xda, 0xe7, 0x80, 0x76, 0x0c, 0xf6, 0xb2, 0xfb,
0x54, 0xf3, 0x45, 0xe5, 0x67, 0xa2, 0x45, 0x06, 0x24, 0x98, 0x4c, 0xbe,
0xef, 0xc2, 0x10, 0x98, 0x04, 0x0e, 0x6c, 0x3e, 0x23, 0x70, 0x9a, 0x14,
0xb9, 0x88, 0x2f, 0xa4, 0x2b, 0xec, 0x90, 0x88, 0x0d, 0x75, 0x3b, 0xae,
0x24, 0x87, 0xfc, 0x25, 0x05, 0xe9, 0xf1, 0xc5, 0xb6, 0xc1, 0xa5, 0x11,
0x76, 0xd1, 0xee, 0xdb, 0x2e, 0x44
};
#define SERVER_CERT_DER_LENGTH 1030
UA_Byte SERVER_CERT_DER_DATA[SERVER_CERT_DER_LENGTH] = {
0x30, 0x82, 0x04, 0x02, 0x30, 0x82, 0x02, 0xea, 0xa0, 0x03, 0x02, 0x01,
0x02, 0x02, 0x14, 0x59, 0x1b, 0x70, 0x7b, 0xac, 0xa0, 0x8e, 0xb0, 0xe1,
0x4f, 0x06, 0x48, 0xef, 0x91, 0x01, 0x5d, 0xc4, 0x3e, 0xde, 0x0b, 0x30,
0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b,
0x05, 0x00, 0x30, 0x54, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04,
0x06, 0x13, 0x02, 0x44, 0x45, 0x31, 0x0d, 0x30, 0x0b, 0x06, 0x03, 0x55,
0x04, 0x07, 0x0c, 0x04, 0x48, 0x65, 0x72, 0x65, 0x31, 0x12, 0x30, 0x10,
0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x09, 0x6f, 0x70, 0x65, 0x6e, 0x36,
0x32, 0x35, 0x34, 0x31, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04,
0x03, 0x0c, 0x19, 0x6f, 0x70, 0x65, 0x6e, 0x36, 0x32, 0x35, 0x34, 0x31,
0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x40, 0x6c, 0x6f, 0x63, 0x61, 0x6c,
0x68, 0x6f, 0x73, 0x74, 0x30, 0x1e, 0x17, 0x0d, 0x32, 0x33, 0x31, 0x31,
0x30, 0x38, 0x31, 0x35, 0x31, 0x35, 0x35, 0x34, 0x5a, 0x17, 0x0d, 0x33,
0x33, 0x31, 0x31, 0x30, 0x35, 0x31, 0x35, 0x31, 0x35, 0x35, 0x34, 0x5a,
0x30, 0x54, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
0x02, 0x44, 0x45, 0x31, 0x0d, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x04, 0x07,
0x0c, 0x04, 0x48, 0x65, 0x72, 0x65, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03,
0x55, 0x04, 0x0a, 0x0c, 0x09, 0x6f, 0x70, 0x65, 0x6e, 0x36, 0x32, 0x35,
0x34, 0x31, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c,
0x19, 0x6f, 0x70, 0x65, 0x6e, 0x36, 0x32, 0x35, 0x34, 0x31, 0x53, 0x65,
0x72, 0x76, 0x65, 0x72, 0x40, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f,
0x73, 0x74, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01,
0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xcf,
0x37, 0x8d, 0x67, 0xf0, 0x28, 0x1a, 0x6b, 0x58, 0x15, 0x19, 0x80, 0x2e,
0xf8, 0xcc, 0xad, 0x85, 0xa1, 0x9c, 0x2f, 0x39, 0x5b, 0x1b, 0xbc, 0xe3,
0x02, 0xa5, 0xac, 0x71, 0xfe, 0xce, 0xa8, 0x59, 0x6a, 0x3c, 0x4c, 0xef,
0xf8, 0x9a, 0x75, 0x3f, 0x77, 0x63, 0xe1, 0x1c, 0x52, 0xbc, 0x13, 0x2c,
0xfb, 0xdd, 0x80, 0x3a, 0x4f, 0x69, 0xaa, 0x7f, 0x77, 0xca, 0x99, 0x1f,
0x1a, 0x42, 0xb5, 0x3f, 0x54, 0xa3, 0x9a, 0x38, 0x85, 0xc5, 0x12, 0x87,
0xd7, 0xe2, 0x58, 0x36, 0x6b, 0xd1, 0xf1, 0xcf, 0xa0, 0x66, 0x08, 0x98,
0xdc, 0xaf, 0x46, 0x66, 0xee, 0x36, 0x91, 0x50, 0x21, 0x20, 0xd6, 0xc4,
0xbb, 0x2d, 0x0b, 0x25, 0x05, 0xeb, 0x0e, 0xcf, 0x2f, 0x15, 0x5e, 0xa5,
0x97, 0x3f, 0x37, 0xc2, 0xf1, 0x2f, 0xd1, 0x8f, 0xd4, 0xc4, 0x76, 0x79,
0x70, 0xbb, 0x73, 0xb4, 0x18, 0xa9, 0x1e, 0xc6, 0xde, 0x2e, 0x77, 0xe9,
0x8b, 0x67, 0x01, 0xd8, 0x97, 0x55, 0xa2, 0x78, 0x35, 0xa7, 0x80, 0xcd,
0xe7, 0x70, 0xa3, 0x84, 0xfc, 0x0d, 0x87, 0xaf, 0xc7, 0x6d, 0xa1, 0xa6,
0x8a, 0x8a, 0x1e, 0x2f, 0xa9, 0x31, 0x00, 0x34, 0xda, 0xe9, 0x4c, 0x6d,
0x96, 0x4c, 0x00, 0x16, 0xab, 0x75, 0x94, 0x73, 0x97, 0x1d, 0x02, 0xfb,
0x7f, 0x1f, 0x1c, 0x20, 0xc4, 0xb9, 0x72, 0x32, 0xeb, 0x43, 0x1c, 0x43,
0x9e, 0x88, 0xc1, 0x3c, 0xab, 0x27, 0x95, 0x61, 0x78, 0x0b, 0xea, 0x39,
0x29, 0x0b, 0xb7, 0xdb, 0xcd, 0xe5, 0x43, 0xfa, 0x9a, 0x8b, 0x14, 0x9e,
0x4e, 0xd8, 0x64, 0x0f, 0x95, 0xea, 0xed, 0xac, 0xa2, 0x80, 0xb9, 0xa4,
0x89, 0x7f, 0x30, 0x39, 0x53, 0xad, 0x3d, 0x5d, 0xf6, 0x27, 0xc5, 0x5a,
0x95, 0xaa, 0x47, 0xbc, 0xe4, 0xfe, 0x1b, 0x1e, 0x23, 0x76, 0xa5, 0x2d,
0xf7, 0x6a, 0xa9, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x81, 0xcb, 0x30,
0x81, 0xc8, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04,
0x14, 0xb4, 0x1f, 0xa6, 0xe1, 0x8b, 0x56, 0x14, 0xe9, 0x9e, 0xf5, 0xbe,
0x3d, 0x00, 0xa8, 0xb4, 0x49, 0xa6, 0x98, 0x12, 0xc2, 0x30, 0x1f, 0x06,
0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0xb4, 0x1f,
0xa6, 0xe1, 0x8b, 0x56, 0x14, 0xe9, 0x9e, 0xf5, 0xbe, 0x3d, 0x00, 0xa8,
0xb4, 0x49, 0xa6, 0x98, 0x12, 0xc2, 0x30, 0x09, 0x06, 0x03, 0x55, 0x1d,
0x13, 0x04, 0x02, 0x30, 0x00, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x1d, 0x0f,
0x04, 0x04, 0x03, 0x02, 0x02, 0xf4, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d,
0x25, 0x04, 0x16, 0x30, 0x14, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05,
0x07, 0x03, 0x01, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03,
0x02, 0x30, 0x4f, 0x06, 0x03, 0x55, 0x1d, 0x11, 0x04, 0x48, 0x30, 0x46,
0x82, 0x0a, 0x76, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x62, 0x6f, 0x78,
0x82, 0x0a, 0x76, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x62, 0x6f, 0x78,
0x87, 0x04, 0x0a, 0x00, 0x02, 0x0f, 0x87, 0x04, 0xc0, 0xa8, 0x38, 0x65,
0x86, 0x20, 0x75, 0x72, 0x6e, 0x3a, 0x6f, 0x70, 0x65, 0x6e, 0x36, 0x32,
0x35, 0x34, 0x31, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x61,
0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x30, 0x0d,
0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05,
0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x73, 0xfc, 0x75, 0xb9, 0xba, 0x6a,
0x7d, 0x20, 0xbb, 0xec, 0x7f, 0xa1, 0xdd, 0xbc, 0xf8, 0x70, 0x94, 0x67,
0x3f, 0xd3, 0xf3, 0x01, 0x3b, 0xe2, 0x8b, 0x12, 0x21, 0xec, 0xb6, 0x47,
0x93, 0x9f, 0xa5, 0x6e, 0xf0, 0x88, 0x17, 0x69, 0x10, 0x08, 0xd0, 0xd8,
0x7a, 0x82, 0x70, 0x1a, 0x1b, 0xf3, 0xa8, 0x40, 0x1f, 0xa0, 0xe2, 0x81,
0x4c, 0x1d, 0x8a, 0x37, 0xdf, 0x02, 0xcb, 0x42, 0xb4, 0xcf, 0xb8, 0x5c,
0x78, 0x87, 0x0a, 0x26, 0x7d, 0x64, 0x2d, 0x07, 0x6a, 0xa1, 0x0a, 0xd8,
0xa6, 0x76, 0xbe, 0x9f, 0x54, 0x37, 0x4a, 0x4e, 0x00, 0x8f, 0x46, 0xab,
0xc7, 0x6c, 0x32, 0xbc, 0xfa, 0x3a, 0x05, 0xd4, 0xef, 0x7e, 0x57, 0xac,
0x22, 0x3c, 0x06, 0xad, 0x2b, 0x68, 0x39, 0x01, 0x7f, 0xdb, 0xa5, 0x18,
0xed, 0x15, 0x9c, 0x64, 0x38, 0x30, 0xcd, 0x01, 0x0f, 0xd0, 0xc6, 0x2d,
0x7d, 0x7f, 0x1e, 0xde, 0x8b, 0xea, 0x29, 0x17, 0x9a, 0x16, 0x07, 0x03,
0xd9, 0xe4, 0x01, 0x86, 0xd6, 0xd2, 0xdd, 0xa0, 0xb6, 0x6c, 0xca, 0x68,
0x88, 0xdd, 0xfe, 0x85, 0x60, 0x64, 0xf2, 0x54, 0x37, 0x83, 0x7d, 0x53,
0x24, 0xe0, 0x0c, 0x87, 0x82, 0x93, 0xb6, 0x3a, 0x4c, 0xf3, 0xe3, 0xfc,
0x0f, 0x6c, 0xcf, 0xce, 0x22, 0x8d, 0x38, 0x28, 0x0c, 0x47, 0xa4, 0x99,
0x2f, 0x7d, 0xbd, 0x21, 0xc9, 0xd3, 0xd8, 0x55, 0xfe, 0x87, 0xba, 0x13,
0x12, 0x89, 0xa0, 0x0f, 0xa7, 0x83, 0x35, 0x79, 0xb8, 0xa5, 0xb0, 0xbb,
0xcd, 0xa5, 0xfd, 0x7d, 0x8e, 0x65, 0xb3, 0xc3, 0x3c, 0xe5, 0x59, 0x27,
0xdc, 0xf6, 0x0f, 0xe6, 0xc5, 0x01, 0xe1, 0xe8, 0x12, 0x08, 0xd4, 0xf0,
0x63, 0x1d, 0x37, 0xb8, 0xc0, 0x24, 0xbe, 0x90, 0x97, 0x35, 0x6e, 0xb7,
0xee, 0xcb, 0x30, 0x0f, 0x10, 0x52, 0x47, 0x10, 0x8b, 0xc3
};
#define SERVER_KEY_DER_LENGTH 1218
UA_Byte SERVER_KEY_DER_DATA[SERVER_KEY_DER_LENGTH] = {
0x30, 0x82, 0x04, 0xbe, 0x02, 0x01, 0x00, 0x30, 0x0d, 0x06, 0x09, 0x2a,
0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82,
0x04, 0xa8, 0x30, 0x82, 0x04, 0xa4, 0x02, 0x01, 0x00, 0x02, 0x82, 0x01,
0x01, 0x00, 0xcf, 0x37, 0x8d, 0x67, 0xf0, 0x28, 0x1a, 0x6b, 0x58, 0x15,
0x19, 0x80, 0x2e, 0xf8, 0xcc, 0xad, 0x85, 0xa1, 0x9c, 0x2f, 0x39, 0x5b,
0x1b, 0xbc, 0xe3, 0x02, 0xa5, 0xac, 0x71, 0xfe, 0xce, 0xa8, 0x59, 0x6a,
0x3c, 0x4c, 0xef, 0xf8, 0x9a, 0x75, 0x3f, 0x77, 0x63, 0xe1, 0x1c, 0x52,
0xbc, 0x13, 0x2c, 0xfb, 0xdd, 0x80, 0x3a, 0x4f, 0x69, 0xaa, 0x7f, 0x77,
0xca, 0x99, 0x1f, 0x1a, 0x42, 0xb5, 0x3f, 0x54, 0xa3, 0x9a, 0x38, 0x85,
0xc5, 0x12, 0x87, 0xd7, 0xe2, 0x58, 0x36, 0x6b, 0xd1, 0xf1, 0xcf, 0xa0,
0x66, 0x08, 0x98, 0xdc, 0xaf, 0x46, 0x66, 0xee, 0x36, 0x91, 0x50, 0x21,
0x20, 0xd6, 0xc4, 0xbb, 0x2d, 0x0b, 0x25, 0x05, 0xeb, 0x0e, 0xcf, 0x2f,
0x15, 0x5e, 0xa5, 0x97, 0x3f, 0x37, 0xc2, 0xf1, 0x2f, 0xd1, 0x8f, 0xd4,
0xc4, 0x76, 0x79, 0x70, 0xbb, 0x73, 0xb4, 0x18, 0xa9, 0x1e, 0xc6, 0xde,
0x2e, 0x77, 0xe9, 0x8b, 0x67, 0x01, 0xd8, 0x97, 0x55, 0xa2, 0x78, 0x35,
0xa7, 0x80, 0xcd, 0xe7, 0x70, 0xa3, 0x84, 0xfc, 0x0d, 0x87, 0xaf, 0xc7,
0x6d, 0xa1, 0xa6, 0x8a, 0x8a, 0x1e, 0x2f, 0xa9, 0x31, 0x00, 0x34, 0xda,
0xe9, 0x4c, 0x6d, 0x96, 0x4c, 0x00, 0x16, 0xab, 0x75, 0x94, 0x73, 0x97,
0x1d, 0x02, 0xfb, 0x7f, 0x1f, 0x1c, 0x20, 0xc4, 0xb9, 0x72, 0x32, 0xeb,
0x43, 0x1c, 0x43, 0x9e, 0x88, 0xc1, 0x3c, 0xab, 0x27, 0x95, 0x61, 0x78,
0x0b, 0xea, 0x39, 0x29, 0x0b, 0xb7, 0xdb, 0xcd, 0xe5, 0x43, 0xfa, 0x9a,
0x8b, 0x14, 0x9e, 0x4e, 0xd8, 0x64, 0x0f, 0x95, 0xea, 0xed, 0xac, 0xa2,
0x80, 0xb9, 0xa4, 0x89, 0x7f, 0x30, 0x39, 0x53, 0xad, 0x3d, 0x5d, 0xf6,
0x27, 0xc5, 0x5a, 0x95, 0xaa, 0x47, 0xbc, 0xe4, 0xfe, 0x1b, 0x1e, 0x23,
0x76, 0xa5, 0x2d, 0xf7, 0x6a, 0xa9, 0x02, 0x03, 0x01, 0x00, 0x01, 0x02,
0x82, 0x01, 0x00, 0x03, 0x0b, 0x7a, 0xed, 0x73, 0x0e, 0xf3, 0xcc, 0x6d,
0xff, 0xe9, 0x5f, 0x03, 0xd1, 0xae, 0x18, 0x42, 0xa5, 0x6c, 0x49, 0x19,
0x5b, 0xa8, 0x5d, 0xaf, 0x2c, 0x43, 0xc8, 0xf3, 0xe7, 0xdd, 0x9b, 0x85,
0xac, 0xd4, 0xf4, 0x00, 0x76, 0xb3, 0xb6, 0x53, 0x57, 0x6a, 0xc5, 0x4d,
0x08, 0x3e, 0x31, 0x3d, 0xf0, 0xf9, 0x81, 0x3f, 0xda, 0x18, 0xe0, 0x63,
0x7d, 0x1c, 0x22, 0x01, 0xdd, 0xfd, 0xea, 0xf1, 0xe2, 0x49, 0x81, 0x23,
0xa1, 0x7b, 0x92, 0xd9, 0x22, 0x27, 0xf6, 0x49, 0xde, 0x6d, 0xb8, 0x52,
0xe7, 0xb5, 0x78, 0x1c, 0xde, 0xe9, 0x48, 0x6c, 0x8c, 0xc5, 0x8a, 0x7f,
0x15, 0xed, 0x88, 0x9a, 0x5d, 0x71, 0xbc, 0xff, 0x2f, 0x46, 0x13, 0xf2,
0xa1, 0x6b, 0x7b, 0xf7, 0x8c, 0xf0, 0x65, 0xde, 0x5c, 0x72, 0xea, 0x6e,
0x65, 0x9e, 0xf9, 0x6a, 0xb1, 0x68, 0x5f, 0xbb, 0xde, 0xbc, 0xe5, 0x6b,
0x19, 0x8a, 0x4a, 0x03, 0x6d, 0x14, 0x1f, 0xfd, 0xe0, 0x05, 0x13, 0x0e,
0x70, 0x0c, 0xf7, 0xa7, 0xbb, 0x2e, 0x87, 0x1f, 0xac, 0x87, 0x16, 0x06,
0x4b, 0x81, 0x1e, 0x97, 0x43, 0xc5, 0x6f, 0x7c, 0x6d, 0x90, 0x43, 0xd5,
0x25, 0x1e, 0x2e, 0x0f, 0xf4, 0xe6, 0x1a, 0xfc, 0xe2, 0x88, 0x7d, 0xd3,
0x82, 0x92, 0x51, 0xf7, 0x31, 0x32, 0xab, 0xf9, 0x9a, 0x1d, 0x7e, 0x94,
0x57, 0xd0, 0xac, 0xf8, 0x5a, 0x80, 0xd1, 0xb7, 0x7e, 0x3b, 0xcc, 0x29,
0x1f, 0x23, 0xf1, 0xa4, 0x1d, 0x11, 0xa4, 0x02, 0x62, 0xcb, 0x4f, 0x6e,
0x01, 0x24, 0x46, 0x15, 0xec, 0x85, 0xb8, 0xe8, 0x47, 0xef, 0x70, 0x81,
0xf0, 0x94, 0xb4, 0x2a, 0xbd, 0x6f, 0xf0, 0xa0, 0xbb, 0x54, 0xdb, 0xf9,
0xb6, 0xf2, 0x25, 0x3a, 0x58, 0x8d, 0xc7, 0xb1, 0x99, 0x6b, 0x0d, 0x1a,
0x5a, 0xf5, 0xf8, 0xbc, 0x2f, 0x01, 0x0d, 0x02, 0x81, 0x81, 0x00, 0xf2,
0x90, 0x20, 0xf2, 0x2b, 0x6c, 0xf6, 0x84, 0xc6, 0xe3, 0xe1, 0x34, 0xcb,
0xfe, 0x77, 0xa1, 0x50, 0xf8, 0x6e, 0xaf, 0x83, 0x8e, 0x06, 0xe1, 0x70,
0x72, 0xec, 0xfb, 0x0e, 0x86, 0x18, 0x15, 0x9a, 0x1f, 0x76, 0xa7, 0xb5,
0x86, 0x7a, 0x4e, 0xc5, 0x80, 0xc7, 0xa8, 0x1d, 0x14, 0xbf, 0xc0, 0xef,
0x70, 0xca, 0xa8, 0xfc, 0x39, 0xc8, 0xe8, 0x16, 0xe2, 0x0e, 0x52, 0x49,
0xe6, 0x00, 0x46, 0x6d, 0x42, 0x83, 0x7e, 0x10, 0xc4, 0x75, 0x6c, 0x5f,
0xe8, 0x16, 0x92, 0x54, 0xab, 0x06, 0xfb, 0x66, 0xe3, 0x63, 0x8e, 0x04,
0xed, 0x8a, 0xa9, 0xe4, 0x7d, 0xe0, 0xdd, 0x04, 0x8a, 0xcf, 0xa0, 0x06,
0xcd, 0xc8, 0x4a, 0xc9, 0x16, 0xb0, 0xbf, 0x29, 0x6c, 0x94, 0x9b, 0x1c,
0x50, 0xf3, 0xea, 0x8a, 0x24, 0xf7, 0xbe, 0x9a, 0x3e, 0x14, 0x24, 0xee,
0xe7, 0xad, 0x7d, 0x95, 0xb0, 0xd5, 0x1b, 0x02, 0x81, 0x81, 0x00, 0xda,
0xb2, 0x2b, 0x6a, 0x2b, 0xe2, 0x7a, 0xd6, 0x63, 0xd7, 0x5b, 0x27, 0x5b,
0x1b, 0x6e, 0xb0, 0x3f, 0xd5, 0xaf, 0x32, 0x6c, 0x63, 0x74, 0xd3, 0x12,
0x87, 0x6e, 0xd0, 0x7e, 0x66, 0x9e, 0x5c, 0x17, 0xc8, 0xd0, 0x09, 0xf7,
0x80, 0x35, 0xc9, 0xc8, 0x42, 0xb1, 0x4c, 0xcf, 0xfa, 0xd4, 0x91, 0x52,
0x99, 0x35, 0x3b, 0x8e, 0x3f, 0x42, 0x38, 0x38, 0x1d, 0xec, 0x99, 0xf8,
0xdd, 0xa5, 0x84, 0x7b, 0xd9, 0x72, 0xfe, 0x80, 0xb7, 0x4c, 0xc5, 0x9a,
0xde, 0xa0, 0xdd, 0x97, 0xbe, 0x26, 0x79, 0xfd, 0x9b, 0xa2, 0x59, 0x5d,
0x77, 0x3a, 0x93, 0x14, 0x92, 0x0e, 0xce, 0x8d, 0x58, 0x45, 0xfc, 0x33,
0x7f, 0x7b, 0x5b, 0x99, 0x5c, 0x4b, 0xa2, 0x10, 0x2d, 0xea, 0xd4, 0x14,
0xbd, 0x6e, 0x4a, 0xdd, 0xca, 0x40, 0x29, 0x11, 0x57, 0xc9, 0xa8, 0x2f,
0xbf, 0x8d, 0xb0, 0x31, 0x77, 0x6f, 0x8b, 0x02, 0x81, 0x81, 0x00, 0x87,
0xe5, 0x41, 0xe0, 0x0b, 0x7e, 0x4f, 0x9a, 0xd2, 0x07, 0x27, 0xcc, 0x39,
0xa1, 0xc6, 0x8a, 0x45, 0x5f, 0xfa, 0x3b, 0x30, 0xfc, 0x28, 0x54, 0xb3,
0x78, 0x5f, 0xd6, 0xc4, 0x2b, 0x52, 0x60, 0xff, 0xe9, 0x32, 0xc4, 0x01,
0x0a, 0x67, 0x89, 0xac, 0x53, 0x5b, 0x08, 0x8f, 0xca, 0x69, 0x28, 0x01,
0xbd, 0xf2, 0x7c, 0xbc, 0x5a, 0xef, 0x79, 0x40, 0x20, 0xc4, 0x1f, 0x4c,
0x31, 0xa4, 0xe3, 0xd0, 0x20, 0xdc, 0xa4, 0x8b, 0x66, 0x55, 0xd7, 0x32,
0xe0, 0x47, 0x8d, 0x12, 0x0c, 0x83, 0xab, 0xe3, 0xd7, 0xef, 0x95, 0xc8,
0xa3, 0x00, 0xf5, 0xf0, 0x02, 0xaa, 0x31, 0x89, 0x72, 0xef, 0xa1, 0xdb,
0x4d, 0xfd, 0x32, 0x10, 0xf9, 0x3a, 0x6a, 0xcf, 0x1d, 0x7b, 0x20, 0x6f,
0xbb, 0xd6, 0xfc, 0x07, 0x0b, 0x71, 0x15, 0x83, 0x3a, 0xd6, 0x74, 0x5e,
0xb8, 0xc3, 0xd5, 0x41, 0x41, 0x42, 0x13, 0x02, 0x81, 0x80, 0x5a, 0x9c,
0xcb, 0xe4, 0x37, 0xbe, 0xa5, 0x0a, 0xc3, 0x5f, 0x6d, 0x83, 0x46, 0xfa,
0x7c, 0xc8, 0x46, 0x0a, 0xb1, 0x86, 0x80, 0xe6, 0x4c, 0x77, 0x50, 0x0c,
0x11, 0x5c, 0x0d, 0xa3, 0x53, 0x25, 0xf1, 0x2c, 0xe1, 0x15, 0xe0, 0x18,
0x9d, 0x30, 0xb7, 0xea, 0xfa, 0x2f, 0x4b, 0x55, 0x30, 0x51, 0xee, 0x19,
0x50, 0xb7, 0x16, 0x5f, 0x1b, 0x7e, 0xd3, 0xb1, 0x82, 0x60, 0xe1, 0x7e,
0x64, 0xa0, 0x19, 0xf8, 0xa4, 0xee, 0xd2, 0x42, 0x20, 0x6b, 0x17, 0x99,
0xfa, 0xa9, 0x15, 0xc0, 0x51, 0x8c, 0xe6, 0x09, 0x60, 0x21, 0x0a, 0xda,
0xe5, 0xc8, 0x1f, 0x13, 0xcd, 0x52, 0xc3, 0xb9, 0xb9, 0x75, 0x9f, 0x98,
0xc8, 0x71, 0xd1, 0x7f, 0x2e, 0x4f, 0x3d, 0xc8, 0xe8, 0xad, 0x6a, 0xd2,
0x7a, 0x2a, 0x46, 0xef, 0x0f, 0xda, 0x74, 0x37, 0x1d, 0x74, 0xb4, 0x23,
0xf7, 0xfe, 0xf2, 0xdf, 0xfb, 0xb5, 0x02, 0x81, 0x81, 0x00, 0xc3, 0x5a,
0x06, 0xad, 0x8a, 0xed, 0xdf, 0x11, 0xda, 0x20, 0x8b, 0x47, 0x82, 0x5e,
0xe4, 0x01, 0x9b, 0x52, 0x9c, 0x7b, 0x30, 0x04, 0x7f, 0x48, 0xce, 0xaf,
0x46, 0x81, 0xa3, 0x07, 0xe8, 0xcc, 0x8a, 0x97, 0x9f, 0x1f, 0x10, 0xe2,
0xf9, 0xf7, 0x66, 0x90, 0x1d, 0xd4, 0x82, 0x45, 0x1f, 0x32, 0x3b, 0xc1,
0x7c, 0xc1, 0xfb, 0x74, 0x4e, 0x64, 0xab, 0xe0, 0xd0, 0x17, 0x99, 0xfc,
0xc4, 0x24, 0xd3, 0xca, 0xae, 0x0a, 0x20, 0xa3, 0xa3, 0x9c, 0x05, 0x45,
0xb3, 0x64, 0x75, 0x94, 0xa4, 0x99, 0x3a, 0x43, 0xbd, 0x98, 0x58, 0xdb,
0x06, 0xec, 0x6d, 0xa7, 0x55, 0xd7, 0x6e, 0x29, 0xe2, 0x93, 0xdb, 0xd9,
0x52, 0x71, 0x50, 0xdb, 0x87, 0xb2, 0x5b, 0x86, 0x7e, 0x20, 0x74, 0x39,
0x45, 0x81, 0xba, 0x94, 0x27, 0x6a, 0x11, 0x67, 0xaa, 0xff, 0x5b, 0xcd,
0xec, 0x5f, 0x7a, 0x5b, 0xfe, 0x10
};
#define CLIENT_CERT_AUTH_DER_LENGTH 1030
UA_Byte CLIENT_CERT_AUTH_DER_DATA[CLIENT_CERT_AUTH_DER_LENGTH] = {
0x30, 0x82, 0x04, 0x02, 0x30, 0x82, 0x02, 0xea, 0xa0, 0x03, 0x02, 0x01,
0x02, 0x02, 0x14, 0x02, 0x99, 0xb0, 0x8f, 0x9a, 0x61, 0x96, 0x15, 0xe9,
0x76, 0xaf, 0x5a, 0x88, 0x61, 0x65, 0x32, 0xa9, 0xff, 0x94, 0x3f, 0x30,
0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b,
0x05, 0x00, 0x30, 0x54, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04,
0x06, 0x13, 0x02, 0x44, 0x45, 0x31, 0x0d, 0x30, 0x0b, 0x06, 0x03, 0x55,
0x04, 0x07, 0x0c, 0x04, 0x48, 0x65, 0x72, 0x65, 0x31, 0x12, 0x30, 0x10,
0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x09, 0x6f, 0x70, 0x65, 0x6e, 0x36,
0x32, 0x35, 0x34, 0x31, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04,
0x03, 0x0c, 0x19, 0x6f, 0x70, 0x65, 0x6e, 0x36, 0x32, 0x35, 0x34, 0x31,
0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x40, 0x6c, 0x6f, 0x63, 0x61, 0x6c,
0x68, 0x6f, 0x73, 0x74, 0x30, 0x1e, 0x17, 0x0d, 0x32, 0x33, 0x31, 0x31,
0x30, 0x38, 0x31, 0x35, 0x31, 0x39, 0x30, 0x33, 0x5a, 0x17, 0x0d, 0x33,
0x33, 0x31, 0x31, 0x30, 0x35, 0x31, 0x35, 0x31, 0x39, 0x30, 0x33, 0x5a,
0x30, 0x54, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
0x02, 0x44, 0x45, 0x31, 0x0d, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x04, 0x07,
0x0c, 0x04, 0x48, 0x65, 0x72, 0x65, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03,
0x55, 0x04, 0x0a, 0x0c, 0x09, 0x6f, 0x70, 0x65, 0x6e, 0x36, 0x32, 0x35,
0x34, 0x31, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c,
0x19, 0x6f, 0x70, 0x65, 0x6e, 0x36, 0x32, 0x35, 0x34, 0x31, 0x53, 0x65,
0x72, 0x76, 0x65, 0x72, 0x40, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f,
0x73, 0x74, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01,
0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xdb,
0xb4, 0xe3, 0xe6, 0xd3, 0x93, 0x25, 0xe5, 0x7c, 0xe2, 0x64, 0x78, 0xa7,
0x88, 0x5b, 0x63, 0x6c, 0x4f, 0x18, 0x10, 0x41, 0x1f, 0x4c, 0x35, 0xeb,
0x3c, 0x33, 0x3b, 0x40, 0x18, 0x79, 0x30, 0x99, 0x3c, 0x7a, 0x9e, 0xd7,
0xbe, 0x2e, 0x77, 0xba, 0x2b, 0x0f, 0x05, 0xb1, 0xec, 0xea, 0x55, 0xbe,
0x4e, 0xce, 0x9a, 0x64, 0xc4, 0xde, 0x5b, 0x25, 0x38, 0x45, 0x7f, 0x49,
0xa5, 0xf3, 0x8c, 0x5a, 0xb9, 0xa6, 0xf2, 0x1d, 0xf4, 0x83, 0x5d, 0xba,
0x44, 0x6b, 0x13, 0x16, 0xbb, 0xf9, 0x20, 0x7e, 0x97, 0xfc, 0xb5, 0xfa,
0x3a, 0x9c, 0x56, 0xc3, 0xaa, 0x27, 0xc1, 0x15, 0xa2, 0x80, 0xd5, 0xb4,
0x62, 0xe0, 0x5b, 0xe8, 0x4e, 0x38, 0xde, 0x2a, 0xc8, 0x2e, 0x27, 0x2f,
0x3c, 0x0e, 0x6f, 0x31, 0xe0, 0xc7, 0x1b, 0x60, 0x83, 0xc1, 0xe8, 0xf3,
0x71, 0x6d, 0x42, 0xc2, 0xf2, 0x57, 0x32, 0xdb, 0xd8, 0x2f, 0xf2, 0xdc,
0x8f, 0x6b, 0x5f, 0xb4, 0x1f, 0xac, 0x02, 0xa9, 0x6e, 0xa8, 0x71, 0xf8,
0x85, 0x01, 0x85, 0x52, 0x2a, 0x83, 0x18, 0xf8, 0xc4, 0x43, 0x46, 0xda,
0xc2, 0xc2, 0xc2, 0xc8, 0xdc, 0x8f, 0x2a, 0xe2, 0xc5, 0xe7, 0xe0, 0x5d,
0x9a, 0xdb, 0xb4, 0x48, 0x69, 0x22, 0xd9, 0xdb, 0x71, 0x65, 0xcd, 0x57,
0x06, 0xf8, 0x2e, 0x29, 0x5a, 0xee, 0x22, 0x9d, 0xce, 0x68, 0xe5, 0xcf,
0x07, 0x27, 0x99, 0xca, 0x80, 0x15, 0xf0, 0xdf, 0x72, 0x04, 0xa3, 0x8e,
0xee, 0xae, 0x28, 0x27, 0x4e, 0xb0, 0x08, 0x38, 0x3c, 0x55, 0x8e, 0xea,
0x52, 0x36, 0xb2, 0xfc, 0x27, 0x5d, 0xfb, 0x42, 0xb6, 0x2e, 0x89, 0xda,
0x86, 0x7d, 0x2a, 0xe2, 0x3f, 0x93, 0x3a, 0x38, 0xda, 0xd1, 0xc7, 0x8a,
0x9b, 0xfc, 0x6f, 0x9c, 0x76, 0xd2, 0x00, 0x0c, 0x26, 0x72, 0x74, 0x0f,
0x29, 0xfd, 0xeb, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x81, 0xcb, 0x30,
0x81, 0xc8, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04,
0x14, 0x05, 0x79, 0x6d, 0x2e, 0x93, 0xaf, 0x23, 0x28, 0xd1, 0xcd, 0xe3,
0xe6, 0xd8, 0x33, 0x08, 0x97, 0x32, 0x41, 0xb4, 0xe8, 0x30, 0x1f, 0x06,
0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x05, 0x79,
0x6d, 0x2e, 0x93, 0xaf, 0x23, 0x28, 0xd1, 0xcd, 0xe3, 0xe6, 0xd8, 0x33,
0x08, 0x97, 0x32, 0x41, 0xb4, 0xe8, 0x30, 0x09, 0x06, 0x03, 0x55, 0x1d,
0x13, 0x04, 0x02, 0x30, 0x00, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x1d, 0x0f,
0x04, 0x04, 0x03, 0x02, 0x02, 0xf4, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d,
0x25, 0x04, 0x16, 0x30, 0x14, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05,
0x07, 0x03, 0x01, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03,
0x02, 0x30, 0x4f, 0x06, 0x03, 0x55, 0x1d, 0x11, 0x04, 0x48, 0x30, 0x46,
0x82, 0x0a, 0x76, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x62, 0x6f, 0x78,
0x82, 0x0a, 0x76, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x62, 0x6f, 0x78,
0x87, 0x04, 0x0a, 0x00, 0x02, 0x0f, 0x87, 0x04, 0xc0, 0xa8, 0x38, 0x65,
0x86, 0x20, 0x75, 0x72, 0x6e, 0x3a, 0x6f, 0x70, 0x65, 0x6e, 0x36, 0x32,
0x35, 0x34, 0x31, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x61,
0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x30, 0x0d,
0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05,
0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x32, 0x5d, 0x3f, 0xcf, 0x97, 0x58,
0x8e, 0x18, 0x1f, 0xeb, 0xbe, 0x11, 0xb4, 0xae, 0x8a, 0x7f, 0x44, 0xc2,
0xd2, 0x69, 0xa9, 0x93, 0x51, 0x41, 0x69, 0x1f, 0xbe, 0x01, 0x5c, 0x69,
0x13, 0xbf, 0xf6, 0xde, 0x48, 0xb8, 0xea, 0xbd, 0x28, 0x5d, 0x7f, 0x5c,
0x02, 0x8d, 0x77, 0x11, 0x27, 0x7b, 0xeb, 0x2b, 0x8b, 0xd6, 0x9b, 0xa4,
0xa5, 0x83, 0x11, 0x89, 0x41, 0x64, 0x00, 0x6b, 0x32, 0x6d, 0xa4, 0xf1,
0xde, 0xac, 0xad, 0x66, 0x87, 0x43, 0x84, 0x96, 0x31, 0xe5, 0x16, 0x50,
0x76, 0xad, 0xed, 0xf8, 0xe4, 0xdf, 0xc9, 0x20, 0xa4, 0xc1, 0xf2, 0xd0,
0x40, 0x47, 0x9c, 0xb9, 0x6f, 0x8d, 0xf3, 0xb7, 0x17, 0x39, 0xbc, 0x69,
0x99, 0x0f, 0xf6, 0x19, 0xf5, 0xdd, 0xca, 0x94, 0xe0, 0x71, 0x4b, 0x94,
0x35, 0x53, 0x2f, 0xf1, 0xcf, 0x62, 0x45, 0x91, 0x36, 0x4b, 0xb6, 0xdf,
0x91, 0xb7, 0x37, 0x44, 0x01, 0x95, 0xf2, 0xc7, 0x44, 0x8f, 0x98, 0x4a,
0x04, 0x41, 0x7a, 0x1b, 0x28, 0x74, 0x3e, 0xbc, 0x56, 0x49, 0x8e, 0x94,
0xdf, 0x6f, 0xee, 0x52, 0xaa, 0x99, 0xe2, 0x15, 0xa9, 0xa8, 0xe1, 0x3e,
0x32, 0x3a, 0xf8, 0x3f, 0x0a, 0x76, 0x85, 0x45, 0x2e, 0x8d, 0x4d, 0xed,
0xc5, 0xdb, 0xe1, 0xf8, 0x79, 0x5d, 0xc1, 0xef, 0x13, 0x8a, 0x5f, 0x18,
0x30, 0xc6, 0x88, 0xef, 0x6d, 0x66, 0x27, 0x5b, 0x00, 0x99, 0xb0, 0x6e,
0xc8, 0x29, 0x8a, 0x90, 0xdd, 0x55, 0x48, 0x66, 0x14, 0xbb, 0xda, 0x02,
0x1f, 0x36, 0x54, 0x11, 0xa0, 0x21, 0x26, 0xc1, 0x54, 0xd3, 0xbd, 0x16,
0xba, 0xa6, 0x72, 0x56, 0xcd, 0x4e, 0x5e, 0xd1, 0x30, 0x25, 0xe7, 0xea,
0x93, 0x13, 0x63, 0x33, 0x1e, 0x39, 0x5a, 0x3b, 0x95, 0xdf, 0x6c, 0x84,
0x8f, 0x1d, 0xe0, 0x9f, 0xcf, 0xc6, 0xab, 0x7c, 0x55, 0xb5
};
#define CLIENT_KEY_AUTH_DER_LENGTH 1218
UA_Byte CLIENT_KEY_AUTH_DER_DATA[CLIENT_KEY_AUTH_DER_LENGTH] = {
0x30, 0x82, 0x04, 0xbe, 0x02, 0x01, 0x00, 0x30, 0x0d, 0x06, 0x09, 0x2a,
0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82,
0x04, 0xa8, 0x30, 0x82, 0x04, 0xa4, 0x02, 0x01, 0x00, 0x02, 0x82, 0x01,
0x01, 0x00, 0xdb, 0xb4, 0xe3, 0xe6, 0xd3, 0x93, 0x25, 0xe5, 0x7c, 0xe2,
0x64, 0x78, 0xa7, 0x88, 0x5b, 0x63, 0x6c, 0x4f, 0x18, 0x10, 0x41, 0x1f,
0x4c, 0x35, 0xeb, 0x3c, 0x33, 0x3b, 0x40, 0x18, 0x79, 0x30, 0x99, 0x3c,
0x7a, 0x9e, 0xd7, 0xbe, 0x2e, 0x77, 0xba, 0x2b, 0x0f, 0x05, 0xb1, 0xec,
0xea, 0x55, 0xbe, 0x4e, 0xce, 0x9a, 0x64, 0xc4, 0xde, 0x5b, 0x25, 0x38,
0x45, 0x7f, 0x49, 0xa5, 0xf3, 0x8c, 0x5a, 0xb9, 0xa6, 0xf2, 0x1d, 0xf4,
0x83, 0x5d, 0xba, 0x44, 0x6b, 0x13, 0x16, 0xbb, 0xf9, 0x20, 0x7e, 0x97,
0xfc, 0xb5, 0xfa, 0x3a, 0x9c, 0x56, 0xc3, 0xaa, 0x27, 0xc1, 0x15, 0xa2,
0x80, 0xd5, 0xb4, 0x62, 0xe0, 0x5b, 0xe8, 0x4e, 0x38, 0xde, 0x2a, 0xc8,
0x2e, 0x27, 0x2f, 0x3c, 0x0e, 0x6f, 0x31, 0xe0, 0xc7, 0x1b, 0x60, 0x83,
0xc1, 0xe8, 0xf3, 0x71, 0x6d, 0x42, 0xc2, 0xf2, 0x57, 0x32, 0xdb, 0xd8,
0x2f, 0xf2, 0xdc, 0x8f, 0x6b, 0x5f, 0xb4, 0x1f, 0xac, 0x02, 0xa9, 0x6e,
0xa8, 0x71, 0xf8, 0x85, 0x01, 0x85, 0x52, 0x2a, 0x83, 0x18, 0xf8, 0xc4,
0x43, 0x46, 0xda, 0xc2, 0xc2, 0xc2, 0xc8, 0xdc, 0x8f, 0x2a, 0xe2, 0xc5,
0xe7, 0xe0, 0x5d, 0x9a, 0xdb, 0xb4, 0x48, 0x69, 0x22, 0xd9, 0xdb, 0x71,
0x65, 0xcd, 0x57, 0x06, 0xf8, 0x2e, 0x29, 0x5a, 0xee, 0x22, 0x9d, 0xce,
0x68, 0xe5, 0xcf, 0x07, 0x27, 0x99, 0xca, 0x80, 0x15, 0xf0, 0xdf, 0x72,
0x04, 0xa3, 0x8e, 0xee, 0xae, 0x28, 0x27, 0x4e, 0xb0, 0x08, 0x38, 0x3c,
0x55, 0x8e, 0xea, 0x52, 0x36, 0xb2, 0xfc, 0x27, 0x5d, 0xfb, 0x42, 0xb6,
0x2e, 0x89, 0xda, 0x86, 0x7d, 0x2a, 0xe2, 0x3f, 0x93, 0x3a, 0x38, 0xda,
0xd1, 0xc7, 0x8a, 0x9b, 0xfc, 0x6f, 0x9c, 0x76, 0xd2, 0x00, 0x0c, 0x26,
0x72, 0x74, 0x0f, 0x29, 0xfd, 0xeb, 0x02, 0x03, 0x01, 0x00, 0x01, 0x02,
0x82, 0x01, 0x00, 0x04, 0x20, 0xe4, 0x8d, 0x70, 0x59, 0x5a, 0x03, 0x73,
0x72, 0xcf, 0x9f, 0x82, 0xca, 0x69, 0xa9, 0x37, 0x1e, 0x4f, 0x5d, 0xf2,
0xd3, 0x53, 0x3b, 0xca, 0x25, 0x51, 0xf3, 0x21, 0x93, 0xb4, 0x27, 0x49,
0x21, 0xdd, 0x4e, 0x01, 0xd0, 0xd5, 0x8f, 0xb3, 0x64, 0x5e, 0xbe, 0x65,
0x27, 0x06, 0x0a, 0x41, 0x6e, 0xba, 0xac, 0x25, 0x0b, 0x9c, 0x00, 0x0b,
0x75, 0x80, 0xbc, 0xd1, 0x15, 0xf8, 0xbb, 0x20, 0xf3, 0x4f, 0x23, 0x4a,
0x93, 0xcf, 0x2a, 0x22, 0x37, 0x69, 0xe9, 0xac, 0x6a, 0x30, 0xd6, 0xbe,
0xfa, 0x3d, 0x29, 0xf0, 0x3f, 0x4c, 0xb3, 0xc6, 0xae, 0x7a, 0x5b, 0xc2,
0xfb, 0xd0, 0x3e, 0xf3, 0xca, 0x4d, 0xdb, 0xfc, 0x44, 0x08, 0x06, 0x88,
0xb8, 0x45, 0x41, 0xc0, 0x3d, 0xf9, 0x29, 0x76, 0xbe, 0xfa, 0x0e, 0xd6,
0x23, 0xf3, 0xaf, 0x5c, 0x6f, 0xbb, 0xb5, 0x5e, 0xf3, 0x6d, 0xd7, 0x02,
0x65, 0x40, 0x92, 0xbb, 0x1c, 0xf4, 0x3f, 0x71, 0xfd, 0x07, 0x83, 0xac,
0xf5, 0x98, 0xa3, 0x26, 0x79, 0x87, 0xd9, 0xdc, 0x6c, 0x87, 0x11, 0xca,
0xb2, 0x23, 0xaa, 0xe6, 0xc3, 0x9f, 0x2b, 0x6b, 0x60, 0x5b, 0x27, 0xbd,
0xc5, 0xd4, 0x71, 0x52, 0xca, 0x28, 0xe2, 0xd3, 0xe0, 0xe2, 0xae, 0x96,
0x45, 0x67, 0xaa, 0x16, 0x42, 0x46, 0xe6, 0x9e, 0x93, 0x35, 0x30, 0x61,
0x5c, 0xdb, 0x9b, 0x4a, 0x3c, 0x8f, 0x82, 0x2c, 0xc0, 0x36, 0x1b, 0x5d,
0x76, 0x5e, 0x3c, 0xc2, 0x99, 0x8a, 0x5e, 0x00, 0x84, 0xce, 0xec, 0x90,
0xc7, 0xeb, 0xac, 0xd4, 0xe6, 0xb9, 0x7a, 0x3a, 0x6f, 0xad, 0x83, 0xed,
0x4e, 0x7a, 0x3b, 0x51, 0xa6, 0x3c, 0xaa, 0xc3, 0x98, 0xac, 0xbb, 0x24,
0x8c, 0x47, 0xaf, 0xf6, 0xc0, 0x96, 0xd2, 0x51, 0xc4, 0xa1, 0xef, 0x40,
0xf7, 0xbd, 0x31, 0x3d, 0x4c, 0xa6, 0xe1, 0x02, 0x81, 0x81, 0x00, 0xf8,
0xb0, 0x9f, 0x21, 0x0e, 0xc4, 0xef, 0x4a, 0x93, 0x5d, 0xc9, 0x5b, 0x6c,
0x0d, 0x7e, 0x2d, 0x08, 0x2d, 0xf1, 0xfc, 0x48, 0x7b, 0x25, 0x37, 0xb7,
0x84, 0xea, 0x0b, 0x8a, 0xd8, 0x4f, 0xff, 0xd2, 0x05, 0x1f, 0x0d, 0xc7,
0x8b, 0x6d, 0x7c, 0x85, 0xa7, 0x41, 0xb9, 0x9b, 0x58, 0xc4, 0xa5, 0xdf,
0x9a, 0xc8, 0x3d, 0xef, 0x76, 0x12, 0xfa, 0xe0, 0xda, 0x4e, 0x82, 0xc2,
0xa3, 0x1f, 0xc5, 0x58, 0x29, 0x14, 0xaa, 0x00, 0xb8, 0x59, 0x40, 0x8e,
0xac, 0x88, 0x0c, 0x1d, 0x8b, 0xa4, 0x0b, 0xb1, 0x16, 0xc8, 0x69, 0xf3,
0xaa, 0x55, 0xd9, 0x4b, 0x27, 0x5b, 0x3a, 0xb4, 0xc6, 0x7d, 0xeb, 0x28,
0xd6, 0xe7, 0xf0, 0x94, 0x41, 0x17, 0x25, 0x81, 0x6e, 0x44, 0x1c, 0x92,
0x0d, 0x18, 0x41, 0xf9, 0xac, 0xac, 0xe9, 0xae, 0xb4, 0xd7, 0xcd, 0x10,
0xdd, 0x17, 0xec, 0x93, 0x16, 0x12, 0xa1, 0x02, 0x81, 0x81, 0x00, 0xe2,
0x2a, 0x2b, 0xb0, 0xeb, 0xaf, 0xcd, 0x2c, 0xe1, 0x76, 0xd7, 0x62, 0xa5,
0x5d, 0x81, 0xd6, 0x88, 0x77, 0xd6, 0x64, 0x4a, 0x5b, 0x98, 0x04, 0xd9,
0xbd, 0x3f, 0x07, 0xe0, 0x7d, 0x39, 0x11, 0x38, 0x5e, 0x8d, 0x17, 0x9c,
0xd3, 0x1e, 0x5f, 0x6e, 0x0a, 0xbe, 0x41, 0x9c, 0x63, 0xb6, 0xc3, 0xa2,
0xde, 0x6c, 0x9b, 0x5f, 0x97, 0x4e, 0x68, 0x4b, 0xf7, 0xe3, 0xca, 0x25,
0xf4, 0x84, 0x3c, 0xaa, 0x09, 0x42, 0xe8, 0x40, 0x30, 0x89, 0x53, 0xcb,
0xc9, 0x2f, 0xdb, 0xc3, 0xa4, 0xbc, 0x40, 0xa7, 0xf0, 0xb8, 0x0a, 0x6c,
0xcc, 0x1c, 0x08, 0x3c, 0x9f, 0x4b, 0x1b, 0xff, 0xe3, 0x6e, 0x8a, 0x5e,
0x98, 0x61, 0xc4, 0xd9, 0x6f, 0xa2, 0xb8, 0x83, 0x56, 0x7d, 0x68, 0x03,
0x6d, 0xbd, 0xa0, 0xea, 0x1a, 0x53, 0x63, 0x4c, 0x74, 0x9a, 0xe9, 0x4f,
0x45, 0x29, 0xae, 0xc6, 0x6a, 0x91, 0x0b, 0x02, 0x81, 0x80, 0x1f, 0xeb,
0xab, 0xc1, 0x36, 0x80, 0x18, 0xa6, 0xdd, 0xdb, 0x7f, 0xe8, 0xf8, 0x29,
0x93, 0x34, 0x7c, 0x84, 0x49, 0x37, 0x34, 0xa6, 0x79, 0xd4, 0x78, 0xfd,
0xda, 0x7c, 0xb8, 0xc9, 0xa3, 0x1b, 0x16, 0xfe, 0x09, 0x4a, 0x5f, 0x7e,
0x8a, 0x03, 0x1d, 0xb4, 0xa6, 0x3f, 0x08, 0xad, 0x90, 0x30, 0x2a, 0x4f,
0x57, 0xbc, 0x7b, 0x6c, 0x10, 0x6b, 0x9b, 0x48, 0xea, 0x22, 0xe6, 0x90,
0xc1, 0x97, 0x37, 0x05, 0xae, 0xdd, 0x53, 0x52, 0x56, 0x42, 0x6f, 0x0d,
0xbe, 0x38, 0xaf, 0xe2, 0x28, 0xa0, 0x47, 0x8e, 0xc1, 0x12, 0xb8, 0x6f,
0xf8, 0xac, 0xf7, 0x74, 0x89, 0xc5, 0x33, 0x46, 0xf7, 0x0a, 0xa4, 0x27,
0x51, 0x86, 0x13, 0xc1, 0x77, 0x13, 0x1d, 0x55, 0xe5, 0xf0, 0x34, 0xde,
0xf1, 0x6a, 0x26, 0x7d, 0xff, 0x83, 0xcf, 0x24, 0xef, 0x3e, 0x27, 0x17,
0xf9, 0xe6, 0x27, 0xcb, 0x01, 0x81, 0x02, 0x81, 0x81, 0x00, 0xb8, 0x19,
0xe3, 0xde, 0xec, 0xbb, 0xfa, 0xa4, 0xa2, 0x13, 0xff, 0x58, 0x49, 0x8c,
0x48, 0x78, 0xbe, 0x35, 0xee, 0xcb, 0x4c, 0xcc, 0x2a, 0x7f, 0x28, 0x4f,
0xa8, 0xd3, 0x5c, 0xa6, 0x12, 0xa2, 0x35, 0xe4, 0xa1, 0xad, 0xaa, 0xf7,
0x20, 0x2e, 0x46, 0x81, 0x70, 0x46, 0x30, 0x6b, 0xeb, 0x06, 0x6d, 0xb9,
0xe9, 0x66, 0xc0, 0xf5, 0x85, 0xd9, 0xd8, 0x9d, 0x3d, 0x4b, 0xfc, 0x81,
0x82, 0x73, 0x6f, 0x66, 0x82, 0x94, 0x54, 0x4c, 0x2e, 0x3d, 0x8c, 0x11,
0x85, 0x67, 0xbb, 0x66, 0x89, 0xe7, 0x87, 0xcd, 0xa7, 0xc2, 0xb4, 0xb5,
0xa1, 0xcc, 0x02, 0xad, 0x18, 0x92, 0xfe, 0x45, 0xc0, 0x61, 0xda, 0x86,
0xe8, 0x6f, 0x39, 0x20, 0x6a, 0xb1, 0x10, 0x18, 0x83, 0x94, 0xfb, 0xd5,
0x85, 0x1b, 0x4b, 0xf5, 0x8a, 0x13, 0xb6, 0xd4, 0xe4, 0x95, 0x2e, 0xf5,
0xf9, 0xec, 0x4f, 0x8f, 0xc7, 0xe9, 0x02, 0x81, 0x81, 0x00, 0x93, 0xc0,
0x5d, 0x4e, 0x69, 0x53, 0x1f, 0xd8, 0x8d, 0x5f, 0xeb, 0xa3, 0x3e, 0xdc,
0x56, 0x9f, 0x98, 0x98, 0xb4, 0xdd, 0x36, 0x37, 0xea, 0xfc, 0xaa, 0xbd,
0x88, 0xce, 0x23, 0x37, 0x44, 0xf1, 0x5e, 0xb1, 0x02, 0xf2, 0xed, 0xe6,
0xcb, 0x8f, 0x17, 0x23, 0xad, 0x49, 0x3e, 0xb2, 0x28, 0x56, 0xbc, 0x08,
0x93, 0x89, 0xe7, 0x1e, 0xf2, 0xb6, 0xf7, 0x61, 0x94, 0x48, 0xa0, 0x2d,
0x8c, 0x34, 0xbb, 0xbc, 0x9f, 0x35, 0xa9, 0x3d, 0xc6, 0xd1, 0x8a, 0xcc,
0x7b, 0xd4, 0x96, 0x4a, 0x1c, 0x39, 0xd5, 0x45, 0x0b, 0xb3, 0xc3, 0xbc,
0xa3, 0xc5, 0x36, 0xce, 0x2f, 0x79, 0x3a, 0x65, 0xf3, 0x5b, 0x89, 0x18,
0x29, 0xc3, 0xd0, 0x7c, 0xcf, 0x9e, 0x4b, 0x2e, 0x0a, 0x62, 0x00, 0x4a,
0x3c, 0xf1, 0x3e, 0xe1, 0xb8, 0x71, 0x37, 0x87, 0x6c, 0xc2, 0x14, 0x63,
0x23, 0x24, 0xd7, 0x6e, 0x8b, 0x3c
};
_UA_END_DECLS
#endif //OPEN62541_CERTIFICATES_H

View File

@@ -0,0 +1,503 @@
/* 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/. */
#include <open62541/client.h>
#include <open62541/client_highlevel.h>
#include <open62541/client_subscriptions.h>
#include <open62541/client_config_default.h>
#include <open62541/server.h>
#include <open62541/server_config_default.h>
#include <open62541/plugin/accesscontrol_default.h>
#include "client/ua_client_internal.h"
#include "ua_server_internal.h"
#include <check.h>
#include <stdlib.h>
#include "testing_clock.h"
#include "thread_wrapper.h"
UA_Server *server;
UA_Boolean running;
THREAD_HANDLE server_thread;
static void
addVariable(size_t size) {
/* Define the attribute of the myInteger variable node */
UA_VariableAttributes attr = UA_VariableAttributes_default;
UA_Int32* array = (UA_Int32*)UA_malloc(size * sizeof(UA_Int32));
for(size_t i = 0; i < size; i++)
array[i] = (UA_Int32)i;
UA_Variant_setArray(&attr.value, array, size, &UA_TYPES[UA_TYPES_INT32]);
char name[] = "my.variable";
attr.description = UA_LOCALIZEDTEXT("en-US", name);
attr.displayName = UA_LOCALIZEDTEXT("en-US", name);
attr.dataType = UA_TYPES[UA_TYPES_INT32].typeId;
/* Add the variable node to the information model */
UA_NodeId myIntegerNodeId = UA_NODEID_STRING(1, name);
UA_QualifiedName myIntegerName = UA_QUALIFIEDNAME(1, name);
UA_NodeId parentNodeId = UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER);
UA_NodeId parentReferenceNodeId = UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES);
UA_Server_addVariableNode(server, myIntegerNodeId, parentNodeId,
parentReferenceNodeId, myIntegerName,
UA_NODEID_NUMERIC(0, UA_NS0ID_BASEDATAVARIABLETYPE),
attr, NULL, NULL);
/* add displayname to variable */
UA_Server_writeDisplayName(server, myIntegerNodeId,
UA_LOCALIZEDTEXT("de", "meine.Variable"));
UA_free(array);
}
THREAD_CALLBACK(serverloop) {
while(running)
UA_Server_run_iterate(server, true);
return 0;
}
#define VARLENGTH 16366
static const size_t usernamePasswordsSize = 2;
static UA_UsernamePasswordLogin usernamePasswords[2] = {
{UA_STRING_STATIC("user1"), UA_STRING_STATIC("password")},
{UA_STRING_STATIC("user2"), UA_STRING_STATIC("password1")}};
static void setup(void) {
running = true;
server = UA_Server_new();
ck_assert(server != NULL);
UA_ServerConfig *config = UA_Server_getConfig(server);
UA_SecurityPolicy *sp = &config->securityPolicies[config->securityPoliciesSize-1];
UA_AccessControl_default(config, true, &sp->policyUri,
usernamePasswordsSize, usernamePasswords);
UA_Server_run_startup(server);
addVariable(VARLENGTH);
THREAD_CREATE(server_thread, serverloop);
}
static void teardown(void) {
running = false;
THREAD_JOIN(server_thread);
UA_Server_run_shutdown(server);
UA_Server_delete(server);
}
static void clearLocale(UA_ClientConfig *config) {
if(config->sessionLocaleIdsSize > 0 && config->sessionLocaleIds) {
UA_Array_delete(config->sessionLocaleIds,
config->sessionLocaleIdsSize, &UA_TYPES[UA_TYPES_LOCALEID]);
}
config->sessionLocaleIds = NULL;
config->sessionLocaleIdsSize = 0;
}
static void changeLocale(UA_Client *client) {
UA_LocalizedText loc;
UA_ClientConfig *config = UA_Client_getConfig(client);
clearLocale(config);
config->sessionLocaleIdsSize = 2;
config->sessionLocaleIds = (UA_LocaleId *)UA_Array_new(2, &UA_TYPES[UA_TYPES_LOCALEID]);
config->sessionLocaleIds[0] = UA_STRING_ALLOC("en-US");
config->sessionLocaleIds[1] = UA_STRING_ALLOC("de");
UA_StatusCode retval = UA_Client_activateCurrentSession(client);
ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD);
const UA_NodeId nodeIdString = UA_NODEID_STRING(1, "my.variable");
retval = UA_Client_readDisplayNameAttribute(client, nodeIdString, &loc);
ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD);
UA_LocalizedText newLocaleEng = UA_LOCALIZEDTEXT("en-US", "my.variable");
ck_assert(UA_String_equal(&newLocaleEng.locale, &loc.locale));
ck_assert(UA_String_equal(&newLocaleEng.text, &loc.text));
UA_LocalizedText_clear(&loc);
clearLocale(config);
config->sessionLocaleIdsSize = 2;
config->sessionLocaleIds = (UA_LocaleId *)UA_Array_new(2, &UA_TYPES[UA_TYPES_LOCALEID]);
config->sessionLocaleIds[0] = UA_STRING_ALLOC("de");
config->sessionLocaleIds[1] = UA_STRING_ALLOC("en-US");
retval = UA_Client_activateCurrentSession(client);
ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD);
retval = UA_Client_readDisplayNameAttribute(client, nodeIdString, &loc);
ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD);
UA_LocalizedText newLocaleGerm = UA_LOCALIZEDTEXT("de", "meine.Variable");
ck_assert(UA_String_equal(&newLocaleGerm.locale, &loc.locale));
ck_assert(UA_String_equal(&newLocaleGerm.text, &loc.text));
UA_LocalizedText_clear(&loc);
}
START_TEST(Client_activateSessionWithoutConnect) {
UA_Client *client = UA_Client_new();
UA_ClientConfig *config = UA_Client_getConfig(client);
UA_ClientConfig_setDefault(config);
config->sessionLocaleIdsSize = 2;
config->sessionLocaleIds = (UA_LocaleId *)UA_Array_new(2, &UA_TYPES[UA_TYPES_LOCALEID]);
config->sessionLocaleIds[0] = UA_STRING_ALLOC("en-US");
config->sessionLocaleIds[1] = UA_STRING_ALLOC("de");
changeLocale(client);
ck_assert_uint_eq(server->sessionCount, 0);
UA_LocaleId_delete(&config->sessionLocaleIds[0]);
UA_LocaleId_delete(&config->sessionLocaleIds[1]);
UA_Client_delete(client);
}
END_TEST
START_TEST(Client_activateSession) {
UA_Client *client = UA_Client_new();
UA_ClientConfig *config = UA_Client_getConfig(client);
UA_ClientConfig_setDefault(config);
config->sessionLocaleIdsSize = 2;
config->sessionLocaleIds = (UA_LocaleId *)UA_Array_new(2, &UA_TYPES[UA_TYPES_LOCALEID]);
config->sessionLocaleIds[0] = UA_STRING_ALLOC("en-US");
config->sessionLocaleIds[1] = UA_STRING_ALLOC("de");
UA_StatusCode retval = UA_Client_connect(client, "opc.tcp://localhost:4840");
ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD);
changeLocale(client);
UA_Client_delete(client);
}
END_TEST
START_TEST(Client_activateSession_username) {
UA_Client *client = UA_Client_new();
UA_ClientConfig *config = UA_Client_getConfig(client);
UA_ClientConfig_setDefault(config);
config->sessionLocaleIdsSize = 2;
config->sessionLocaleIds = (UA_LocaleId *)UA_Array_new(2, &UA_TYPES[UA_TYPES_LOCALEID]);
config->sessionLocaleIds[0] = UA_STRING_ALLOC("en-US");
config->sessionLocaleIds[1] = UA_STRING_ALLOC("de");
UA_StatusCode retval =
UA_Client_connectUsername(client, "opc.tcp://localhost:4840", "user1", "password");
ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD);
changeLocale(client);
UA_Client_delete(client);
}
END_TEST
START_TEST(Client_read) {
UA_Client *client = UA_Client_new();
UA_ClientConfig *config = UA_Client_getConfig(client);
UA_ClientConfig_setDefault(config);
config->sessionLocaleIdsSize = 2;
config->sessionLocaleIds = (UA_LocaleId *)UA_Array_new(2, &UA_TYPES[UA_TYPES_LOCALEID]);
config->sessionLocaleIds[0] = UA_STRING_ALLOC("en-US");
config->sessionLocaleIds[1] = UA_STRING_ALLOC("de");
UA_StatusCode retval = UA_Client_connect(client, "opc.tcp://localhost:4840");
ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD);
changeLocale(client);
UA_Variant val;
UA_NodeId nodeId = UA_NODEID_STRING(1, "my.variable");
retval = UA_Client_readValueAttribute(client, nodeId, &val);
ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD);
ck_assert(val.type == &UA_TYPES[UA_TYPES_INT32]);
UA_Int32 *var = (UA_Int32*)val.data;
for(size_t i = 0; i < VARLENGTH; i++)
ck_assert_uint_eq((size_t)var[i], i);
UA_Variant_clear(&val);
UA_Client_delete(client);
}
END_TEST
START_TEST(Client_renewSecureChannel) {
UA_Client *client = UA_Client_new();
UA_ClientConfig *config = UA_Client_getConfig(client);
UA_ClientConfig_setDefault(config);
config->sessionLocaleIdsSize = 2;
config->sessionLocaleIds = (UA_LocaleId *)UA_Array_new(2, &UA_TYPES[UA_TYPES_LOCALEID]);
config->sessionLocaleIds[0] = UA_STRING_ALLOC("en-US");
config->sessionLocaleIds[1] = UA_STRING_ALLOC("de");
UA_StatusCode retval = UA_Client_connect(client, "opc.tcp://localhost:4840");
ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD);
changeLocale(client);
/* Forward the time */
UA_ClientConfig *cc = UA_Client_getConfig(client);
UA_fakeSleep((UA_UInt32)((UA_Double)cc->secureChannelLifeTime * 0.8));
/* Make the client renew the channel */
retval = UA_Client_run_iterate(client, 1);
ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD);
/* Now read */
UA_Variant val;
UA_NodeId nodeId = UA_NODEID_STRING(1, "my.variable");
retval = UA_Client_readValueAttribute(client, nodeId, &val);
ck_assert(retval == UA_STATUSCODE_GOOD);
UA_Variant_clear(&val);
UA_Client_delete(client);
} END_TEST
#ifdef UA_ENABLE_SUBSCRIPTIONS
START_TEST(Client_renewSecureChannelWithActiveSubscription) {
UA_Client *client = UA_Client_new();
UA_ClientConfig *config = UA_Client_getConfig(client);
UA_ClientConfig_setDefault(config);
config->sessionLocaleIdsSize = 2;
config->sessionLocaleIds = (UA_LocaleId *)UA_Array_new(2, &UA_TYPES[UA_TYPES_LOCALEID]);
config->sessionLocaleIds[0] = UA_STRING_ALLOC("en-US");
config->sessionLocaleIds[1] = UA_STRING_ALLOC("de");
config->secureChannelLifeTime = 60000;
UA_StatusCode retval = UA_Client_connect(client, "opc.tcp://localhost:4840");
ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD);
UA_CreateSubscriptionRequest request = UA_CreateSubscriptionRequest_default();
/* Force the server to send keep alive responses every second to trigg
* the client to send new publish requests. Requests from the client
* will make the server to change to the new SecurityToken after renewal.
*/
request.requestedPublishingInterval = 1000;
request.requestedMaxKeepAliveCount = 1;
UA_CreateSubscriptionResponse response = UA_Client_Subscriptions_create(client, request,
NULL, NULL, NULL);
UA_CreateSubscriptionResponse_clear(&response);
changeLocale(client);
/* manually control the server thread */
running = false;
THREAD_JOIN(server_thread);
for(int i = 0; i < 15; ++i) {
UA_fakeSleep(1000);
UA_Server_run_iterate(server, true);
retval = UA_Client_run_iterate(client, 1);
ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD);
}
/* run the server in an independent thread again */
running = true;
THREAD_CREATE(server_thread, serverloop);
// UA_Client_disconnect(client);
UA_Client_delete(client);
} END_TEST
#endif
START_TEST(Client_switch) {
UA_Client *client = UA_Client_new();
UA_ClientConfig *config = UA_Client_getConfig(client);
UA_ClientConfig_setDefault(config);
config->sessionLocaleIdsSize = 2;
config->sessionLocaleIds = (UA_LocaleId *)UA_Array_new(2, &UA_TYPES[UA_TYPES_LOCALEID]);
config->sessionLocaleIds[0] = UA_STRING_ALLOC("en-US");
config->sessionLocaleIds[1] = UA_STRING_ALLOC("de");
UA_StatusCode retval = UA_Client_connect(client, "opc.tcp://localhost:4840");
ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD);
changeLocale(client);
UA_Variant val;
UA_NodeId nodeId = UA_NODEID_STRING(1, "my.variable");
retval = UA_Client_readValueAttribute(client, nodeId, &val);
ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD);
UA_Variant_clear(&val);
UA_NodeId authenticationToken;
UA_ByteString sessionNonce;
UA_Client_getSessionAuthenticationToken(client, &authenticationToken,
&sessionNonce);
UA_Client *client2 = UA_Client_new();
UA_ClientConfig *config2 = UA_Client_getConfig(client2);
UA_ClientConfig_setDefault(config2);
retval = UA_Client_connectSecureChannel(client2, "opc.tcp://localhost:4840");
ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD);
retval = UA_Client_activateSession(client2, authenticationToken, sessionNonce);
ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD);
retval = UA_Client_readValueAttribute(client, nodeId, &val);
ck_assert_uint_ne(retval, UA_STATUSCODE_GOOD);
UA_Variant_clear(&val);
retval = UA_Client_readValueAttribute(client2, nodeId, &val);
ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD);
UA_Variant_clear(&val);
UA_NodeId_clear(&authenticationToken);
UA_ByteString_clear(&sessionNonce);
UA_Client_delete(client);
UA_Client_delete(client2);
}
END_TEST
START_TEST(Client_activateSessionClose) {
// restart server
teardown();
setup();
ck_assert_uint_eq(server->sessionCount, 0);
UA_Client *client = UA_Client_new();
UA_ClientConfig *config = UA_Client_getConfig(client);
UA_ClientConfig_setDefault(config);
config->sessionLocaleIdsSize = 2;
config->sessionLocaleIds = (UA_LocaleId *)UA_Array_new(2, &UA_TYPES[UA_TYPES_LOCALEID]);
config->sessionLocaleIds[0] = UA_STRING_ALLOC("en-US");
config->sessionLocaleIds[1] = UA_STRING_ALLOC("de");
UA_StatusCode retval = UA_Client_connect(client, "opc.tcp://localhost:4840");
ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD);
ck_assert_uint_eq(server->sessionCount, 1);
UA_Variant val;
UA_NodeId nodeId = UA_NODEID_STRING(1, "my.variable");
retval = UA_Client_readValueAttribute(client, nodeId, &val);
ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD);
UA_Variant_clear(&val);
changeLocale(client);
UA_Client_disconnect(client);
retval = UA_Client_connect(client, "opc.tcp://localhost:4840");
ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD);
ck_assert_uint_eq(server->sessionCount, 1);
changeLocale(client);
nodeId = UA_NODEID_STRING(1, "my.variable");
retval = UA_Client_readValueAttribute(client, nodeId, &val);
ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD);
UA_Variant_clear(&val);
UA_Client_delete(client);
ck_assert_uint_eq(server->sessionCount, 0);
}
END_TEST
START_TEST(Client_activateSessionTimeout) {
// restart server
teardown();
setup();
ck_assert_uint_eq(server->sessionCount, 0);
UA_Client *client = UA_Client_new();
UA_ClientConfig *config = UA_Client_getConfig(client);
UA_ClientConfig_setDefault(config);
config->sessionLocaleIdsSize = 2;
config->sessionLocaleIds = (UA_LocaleId *)UA_Array_new(2, &UA_TYPES[UA_TYPES_LOCALEID]);
config->sessionLocaleIds[0] = UA_STRING_ALLOC("en-US");
config->sessionLocaleIds[1] = UA_STRING_ALLOC("de");
UA_StatusCode retval = UA_Client_connect(client, "opc.tcp://localhost:4840");
ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD);
ck_assert_uint_eq(server->sessionCount, 1);
changeLocale(client);
ck_assert_uint_eq(server->sessionCount, 1);
UA_Variant val;
UA_Variant_init(&val);
UA_NodeId nodeId = UA_NODEID_NUMERIC(0, UA_NS0ID_SERVER_SERVERSTATUS_STATE);
retval = UA_Client_readValueAttribute(client, nodeId, &val);
ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD);
UA_Variant_clear(&val);
/* Manually close the connection. The connection is internally closed at the
* next iteration of the EventLoop. Hence the next request is sent out. But
* the connection "actually closes" before receiving the response. */
UA_ConnectionManager *cm = client->channel.connectionManager;
uintptr_t connId = client->channel.connectionId;
cm->closeConnection(cm, connId);
UA_Variant_init(&val);
retval = UA_Client_readValueAttribute(client, nodeId, &val);
ck_assert_uint_eq(retval, UA_STATUSCODE_BADCONNECTIONCLOSED);
retval = UA_Client_connect(client, "opc.tcp://localhost:4840");
ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD);
ck_assert_uint_eq(server->sessionCount, 1);
retval = UA_Client_readValueAttribute(client, nodeId, &val);
ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD);
UA_Variant_clear(&val);
UA_Client_delete(client);
ck_assert_uint_eq(server->sessionCount, 0);
}
END_TEST
START_TEST(Client_activateSessionLocaleIds) {
// restart server
teardown();
setup();
ck_assert_uint_eq(server->sessionCount, 0);
UA_Client *client = UA_Client_new();
UA_ClientConfig *config = UA_Client_getConfig(client);
UA_ClientConfig_setDefault(config);
config->sessionLocaleIdsSize = 2;
config->sessionLocaleIds = (UA_LocaleId*)UA_Array_new(2, &UA_TYPES[UA_TYPES_LOCALEID]);
config->sessionLocaleIds[0] = UA_STRING_ALLOC("en");
config->sessionLocaleIds[1] = UA_STRING_ALLOC("fr");
UA_StatusCode retval = UA_Client_connect(client, "opc.tcp://localhost:4840");
ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD);
ck_assert_uint_eq(server->sessionCount, 1);
changeLocale(client);
ck_assert_uint_eq(server->sessionCount, 1);
UA_QualifiedName key = {0, UA_STRING_STATIC("localeIds")};
UA_Variant locales;
UA_Server_getSessionAttribute(server, &server->sessions.lh_first->session.sessionId,
key, &locales);
ck_assert_uint_eq(locales.arrayLength, 2);
UA_String *localeIds = (UA_String*)locales.data;
ck_assert(UA_String_equal(localeIds, &config->sessionLocaleIds[0]));
UA_Client_delete(client);
ck_assert_uint_eq(server->sessionCount, 0);
}
END_TEST
static Suite* testSuite_Client(void) {
Suite *s = suite_create("Client");
TCase *tc_client = tcase_create("Client Basic");
tcase_add_checked_fixture(tc_client, setup, teardown);
tcase_add_test(tc_client, Client_activateSession);
tcase_add_test(tc_client, Client_activateSession_username);
tcase_add_test(tc_client, Client_read);
tcase_add_test(tc_client, Client_renewSecureChannel);
#ifdef UA_ENABLE_SUBSCRIPTIONS
tcase_add_test(tc_client, Client_renewSecureChannelWithActiveSubscription);
#endif
tcase_add_test(tc_client, Client_activateSessionClose);
tcase_add_test(tc_client, Client_activateSessionTimeout);
tcase_add_test(tc_client, Client_activateSessionLocaleIds);
suite_add_tcase(s,tc_client);
TCase *tc_client_reconnect = tcase_create("Client Session Switch");
tcase_add_checked_fixture(tc_client_reconnect, setup, teardown);
tcase_add_test(tc_client_reconnect, Client_switch);
suite_add_tcase(s,tc_client_reconnect);
return s;
}
int main(void) {
Suite *s = testSuite_Client();
SRunner *sr = srunner_create(s);
srunner_set_fork_status(sr, CK_NOFORK);
srunner_run_all(sr,CK_NORMAL);
int number_failed = srunner_ntests_failed(sr);
srunner_free(sr);
return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
}

View File

@@ -0,0 +1,182 @@
/* 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/. */
#include <open62541/client.h>
#include <open62541/client_config_default.h>
#include <open62541/client_highlevel_async.h>
#include <open62541/server.h>
#include <open62541/server_config_default.h>
#include "open62541/common.h"
#include "ua_server_internal.h"
#include "client/ua_client_internal.h"
#include <check.h>
#include <stdlib.h>
#include "testing_clock.h"
#include "thread_wrapper.h"
UA_Server *server;
UA_Boolean connected = false;
UA_Boolean running;
#define VARLENGTH 16366
THREAD_HANDLE server_thread;
static void
addVariable(size_t size) {
/* Define the attribute of the myInteger variable node */
UA_VariableAttributes attr = UA_VariableAttributes_default;
UA_Int32* array = (UA_Int32*)UA_malloc(size * sizeof(UA_Int32));
for(size_t i = 0; i < size; i++)
array[i] = (UA_Int32)i;
UA_Variant_setArray(&attr.value, array, size, &UA_TYPES[UA_TYPES_INT32]);
char name[] = "my.variable";
attr.description = UA_LOCALIZEDTEXT("en-US", name);
attr.displayName = UA_LOCALIZEDTEXT("en-US", name);
attr.dataType = UA_TYPES[UA_TYPES_INT32].typeId;
/* Add the variable node to the information model */
UA_NodeId myIntegerNodeId = UA_NODEID_STRING(1, name);
UA_QualifiedName myIntegerName = UA_QUALIFIEDNAME(1, name);
UA_NodeId parentNodeId = UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER);
UA_NodeId parentReferenceNodeId = UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES);
UA_Server_addVariableNode(server, myIntegerNodeId, parentNodeId,
parentReferenceNodeId, myIntegerName,
UA_NODEID_NUMERIC(0, UA_NS0ID_BASEDATAVARIABLETYPE),
attr, NULL, NULL);
/* add displayname to variable */
UA_Server_writeDisplayName(server, myIntegerNodeId,
UA_LOCALIZEDTEXT("de", "meine.Variable"));
UA_free(array);
}
THREAD_CALLBACK(serverloop) {
while(running)
UA_Server_run_iterate(server, true);
return 0;
}
static void setup(void) {
running = true;
server = UA_Server_new();
ck_assert(server != NULL);
UA_ServerConfig_setDefault(UA_Server_getConfig(server));
UA_Server_run_startup(server);
addVariable(VARLENGTH);
THREAD_CREATE(server_thread, serverloop);
}
static void teardown(void) {
running = false;
THREAD_JOIN(server_thread);
UA_Server_run_shutdown(server);
UA_Server_delete(server);
}
static void
asyncBrowseCallback(UA_Client *Client, void *userdata,
UA_UInt32 requestId, UA_BrowseResponse *response) {
UA_UInt16 *asyncCounter = (UA_UInt16*)userdata;
(*asyncCounter)++;
}
static void clearLocale(UA_ClientConfig *config) {
if(config->sessionLocaleIdsSize > 0 && config->sessionLocaleIds) {
UA_Array_delete(config->sessionLocaleIds,
config->sessionLocaleIdsSize, &UA_TYPES[UA_TYPES_LOCALEID]);
}
config->sessionLocaleIds = NULL;
config->sessionLocaleIdsSize = 0;
}
START_TEST(Client_activateSession_async) {
UA_StatusCode retval;
UA_Client *client = UA_Client_new();
UA_ClientConfig *cc = UA_Client_getConfig(client);
cc->sessionLocaleIdsSize = 2;
cc->sessionLocaleIds = (UA_LocaleId*)UA_Array_new(2, &UA_TYPES[UA_TYPES_LOCALEID]);
cc->sessionLocaleIds[0] = UA_STRING_ALLOC("en-US");
cc->sessionLocaleIds[1] = UA_STRING_ALLOC("de");
UA_ClientConfig_setDefault(cc);
connected = false;
// connect sync
retval = UA_Client_connect(client, "opc.tcp://localhost:4840");
ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD);
// now join server thread to take control
running = false;
THREAD_JOIN(server_thread);
/* try to change locale */
clearLocale(cc);
cc->sessionLocaleIdsSize = 2;
cc->sessionLocaleIds = (UA_LocaleId*)UA_Array_new(2, &UA_TYPES[UA_TYPES_LOCALEID]);
cc->sessionLocaleIds[0] = UA_STRING_ALLOC("de");
cc->sessionLocaleIds[1] = UA_STRING_ALLOC("en-US");
UA_Client_activateCurrentSessionAsync(client);
ck_assert_uint_eq(server->sessionCount, 1);
// read locale,it must not be changed
UA_String loc = LIST_FIRST(&server->sessions)->session.localeIds[0];
char *convert = (char *)UA_malloc(sizeof(char) * loc.length + 1);
memcpy(convert, loc.data, loc.length);
convert[loc.length] = '\0';
ck_assert_str_eq(convert, "en-US");
UA_free(convert);
ck_assert_uint_eq(server->sessionCount, 1);
/* Manual clock for unit tests */
UA_Server_run_iterate(server, false);
loc = LIST_FIRST(&server->sessions)->session.localeIds[0];
convert = (char *)UA_malloc(sizeof(char) * loc.length + 1);
memcpy(convert, loc.data, loc.length);
convert[loc.length] = '\0';
ck_assert_str_eq(convert, "de");
UA_free(convert);
ck_assert_uint_eq(server->sessionCount, 1);
running = true;
// start serverthread again
THREAD_CREATE(server_thread, serverloop);
// read displayname with changed locale
UA_LocalizedText dName;
const UA_NodeId nodeIdString = UA_NODEID_STRING(1, "my.variable");
retval = UA_Client_readDisplayNameAttribute(client, nodeIdString, &dName);
ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD);
UA_LocalizedText newLocaleEng = UA_LOCALIZEDTEXT("de", "meine.Variable");
ck_assert(UA_String_equal(&newLocaleEng.locale, &dName.locale));
ck_assert(UA_String_equal(&newLocaleEng.text, &dName.text));
UA_LocalizedText_clear(&dName);
UA_Client_disconnect(client);
UA_Client_delete (client);
}
END_TEST
static Suite* testSuite_Client(void) {
Suite *s = suite_create("Client");
TCase *tc_client_activateSession_async = tcase_create("Client Activate Session Async");
tcase_add_checked_fixture(tc_client_activateSession_async, setup, teardown);
tcase_add_test(tc_client_activateSession_async, Client_activateSession_async);
suite_add_tcase(s,tc_client_activateSession_async);
return s;
}
int main(void) {
Suite *s = testSuite_Client();
SRunner *sr = srunner_create(s);
srunner_set_fork_status(sr, CK_NOFORK);
srunner_run_all(sr, CK_NORMAL);
int number_failed = srunner_ntests_failed(sr);
srunner_free(sr);
return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
}

View File

@@ -0,0 +1,500 @@
/* 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/. */
#include <open62541/client_config_default.h>
#include <open62541/server_config_default.h>
#include <open62541/plugin/accesscontrol_default.h>
#include "client/ua_client_internal.h"
#include "ua_server_internal.h"
#include <check.h>
#include <stdlib.h>
#include "testing_clock.h"
#include "thread_wrapper.h"
UA_Server *server;
UA_Boolean running;
THREAD_HANDLE server_thread;
static const size_t usernamePasswordsSize = 2;
static UA_UsernamePasswordLogin usernamePasswords[2] = {
{UA_STRING_STATIC("user1"), UA_STRING_STATIC("password")},
{UA_STRING_STATIC("user2"), UA_STRING_STATIC("password1")}};
static void
addVariable(size_t size) {
/* Define the attribute of the myInteger variable node */
UA_VariableAttributes attr = UA_VariableAttributes_default;
UA_Int32* array = (UA_Int32*)UA_malloc(size * sizeof(UA_Int32));
for(size_t i = 0; i < size; i++)
array[i] = (UA_Int32)i;
UA_Variant_setArray(&attr.value, array, size, &UA_TYPES[UA_TYPES_INT32]);
char name[] = "my.variable";
attr.description = UA_LOCALIZEDTEXT("en-US", name);
attr.displayName = UA_LOCALIZEDTEXT("en-US", name);
attr.dataType = UA_TYPES[UA_TYPES_INT32].typeId;
/* Add the variable node to the information model */
UA_NodeId myIntegerNodeId = UA_NODEID_STRING(1, name);
UA_QualifiedName myIntegerName = UA_QUALIFIEDNAME(1, name);
UA_NodeId parentNodeId = UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER);
UA_NodeId parentReferenceNodeId = UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES);
UA_Server_addVariableNode(server, myIntegerNodeId, parentNodeId,
parentReferenceNodeId, myIntegerName,
UA_NODEID_NUMERIC(0, UA_NS0ID_BASEDATAVARIABLETYPE),
attr, NULL, NULL);
UA_free(array);
}
THREAD_CALLBACK(serverloop) {
while(running)
UA_Server_run_iterate(server, true);
return 0;
}
#define VARLENGTH 16366
static void setup(void) {
running = true;
server = UA_Server_new();
ck_assert(server != NULL);
/* Instatiate a new AccessControl plugin that knows username/pw */
UA_ServerConfig *config = UA_Server_getConfig(server);
UA_SecurityPolicy *sp = &config->securityPolicies[config->securityPoliciesSize-1];
UA_AccessControl_default(config, true, &sp->policyUri,
usernamePasswordsSize, usernamePasswords);
UA_Server_run_startup(server);
addVariable(VARLENGTH);
THREAD_CREATE(server_thread, serverloop);
}
static void teardown(void) {
running = false;
THREAD_JOIN(server_thread);
UA_Server_run_shutdown(server);
UA_Server_delete(server);
}
START_TEST(ClientConfig_Copy){
UA_ClientConfig dstConfig;
memset(&dstConfig, 0, sizeof(UA_ClientConfig));
UA_ClientConfig srcConfig;
memset(&srcConfig, 0, sizeof(UA_ClientConfig));
UA_ClientConfig_setDefault(&srcConfig);
UA_StatusCode retval = UA_ClientConfig_copy(&srcConfig, &dstConfig);
ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD);
UA_Client *dstConfigClient = UA_Client_newWithConfig(&dstConfig);
retval = UA_Client_connect(dstConfigClient, "opc.tcp://localhost:4840");
ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD);
UA_Client_disconnect(dstConfigClient);
UA_Client_delete(dstConfigClient);
UA_ApplicationDescription_clear(&srcConfig.clientDescription);
}
END_TEST
START_TEST(Client_connect) {
UA_Client *client = UA_Client_new();
UA_ClientConfig_setDefault(UA_Client_getConfig(client));
UA_StatusCode retval = UA_Client_connect(client, "opc.tcp://localhost:4840");
ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD);
UA_Client_disconnect(client);
UA_Client_delete(client);
}
END_TEST
START_TEST(Client_connect_username) {
UA_Client *client = UA_Client_new();
UA_ClientConfig_setDefault(UA_Client_getConfig(client));
UA_StatusCode retval =
UA_Client_connectUsername(client, "opc.tcp://localhost:4840", "user1", "password");
ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD);
UA_Client_disconnect(client);
UA_Client_delete(client);
}
END_TEST
START_TEST(Client_endpoints) {
UA_Client *client = UA_Client_new();
UA_ClientConfig_setDefault(UA_Client_getConfig(client));
UA_EndpointDescription* endpointArray = NULL;
size_t endpointArraySize = 0;
UA_StatusCode retval = UA_Client_getEndpoints(client, "opc.tcp://localhost:4840",
&endpointArraySize, &endpointArray);
ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD);
ck_assert(endpointArraySize > 0);
UA_Array_delete(endpointArray,endpointArraySize, &UA_TYPES[UA_TYPES_ENDPOINTDESCRIPTION]);
UA_Client_delete(client);
}
END_TEST
START_TEST(Client_endpoints_empty) {
/* Issue a getEndpoints call with empty endpointUrl.
* Using UA_Client_getEndpoints automatically passes the client->endpointUrl as requested endpointUrl.
* The spec says:
* The Server should return a suitable default URL if it does not recognize the HostName in the URL.
*
* See https://github.com/open62541/open62541/issues/775
*/
UA_Client *client = UA_Client_new();
UA_ClientConfig_setDefault(UA_Client_getConfig(client));
UA_StatusCode retval = UA_Client_connect(client, "opc.tcp://localhost:4840");
ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD);
UA_GetEndpointsRequest request;
UA_GetEndpointsRequest_init(&request);
request.requestHeader.timestamp = UA_DateTime_now();
request.requestHeader.timeoutHint = 10000;
UA_GetEndpointsResponse response;
__UA_Client_Service(client, &request, &UA_TYPES[UA_TYPES_GETENDPOINTSREQUEST],
&response, &UA_TYPES[UA_TYPES_GETENDPOINTSRESPONSE]);
ck_assert_uint_eq(response.responseHeader.serviceResult, UA_STATUSCODE_GOOD);
ck_assert(response.endpointsSize > 0);
UA_GetEndpointsResponse_clear(&response);
UA_GetEndpointsRequest_clear(&request);
UA_Client_delete(client);
}
END_TEST
START_TEST(Client_read) {
UA_Client *client = UA_Client_new();
UA_ClientConfig_setDefault(UA_Client_getConfig(client));
UA_StatusCode retval = UA_Client_connect(client, "opc.tcp://localhost:4840");
ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD);
UA_Variant val;
UA_NodeId nodeId = UA_NODEID_STRING(1, "my.variable");
retval = UA_Client_readValueAttribute(client, nodeId, &val);
ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD);
ck_assert(val.type == &UA_TYPES[UA_TYPES_INT32]);
UA_Int32 *var = (UA_Int32*)val.data;
for(size_t i = 0; i < VARLENGTH; i++)
ck_assert_uint_eq((size_t)var[i], i);
UA_Variant_clear(&val);
UA_Client_disconnect(client);
UA_Client_delete(client);
}
END_TEST
START_TEST(Client_renewSecureChannel) {
UA_Client *client = UA_Client_new();
UA_ClientConfig_setDefault(UA_Client_getConfig(client));
UA_StatusCode retval = UA_Client_connect(client, "opc.tcp://localhost:4840");
ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD);
/* Forward the time */
UA_ClientConfig *cc = UA_Client_getConfig(client);
UA_fakeSleep((UA_UInt32)((UA_Double)cc->secureChannelLifeTime * 0.8));
/* Make the client renew the channel */
retval = UA_Client_run_iterate(client, 1);
ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD);
/* Now read */
UA_Variant val;
UA_NodeId nodeId = UA_NODEID_STRING(1, "my.variable");
retval = UA_Client_readValueAttribute(client, nodeId, &val);
ck_assert(retval == UA_STATUSCODE_GOOD);
UA_Variant_clear(&val);
UA_Client_disconnect(client);
UA_Client_delete(client);
} END_TEST
#ifdef UA_ENABLE_SUBSCRIPTIONS
START_TEST(Client_renewSecureChannelWithActiveSubscription) {
UA_Client *client = UA_Client_new();
UA_ClientConfig_setDefault(UA_Client_getConfig(client));
UA_ClientConfig *cc = UA_Client_getConfig(client);
cc->secureChannelLifeTime = 60000;
UA_StatusCode retval = UA_Client_connect(client, "opc.tcp://localhost:4840");
ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD);
UA_CreateSubscriptionRequest request = UA_CreateSubscriptionRequest_default();
/* Force the server to send keep alive responses every second to trigg
* the client to send new publish requests. Requests from the client
* will make the server to change to the new SecurityToken after renewal.
*/
request.requestedPublishingInterval = 1000;
request.requestedMaxKeepAliveCount = 1;
UA_CreateSubscriptionResponse response = UA_Client_Subscriptions_create(client, request,
NULL, NULL, NULL);
UA_CreateSubscriptionResponse_clear(&response);
/* manually control the server thread */
running = false;
THREAD_JOIN(server_thread);
for(int i = 0; i < 15; ++i) {
UA_fakeSleep(1000);
UA_Server_run_iterate(server, true);
retval = UA_Client_run_iterate(client, 1);
ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD);
}
/* run the server in an independent thread again */
running = true;
THREAD_CREATE(server_thread, serverloop);
UA_Client_disconnect(client);
UA_Client_delete(client);
} END_TEST
#endif
START_TEST(Client_reconnect) {
UA_Client *client = UA_Client_new();
UA_ClientConfig_setDefault(UA_Client_getConfig(client));
UA_StatusCode retval = UA_Client_connect(client, "opc.tcp://localhost:4840");
ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD);
UA_Variant val;
UA_NodeId nodeId = UA_NODEID_STRING(1, "my.variable");
retval = UA_Client_readValueAttribute(client, nodeId, &val);
ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD);
UA_Variant_clear(&val);
// FIX THIS FOR THE AZURE BUILD
#if 0
printf("Restart server to test reconnect\n");
fflush(stdout);
teardown();
setup();
printf("Read attribute with closed connection\n");
fflush(stdout);
retval = UA_Client_readValueAttribute(client, nodeId, &val);
ck_assert_uint_eq(retval, UA_STATUSCODE_BADCONNECTIONCLOSED);
printf("Reconnect client \n");
fflush(stdout);
retval = UA_Client_connect(client, "opc.tcp://localhost:4840");
ck_assert_msg(retval == UA_STATUSCODE_GOOD, UA_StatusCode_name(retval));
UA_SessionState ss;
UA_Client_getState(client, NULL, &ss, NULL);
ck_assert_int_eq(ss, UA_SESSIONSTATE_ACTIVATED);
printf("Read attribute again\n");
fflush(stdout);
retval = UA_Client_readValueAttribute(client, nodeId, &val);
ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD);
UA_Variant_clear(&val);
printf("Finish up\n");
fflush(stdout);
#endif
UA_Client_disconnect(client);
UA_Client_delete(client);
}
END_TEST
START_TEST(Client_delete_without_connect) {
UA_Client *client = UA_Client_new();
UA_ClientConfig_setDefault(UA_Client_getConfig(client));
ck_assert(client != NULL);
UA_Client_delete(client);
}
END_TEST
START_TEST(Client_activateSessionClose) {
// restart server
teardown();
setup();
ck_assert_uint_eq(server->sessionCount, 0);
UA_Client *client = UA_Client_new();
UA_ClientConfig_setDefault(UA_Client_getConfig(client));
UA_StatusCode retval = UA_Client_connect(client, "opc.tcp://localhost:4840");
ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD);
ck_assert_uint_eq(server->sessionCount, 1);
UA_Variant val;
UA_NodeId nodeId = UA_NODEID_STRING(1, "my.variable");
retval = UA_Client_readValueAttribute(client, nodeId, &val);
ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD);
UA_Variant_clear(&val);
UA_Client_disconnect(client);
retval = UA_Client_connect(client, "opc.tcp://localhost:4840");
ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD);
ck_assert_uint_eq(server->sessionCount, 1);
nodeId = UA_NODEID_STRING(1, "my.variable");
retval = UA_Client_readValueAttribute(client, nodeId, &val);
ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD);
UA_Variant_clear(&val);
UA_Client_disconnect(client);
UA_Client_delete(client);
ck_assert_uint_eq(server->sessionCount, 0);
}
END_TEST
START_TEST(Client_activateSessionTimeout) {
// restart server
teardown();
setup();
ck_assert_uint_eq(server->sessionCount, 0);
UA_Client *client = UA_Client_new();
UA_ClientConfig_setDefault(UA_Client_getConfig(client));
UA_StatusCode retval = UA_Client_connect(client, "opc.tcp://localhost:4840");
ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD);
ck_assert_uint_eq(server->sessionCount, 1);
UA_Variant val;
UA_Variant_init(&val);
UA_NodeId nodeId = UA_NODEID_NUMERIC(0, UA_NS0ID_SERVER_SERVERSTATUS_STATE);
retval = UA_Client_readValueAttribute(client, nodeId, &val);
ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD);
UA_Variant_clear(&val);
/* Manually close the connection. The connection is internally closed at the
* next iteration of the EventLoop. Hence the next request is sent out. But
* the connection "actually closes" before receiving the response. */
UA_ConnectionManager *cm = client->channel.connectionManager;
uintptr_t connId = client->channel.connectionId;
cm->closeConnection(cm, connId);
UA_Variant_init(&val);
retval = UA_Client_readValueAttribute(client, nodeId, &val);
ck_assert_uint_eq(retval, UA_STATUSCODE_BADCONNECTIONCLOSED);
retval = UA_Client_connect(client, "opc.tcp://localhost:4840");
ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD);
ck_assert_uint_eq(server->sessionCount, 1);
retval = UA_Client_readValueAttribute(client, nodeId, &val);
ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD);
UA_Variant_clear(&val);
UA_Client_delete(client);
ck_assert_uint_eq(server->sessionCount, 0);
}
END_TEST
START_TEST(Client_activateSessionLocaleIds) {
// restart server
teardown();
setup();
ck_assert_uint_eq(server->sessionCount, 0);
UA_Client *client = UA_Client_new();
UA_ClientConfig *config = UA_Client_getConfig(client);
UA_ClientConfig_setDefault(config);
config->sessionLocaleIdsSize = 2;
config->sessionLocaleIds = (UA_LocaleId*)UA_Array_new(2, &UA_TYPES[UA_TYPES_LOCALEID]);
config->sessionLocaleIds[0] = UA_STRING_ALLOC("en");
config->sessionLocaleIds[1] = UA_STRING_ALLOC("fr");
UA_StatusCode retval = UA_Client_connect(client, "opc.tcp://localhost:4840");
ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD);
ck_assert_uint_eq(server->sessionCount, 1);
UA_QualifiedName key = {0, UA_STRING_STATIC("localeIds")};
UA_Variant locales;
UA_Server_getSessionAttribute(server, &server->sessions.lh_first->session.sessionId,
key, &locales);
ck_assert_uint_eq(locales.arrayLength, 2);
UA_String *localeIds = (UA_String*)locales.data;
ck_assert(UA_String_equal(&localeIds[0], &config->sessionLocaleIds[0]));
ck_assert(UA_String_equal(&localeIds[1], &config->sessionLocaleIds[1]));
UA_Client_delete(client);
ck_assert_uint_eq(server->sessionCount, 0);
}
END_TEST
START_TEST(Client_closes_on_server_error) {
UA_Client *client = UA_Client_new();
UA_ClientConfig_setDefault(UA_Client_getConfig(client));
UA_StatusCode retval = UA_Client_connect(client, "opc.tcp://localhost:4840");
ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD);
ck_assert_uint_eq(server->sessionCount, 1);
UA_SecureChannel *channel = server->sessions.lh_first->session.header.channel;
// send error message from server to client
UA_TcpErrorMessage errMsg = {.error = UA_STATUSCODE_BADSECURITYCHECKSFAILED,
.reason = UA_STRING_NULL};
UA_SecureChannel_sendError(channel, &errMsg);
// client should disconnect and close TCP connections, although err was received
// note: if it fails to do so the tests might hang here
UA_Client_disconnect(client);
UA_Client_delete(client);
}
END_TEST
static Suite* testSuite_Client(void) {
Suite *s = suite_create("Client");
TCase *tc_client = tcase_create("Client Basic");
tcase_add_checked_fixture(tc_client, setup, teardown);
tcase_add_test(tc_client, ClientConfig_Copy);
tcase_add_test(tc_client, Client_connect);
tcase_add_test(tc_client, Client_connect_username);
tcase_add_test(tc_client, Client_delete_without_connect);
tcase_add_test(tc_client, Client_endpoints);
tcase_add_test(tc_client, Client_endpoints_empty);
tcase_add_test(tc_client, Client_read);
tcase_add_test(tc_client, Client_closes_on_server_error);
suite_add_tcase(s,tc_client);
TCase *tc_client_reconnect = tcase_create("Client Reconnect");
tcase_add_checked_fixture(tc_client_reconnect, setup, teardown);
tcase_add_test(tc_client_reconnect, Client_renewSecureChannel);
#ifdef UA_ENABLE_SUBSCRIPTIONS
tcase_add_test(tc_client_reconnect, Client_renewSecureChannelWithActiveSubscription);
#endif
tcase_add_test(tc_client_reconnect, Client_reconnect);
tcase_add_test(tc_client_reconnect, Client_activateSessionClose);
tcase_add_test(tc_client_reconnect, Client_activateSessionTimeout);
tcase_add_test(tc_client_reconnect, Client_activateSessionLocaleIds);
suite_add_tcase(s,tc_client_reconnect);
return s;
}
int main(void) {
Suite *s = testSuite_Client();
SRunner *sr = srunner_create(s);
srunner_set_fork_status(sr, CK_NOFORK);
srunner_run_all(sr,CK_NORMAL);
int number_failed = srunner_ntests_failed(sr);
srunner_free(sr);
return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
}

View File

@@ -0,0 +1,301 @@
/* 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/. */
#include <open62541/client.h>
#include <open62541/client_config_default.h>
#include <open62541/client_highlevel_async.h>
#include <open62541/server.h>
#include <open62541/server_config_default.h>
#include "client/ua_client_internal.h"
#include <check.h>
#include <stdio.h>
#include <stdlib.h>
#include "testing_clock.h"
#include "thread_wrapper.h"
UA_Server *server;
UA_Boolean running;
THREAD_HANDLE server_thread;
THREAD_CALLBACK(serverloop) {
while (running)
UA_Server_run_iterate(server, true);
return 0;
}
static void setup(void) {
running = true;
server = UA_Server_new();
ck_assert(server != NULL);
UA_ServerConfig_setDefault(UA_Server_getConfig(server));
UA_Server_run_startup(server);
THREAD_CREATE(server_thread, serverloop);
}
static void teardown(void) {
running = false;
THREAD_JOIN(server_thread);
UA_Server_run_shutdown(server);
UA_Server_delete(server);
}
static void
asyncReadCallback(UA_Client *client, void *userdata,
UA_UInt32 requestId, const UA_ReadResponse *response) {
UA_UInt16 *asyncCounter = (UA_UInt16*) userdata;
if(response->responseHeader.serviceResult != UA_STATUSCODE_GOOD) {
(*asyncCounter) = 9999;
UA_fakeSleep(10);
} else {
(*asyncCounter)++;
UA_fakeSleep(10);
}
}
static void
asyncReadValueAtttributeCallback(UA_Client *client, void *userdata,
UA_UInt32 requestId, UA_StatusCode opstatus,
UA_DataValue *value) {
UA_UInt16 *asyncCounter = (UA_UInt16*) userdata;
(*asyncCounter)++;
UA_fakeSleep(10);
}
START_TEST(Client_highlevel_async_readValue) {
UA_Client *client = UA_Client_new();
UA_ClientConfig *clientConfig = UA_Client_getConfig(client);
UA_ClientConfig_setDefault(clientConfig);
#ifdef UA_ENABLE_SUBSCRIPTIONS
clientConfig->outStandingPublishRequests = 0;
#endif
UA_StatusCode retval = UA_Client_connect(client, "opc.tcp://localhost:4840");
ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD);
UA_UInt16 asyncCounter = 0;
UA_UInt32 reqId = 0;
retval = UA_Client_readValueAttribute_async(client,
UA_NODEID_NUMERIC(0, UA_NS0ID_SERVER_SERVERSTATUS_CURRENTTIME),
(UA_ClientAsyncReadValueAttributeCallback) asyncReadValueAtttributeCallback,
(void*)&asyncCounter, &reqId);
ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD);
/* Process async responses during 1s */
UA_Client_run_iterate(client, 999 + 1);
ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD);
ck_assert_uint_eq(asyncCounter, 1);
/* Simulate network cable unplugged */
UA_ConnectionManager *cm = client->channel.connectionManager;
cm->closeConnection(cm, client->channel.connectionId);
UA_EventLoop *el = client->config.eventLoop;
el->run(el, 0);
UA_Client_disconnect(client);
UA_Client_delete(client);
} END_TEST
START_TEST(Client_read_async) {
UA_Client *client = UA_Client_new();
UA_ClientConfig *clientConfig = UA_Client_getConfig(client);
UA_ClientConfig_setDefault(clientConfig);
UA_StatusCode retval = UA_Client_connect(client, "opc.tcp://localhost:4840");
ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD);
UA_UInt16 asyncCounter = 0;
UA_ReadRequest rr;
UA_ReadRequest_init(&rr);
UA_ReadValueId rvid;
UA_ReadValueId_init(&rvid);
rvid.attributeId = UA_ATTRIBUTEID_VALUE;
rvid.nodeId = UA_NODEID_NUMERIC(0,
UA_NS0ID_SERVER_SERVERSTATUS_CURRENTTIME);
rr.nodesToRead = &rvid;
rr.nodesToReadSize = 1;
/* Send 100 requests */
for (size_t i = 0; i < 100; i++) {
retval = __UA_Client_AsyncService(client, &rr,
&UA_TYPES[UA_TYPES_READREQUEST],
(UA_ClientAsyncServiceCallback) asyncReadCallback,
&UA_TYPES[UA_TYPES_READRESPONSE], &asyncCounter, NULL);
ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD);
}
/* Process async responses during 1s */
while(asyncCounter < 100)
retval |= UA_Client_run_iterate(client, 999);
ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD);
UA_Client_disconnect(client);
UA_Client_delete(client);
} END_TEST
static void
asyncReadNodeClassAttributeCallback(UA_Client *client, void *userdata,
UA_UInt32 requestId, UA_StatusCode status,
UA_NodeClass *nodeClass) {
ck_assert_uint_eq(status, UA_STATUSCODE_GOOD);
UA_UInt16 *asyncCounter = (UA_UInt16*)userdata;
(*asyncCounter)++;
}
START_TEST(Client_readNodeClass_async) {
UA_Client *client = UA_Client_new();
UA_ClientConfig *clientConfig = UA_Client_getConfig(client);
UA_ClientConfig_setDefault(clientConfig);
UA_StatusCode retval = UA_Client_connect(client, "opc.tcp://localhost:4840");
ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD);
UA_UInt16 asyncCounter = 0;
UA_NodeId cTimeId = UA_NODEID_NUMERIC(0, UA_NS0ID_SERVER_SERVERSTATUS_CURRENTTIME);
retval = UA_Client_readNodeClassAttribute_async(client, cTimeId,
asyncReadNodeClassAttributeCallback,
&asyncCounter, NULL);
ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD);
/* Process async responses during 1s */
while(asyncCounter == 0)
retval |= UA_Client_run_iterate(client, 999);
ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD);
UA_Client_disconnect(client);
UA_Client_delete(client);
} END_TEST
START_TEST(Client_read_async_timed) {
UA_Client *client = UA_Client_new();
UA_ClientConfig *clientConfig = UA_Client_getConfig(client);
UA_ClientConfig_setDefault(clientConfig);
#ifdef UA_ENABLE_SUBSCRIPTIONS
clientConfig->outStandingPublishRequests = 0;
#endif
UA_StatusCode retval = UA_Client_connect(client, "opc.tcp://localhost:4840");
ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD);
UA_UInt16 asyncCounter = 0;
UA_ReadRequest rr;
UA_ReadRequest_init(&rr);
UA_ReadValueId rvid;
UA_ReadValueId_init(&rvid);
rvid.attributeId = UA_ATTRIBUTEID_VALUE;
rvid.nodeId = UA_NODEID_NUMERIC(0,
UA_NS0ID_SERVER_SERVERSTATUS_CURRENTTIME);
rr.nodesToRead = &rvid;
rr.nodesToReadSize = 1;
rr.requestHeader.timeoutHint = 999;
retval = __UA_Client_AsyncService(client, &rr,
&UA_TYPES[UA_TYPES_READREQUEST],
(UA_ClientAsyncServiceCallback) asyncReadCallback,
&UA_TYPES[UA_TYPES_READRESPONSE], &asyncCounter, NULL);
ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD);
/* Process async responses during 1s */
retval = UA_Client_run_iterate(client, 999 + 1);
ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD);
ck_assert_uint_eq(asyncCounter, 1);
/* Manually close the connection */
UA_ConnectionManager *cm = client->channel.connectionManager;
uintptr_t connId = client->channel.connectionId;
cm->closeConnection(cm, connId);
rr.requestHeader.timeoutHint = 100;
retval = __UA_Client_AsyncService(client, &rr, &UA_TYPES[UA_TYPES_READREQUEST],
(UA_ClientAsyncServiceCallback) asyncReadCallback,
&UA_TYPES[UA_TYPES_READRESPONSE], &asyncCounter,
NULL);
/* Sending out the request failed */
ck_assert_uint_eq(retval, UA_STATUSCODE_BADCONNECTIONCLOSED);
UA_Client_disconnect(client);
UA_Client_delete(client);
} END_TEST
static UA_Boolean inactivityCallbackTriggered = false;
static void inactivityCallback(UA_Client *client) {
inactivityCallbackTriggered = true;
}
START_TEST(Client_connectivity_check) {
UA_Client *client = UA_Client_new();
UA_ClientConfig *clientConfig = UA_Client_getConfig(client);
UA_ClientConfig_setDefault(clientConfig);
#ifdef UA_ENABLE_SUBSCRIPTIONS
clientConfig->outStandingPublishRequests = 0;
#endif
clientConfig->inactivityCallback = inactivityCallback;
clientConfig->connectivityCheckInterval = 1000;
UA_StatusCode retval = UA_Client_connect(client, "opc.tcp://localhost:4840");
ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD);
inactivityCallbackTriggered = false;
retval = UA_Client_run_iterate(client, 1000 + 1);
ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD);
ck_assert_uint_eq(inactivityCallbackTriggered, false);
/* Simulate network cable unplugged (no response from server) */
running = false;
THREAD_JOIN(server_thread);
UA_fakeSleep(1000 + 1 + clientConfig->connectivityCheckInterval);
retval = UA_Client_run_iterate(client, 1);
ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD);
UA_fakeSleep(1000 + 1 + clientConfig->timeout);
retval = UA_Client_run_iterate(client, 1);
ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD);
ck_assert_uint_eq(inactivityCallbackTriggered, true);
/* Get the server back up */
running = true;
THREAD_CREATE(server_thread, serverloop);
UA_Client_disconnect(client);
UA_Client_delete(client);
}END_TEST
static Suite* testSuite_Client(void) {
Suite *s = suite_create("Client");
TCase *tc_client = tcase_create("Client Basic");
tcase_add_checked_fixture(tc_client, setup, teardown);
tcase_add_test(tc_client, Client_read_async);
tcase_add_test(tc_client, Client_readNodeClass_async);
tcase_add_test(tc_client, Client_read_async_timed);
tcase_add_test(tc_client, Client_connectivity_check);
tcase_add_test(tc_client, Client_highlevel_async_readValue);
suite_add_tcase(s, tc_client);
return s;
}
int main(void) {
Suite *s = testSuite_Client();
SRunner *sr = srunner_create(s);
srunner_set_fork_status(sr, CK_NOFORK);
srunner_run_all(sr, CK_NORMAL);
int number_failed = srunner_ntests_failed(sr);
srunner_free(sr);
return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
}

View File

@@ -0,0 +1,222 @@
/* 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/. */
#include <open62541/client.h>
#include <open62541/client_config_default.h>
#include <open62541/client_highlevel_async.h>
#include <open62541/server.h>
#include <open62541/server_config_default.h>
#include "open62541/common.h"
#include "client/ua_client_internal.h"
#include <check.h>
#include <stdlib.h>
#include "testing_clock.h"
#include "thread_wrapper.h"
UA_Server *server;
UA_Boolean connected = false;
static void
currentState(UA_Client *client, UA_SecureChannelState channelState,
UA_SessionState sessionState, UA_StatusCode recoveryStatus) {
if(sessionState == UA_SESSIONSTATE_ACTIVATED)
connected = true;
else
connected = false;
}
static void setup(void) {
server = UA_Server_new();
ck_assert(server != NULL);
UA_ServerConfig_setDefault(UA_Server_getConfig(server));
UA_Server_run_startup(server);
}
static void teardown(void) {
UA_Server_run_shutdown(server);
UA_Server_delete(server);
}
static void
asyncBrowseCallback(UA_Client *Client, void *userdata,
UA_UInt32 requestId, UA_BrowseResponse *response) {
UA_UInt16 *asyncCounter = (UA_UInt16*)userdata;
(*asyncCounter)++;
}
START_TEST(Client_connect_async) {
UA_StatusCode retval;
UA_Client *client = UA_Client_new();
UA_ClientConfig *cc = UA_Client_getConfig(client);
UA_ClientConfig_setDefault(cc);
cc->stateCallback = currentState;
connected = false;
UA_Client_connectAsync(client, "opc.tcp://localhost:4840");
UA_Server_run_iterate(server, false);
UA_UInt32 reqId = 0;
UA_UInt16 asyncCounter = 0;
UA_BrowseRequest bReq;
UA_BrowseRequest_init (&bReq);
bReq.requestedMaxReferencesPerNode = 0;
bReq.nodesToBrowse = UA_BrowseDescription_new ();
bReq.nodesToBrowseSize = 1;
bReq.nodesToBrowse[0].nodeId = UA_NODEID_NUMERIC (0, UA_NS0ID_OBJECTSFOLDER);
bReq.nodesToBrowse[0].resultMask = UA_BROWSERESULTMASK_ALL; /* return everything */
/* Connected gets updated when client is connected */
do {
if(connected) {
/* If not connected requests are not sent */
UA_Client_sendAsyncBrowseRequest(client, &bReq, asyncBrowseCallback,
&asyncCounter, &reqId);
}
/* Give network a chance to process packet */
UA_realSleep(100);
/* Manual clock for unit tests */
UA_Server_run_iterate(server, false);
retval = UA_Client_run_iterate(client, 0);
/*fix infinite loop, but why is server occasionally shut down in Appveyor?!*/
if(retval == UA_STATUSCODE_BADCONNECTIONCLOSED)
break;
} while(reqId < 10);
UA_BrowseRequest_clear(&bReq);
ck_assert_uint_eq(connected, true);
ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD);
/* With default setting the client uses 7 iterations to connect */
ck_assert_uint_eq(asyncCounter, 5);
UA_Client_disconnectAsync(client);
while(connected) {
UA_Server_run_iterate(server, false);
UA_Client_run_iterate(client, 0);
}
UA_Client_delete (client);
}
END_TEST
UA_SecureChannelState abortState;
static void
abortSecureChannelConnect(UA_Client *client, UA_SecureChannelState channelState,
UA_SessionState sessionState, UA_StatusCode recoveryStatus) {
if(channelState >= abortState)
UA_Client_disconnectAsync(client);
}
/* Abort the connection by calling disconnect */
START_TEST(Client_connect_async_abort) {
UA_Client *client = UA_Client_new();
UA_ClientConfig *cc = UA_Client_getConfig(client);
UA_ClientConfig_setDefault(cc);
cc->stateCallback = abortSecureChannelConnect;
for(int i = 0; i < UA_SECURECHANNELSTATE_CLOSING; i++) {
abortState = (UA_SecureChannelState)i;
UA_Client_connectAsync(client, "opc.tcp://localhost:4840");
UA_SecureChannelState currentState;
do {
UA_Server_run_iterate(server, false);
UA_Client_run_iterate(client, 5);
UA_Client_getState(client, &currentState, NULL, NULL);
} while(currentState != UA_SECURECHANNELSTATE_CLOSED);
}
UA_Client_delete(client);
}
END_TEST
START_TEST(Client_no_connection) {
UA_Client *client = UA_Client_new();
UA_ClientConfig *cc = UA_Client_getConfig(client);
UA_ClientConfig_setDefault(cc);
cc->stateCallback = currentState;
connected = false;
UA_StatusCode retval = UA_Client_connectAsync(client, "opc.tcp://localhost:4840");
ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD);
/* Wait for the initial socket */
//UA_EventLoop *el = client->config.eventLoop;
while(client->channel.state != UA_SECURECHANNELSTATE_OPEN) {
//el->run(el, 0);
UA_Server_run_iterate(server, true);
UA_Client_run_iterate(client, 1);
}
/* Manually close the TCP connection */
UA_ConnectionManager *cm = client->channel.connectionManager;
cm->closeConnection(cm, client->channel.connectionId);
do {
UA_Server_run_iterate(server, false);
retval |= UA_Client_run_iterate(client, 0);
ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD);
} while(client->channel.state != UA_SECURECHANNELSTATE_OPEN);
UA_Client_disconnect(client);
UA_Client_delete(client);
}
END_TEST
START_TEST(Client_without_run_iterate) {
UA_Client *client = UA_Client_new();
UA_ClientConfig *cc = UA_Client_getConfig(client);
UA_ClientConfig_setDefault(cc);
cc->stateCallback = currentState;
connected = false;
UA_Client_connectAsync(client, "opc.tcp://localhost:4840");
UA_Client_delete(client);
}
END_TEST
START_TEST(Client_run_iterate) {
UA_StatusCode retval;
UA_Client *client = UA_Client_new();
UA_ClientConfig *cc = UA_Client_getConfig(client);
UA_ClientConfig_setDefault(cc);
cc->stateCallback = currentState;
connected = false;
retval = UA_Client_connectAsync(client, "opc.tcp://localhost:4840");
ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD);
while (!connected) {
UA_Server_run_iterate(server, false);
retval = UA_Client_run_iterate(client, 0);
ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD);
UA_realSleep(100);
}
UA_Client_disconnectAsync(client);
while(client->channel.state != UA_SECURECHANNELSTATE_CLOSED) {
UA_Server_run_iterate(server, false);
UA_Client_run_iterate(client, 0);
}
UA_Client_delete(client);
}
END_TEST
static Suite* testSuite_Client(void) {
Suite *s = suite_create("Client");
TCase *tc_client_connect = tcase_create("Client Connect Async");
tcase_add_checked_fixture(tc_client_connect, setup, teardown);
tcase_add_test(tc_client_connect, Client_connect_async);
tcase_add_test(tc_client_connect, Client_connect_async_abort);
tcase_add_test(tc_client_connect, Client_no_connection);
tcase_add_test(tc_client_connect, Client_without_run_iterate);
tcase_add_test(tc_client_connect, Client_run_iterate);
suite_add_tcase(s,tc_client_connect);
return s;
}
int main(void) {
Suite *s = testSuite_Client();
SRunner *sr = srunner_create(s);
srunner_set_fork_status(sr, CK_NOFORK);
srunner_run_all(sr, CK_NORMAL);
int number_failed = srunner_ntests_failed(sr);
srunner_free(sr);
return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
}

View File

@@ -0,0 +1,193 @@
/* 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/.
*
* Copyright 2022 (c) Fraunhofer IOSB (Author: Noel Graf)
*/
#include <open62541/client_config_default.h>
#include <open62541/server_config_default.h>
#include <open62541/client.h>
#include <open62541/client_highlevel.h>
#include <open62541/plugin/securitypolicy.h>
#include <open62541/plugin/pki_default.h>
#include <open62541/plugin/accesscontrol_default.h>
#include <open62541/server.h>
#include "client/ua_client_internal.h"
#include "ua_server_internal.h"
#include <check.h>
#include <stdlib.h>
#include "certificates.h"
#include "testing_clock.h"
#include "thread_wrapper.h"
UA_Server *server;
UA_Boolean running;
THREAD_HANDLE server_thread;
THREAD_CALLBACK(serverloop) {
while(running)
UA_Server_run_iterate(server, true);
return 0;
}
static void setup(void) {
running = true;
/* Load server certificate and private key */
UA_ByteString certificate;
certificate.length = SERVER_CERT_DER_LENGTH;
certificate.data = SERVER_CERT_DER_DATA;
UA_ByteString privateKey;
privateKey.length = SERVER_KEY_DER_LENGTH;
privateKey.data = SERVER_KEY_DER_DATA;
/* Load client certificate for authentication */
UA_ByteString certificate_client_auth;
certificate_client_auth.length = CLIENT_CERT_AUTH_DER_LENGTH;
certificate_client_auth.data = CLIENT_CERT_AUTH_DER_DATA;
/* Add client certificate to the trust list */
size_t trustListSize = 1;
UA_STACKARRAY(UA_ByteString, trustList, trustListSize);
trustList[0] = certificate_client_auth;
size_t issuerListSize = 0;
UA_ByteString *issuerList = NULL;
UA_ByteString *revocationList = NULL;
size_t revocationListSize = 0;
server = UA_Server_new();
ck_assert(server != NULL);
UA_ServerConfig *config = UA_Server_getConfig(server);
UA_ServerConfig_setDefaultWithSecurityPolicies(config, 4840, &certificate, &privateKey,
trustList, trustListSize,
issuerList, issuerListSize,
revocationList, revocationListSize);
UA_CertificateVerification_AcceptAll(&config->secureChannelPKI);
UA_Server_run_startup(server);
THREAD_CREATE(server_thread, serverloop);
}
static void teardown(void) {
running = false;
THREAD_JOIN(server_thread);
UA_Server_run_shutdown(server);
UA_Server_delete(server);
}
START_TEST(Client_connect_certificate) {
/* Load client certificate and private key for the SecureChannel */
UA_ByteString certificate;
certificate.length = CLIENT_CERT_DER_LENGTH;
certificate.data = CLIENT_CERT_DER_DATA;
UA_ByteString privateKey;
privateKey.length = CLIENT_KEY_DER_LENGTH;
privateKey.data = CLIENT_KEY_DER_DATA;
/* Load client certificate and private key for authentication */
UA_ByteString certificateAuth;
certificateAuth.length = CLIENT_CERT_AUTH_DER_LENGTH;
certificateAuth.data = CLIENT_CERT_AUTH_DER_DATA;
UA_ByteString privateKeyAuth;
privateKeyAuth.length = CLIENT_KEY_AUTH_DER_LENGTH;
privateKeyAuth.data = CLIENT_KEY_AUTH_DER_DATA;
UA_Client *client = UA_Client_new();
UA_ClientConfig *cc = UA_Client_getConfig(client);
/* Set securityMode and securityPolicyUri */
cc->securityMode = UA_MESSAGESECURITYMODE_SIGNANDENCRYPT;
cc->securityPolicyUri = UA_String_fromChars("http://opcfoundation.org/UA/SecurityPolicy#Aes128_Sha256_RsaOaep");
UA_ClientConfig_setDefaultEncryption(cc, certificate, privateKey,
NULL, 0, NULL, 0);
UA_CertificateVerification_AcceptAll(&cc->certificateVerification);
/* Set the ApplicationUri used in the certificate */
UA_String_clear(&cc->clientDescription.applicationUri);
cc->clientDescription.applicationUri = UA_STRING_ALLOC("urn:open62541.server.application");
UA_ClientConfig_setAuthenticationCert(cc, certificateAuth, privateKeyAuth);
UA_StatusCode retval = UA_Client_connect(client, "opc.tcp://localhost:4840");
ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD);
UA_Client_disconnect(client);
UA_Client_delete(client);
}
END_TEST
START_TEST(Client_connect_invalid_certificate) {
/* Load client certificate and private key for the SecureChannel */
UA_ByteString certificate;
certificate.length = CLIENT_CERT_DER_LENGTH;
certificate.data = CLIENT_CERT_DER_DATA;
UA_ByteString privateKey;
privateKey.length = CLIENT_KEY_DER_LENGTH;
privateKey.data = CLIENT_KEY_DER_DATA;
/* Load client certificate and private key for authentication */
UA_ByteString certificateAuth;
certificateAuth.length = CLIENT_CERT_DER_LENGTH;
certificateAuth.data = CLIENT_CERT_DER_DATA;
UA_ByteString privateKeyAuth;
privateKeyAuth.length = CLIENT_KEY_DER_LENGTH;
privateKeyAuth.data = CLIENT_KEY_DER_DATA;
UA_Client *client = UA_Client_new();
UA_ClientConfig *cc = UA_Client_getConfig(client);
/* Set securityMode and securityPolicyUri */
cc->securityMode = UA_MESSAGESECURITYMODE_SIGNANDENCRYPT;
cc->securityPolicyUri = UA_String_fromChars("http://opcfoundation.org/UA/SecurityPolicy#Aes128_Sha256_RsaOaep");
UA_ClientConfig_setDefaultEncryption(cc, certificate, privateKey,
NULL, 0, NULL, 0);
UA_CertificateVerification_AcceptAll(&cc->certificateVerification);
/* Set the ApplicationUri used in the certificate */
UA_String_clear(&cc->clientDescription.applicationUri);
cc->clientDescription.applicationUri = UA_STRING_ALLOC("urn:open62541.server.application");
UA_ClientConfig_setAuthenticationCert(cc, certificateAuth, privateKeyAuth);
UA_StatusCode retval = UA_Client_connect(client, "opc.tcp://localhost:4840");
/* openssl v.3 returns a different exit code than other versions. */
//ck_assert_uint_eq(retval, UA_STATUSCODE_BADCERTIFICATEUNTRUSTED);
ck_assert_uint_ne(retval, UA_STATUSCODE_GOOD);
UA_Client_disconnect(client);
UA_Client_delete(client);
}
END_TEST
static Suite* testSuite_Client(void) {
Suite *s = suite_create("Client");
TCase *tc_client = tcase_create("Client with Authentication");
tcase_add_checked_fixture(tc_client, setup, teardown);
tcase_add_test(tc_client, Client_connect_certificate);
tcase_add_test(tc_client, Client_connect_invalid_certificate);
suite_add_tcase(s,tc_client);
return s;
}
int main(void) {
Suite *s = testSuite_Client();
SRunner *sr = srunner_create(s);
srunner_set_fork_status(sr, CK_NOFORK);
srunner_run_all(sr,CK_NORMAL);
int number_failed = srunner_ntests_failed(sr);
srunner_free(sr);
return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
}

View File

@@ -0,0 +1,81 @@
/* 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/. */
#include <open62541/client_config_default.h>
#include <open62541/server_config_default.h>
#include "client/ua_client_internal.h"
#include <check.h>
#include <stdlib.h>
#include "thread_wrapper.h"
UA_Server *server;
UA_Boolean running;
THREAD_HANDLE server_thread;
THREAD_CALLBACK(serverloop) {
while(running)
UA_Server_run_iterate(server, true);
return 0;
}
static void setup(void) {
running = true;
server = UA_Server_new();
UA_ServerConfig_setDefault(UA_Server_getConfig(server));
UA_Server_run_startup(server);
THREAD_CREATE(server_thread, serverloop);
}
static void teardown(void) {
running = false;
THREAD_JOIN(server_thread);
UA_Server_run_shutdown(server);
UA_Server_delete(server);
}
START_TEST(Client_connect_badEndpointUrl) {
UA_Client *client = UA_Client_new();
UA_ClientConfig_setDefault(UA_Client_getConfig(client));
/* Use the internal API to force a bad DiscoveryUrl */
UA_String_clear(&client->config.endpointUrl);
UA_String_clear(&client->discoveryUrl);
client->config.endpointUrl = UA_STRING_ALLOC("opc.tcp://localhost:4840");
client->discoveryUrl = UA_STRING_ALLOC("abc://xxx:4840");
/* Open a Session when possible */
client->config.noSession = false;
UA_LOCK(&client->clientMutex);
connectSync(client);
UA_UNLOCK(&client->clientMutex);
ck_assert_uint_eq(client->connectStatus, UA_STATUSCODE_GOOD);
UA_Client_disconnect(client);
UA_Client_delete(client);
}
END_TEST
static Suite* testSuite_Client(void) {
Suite *s = suite_create("Client");
TCase *tc_client = tcase_create("Client Discovery");
tcase_add_checked_fixture(tc_client, setup, teardown);
tcase_add_test(tc_client, Client_connect_badEndpointUrl);
suite_add_tcase(s,tc_client);
return s;
}
int main(void) {
Suite *s = testSuite_Client();
SRunner *sr = srunner_create(s);
srunner_set_fork_status(sr, CK_NOFORK);
srunner_run_all(sr,CK_NORMAL);
int number_failed = srunner_ntests_failed(sr);
srunner_free(sr);
return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
}

View File

@@ -0,0 +1,165 @@
/* 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/.
*
* Copyright 2019 (c) Kalycito Infotech Private Limited
*
*/
#include <open62541/client.h>
#include <open62541/client_config_default.h>
#include <open62541/client_highlevel.h>
#include <open62541/plugin/securitypolicy.h>
#include <open62541/plugin/pki_default.h>
#include <open62541/server.h>
#include <open62541/server_config_default.h>
#include "client/ua_client_internal.h"
#include "ua_server_internal.h"
#include <stdio.h>
#include <stdlib.h>
#include "../encryption/certificates.h"
#include "check.h"
#include "testing_clock.h"
#include "testing_networklayers.h"
#include "thread_wrapper.h"
UA_Server *server;
UA_Boolean running;
THREAD_HANDLE server_thread;
THREAD_CALLBACK(serverloop) {
while(running)
UA_Server_run_iterate(server, true);
return 0;
}
static void setup(void) {
running = true;
/* Load certificate and private key */
UA_ByteString certificate;
certificate.length = CERT_DER_LENGTH;
certificate.data = CERT_DER_DATA;
UA_ByteString privateKey;
privateKey.length = KEY_DER_LENGTH;
privateKey.data = KEY_DER_DATA;
size_t trustListSize = 0;
UA_ByteString *trustList = NULL;
size_t issuerListSize = 0;
UA_ByteString *issuerList = NULL;
UA_ByteString *revocationList = NULL;
size_t revocationListSize = 0;
server = UA_Server_new();
ck_assert(server != NULL);
UA_ServerConfig *config = UA_Server_getConfig(server);
UA_ServerConfig_setDefaultWithSecurityPolicies(config, 4840, &certificate, &privateKey,
trustList, trustListSize,
issuerList, issuerListSize,
revocationList, revocationListSize);
UA_CertificateVerification_AcceptAll(&config->secureChannelPKI);
UA_CertificateVerification_AcceptAll(&config->sessionPKI);
/* Set the ApplicationUri used in the certificate */
UA_String_clear(&config->applicationDescription.applicationUri);
config->applicationDescription.applicationUri =
UA_STRING_ALLOC("urn:unconfigured:application");
UA_Server_run_startup(server);
THREAD_CREATE(server_thread, serverloop);
}
static void teardown(void) {
running = false;
THREAD_JOIN(server_thread);
UA_Server_run_shutdown(server);
UA_Server_delete(server);
}
/* Test re-activating a Session on a new SecureChannel */
START_TEST(encryption_reconnect_session) {
UA_Client *client = NULL;
UA_ByteString *trustList = NULL;
size_t trustListSize = 0;
UA_ByteString *revocationList = NULL;
size_t revocationListSize = 0;
/* Load certificate and private key */
UA_ByteString certificate;
certificate.length = CERT_DER_LENGTH;
certificate.data = CERT_DER_DATA;
ck_assert_uint_ne(certificate.length, 0);
UA_ByteString privateKey;
privateKey.length = KEY_DER_LENGTH;
privateKey.data = KEY_DER_DATA;
ck_assert_uint_ne(privateKey.length, 0);
/* Secure client initialization */
client = UA_Client_new();
UA_ClientConfig *cc = UA_Client_getConfig(client);
UA_ClientConfig_setDefaultEncryption(cc, certificate, privateKey,
trustList, trustListSize,
revocationList, revocationListSize);
cc->certificateVerification.clear(&cc->certificateVerification);
UA_CertificateVerification_AcceptAll(&cc->certificateVerification);
cc->securityPolicyUri =
UA_STRING_ALLOC("http://opcfoundation.org/UA/SecurityPolicy#Basic256Sha256");
ck_assert(client != NULL);
/* Secure client connect */
UA_StatusCode retval = UA_Client_connect(client, "opc.tcp://localhost:4840");
ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD);
UA_Variant val;
UA_Variant_init(&val);
UA_NodeId nodeId = UA_NODEID_NUMERIC(0, UA_NS0ID_SERVER_SERVERSTATUS_STATE);
retval = UA_Client_readValueAttribute(client, nodeId, &val);
ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD);
UA_Variant_clear(&val);
UA_NodeId oldAuthToken = client->authenticationToken;
/* Close the SecureChannel without closing the session */
UA_Client_disconnectSecureChannel(client);
/* Reconnect. This reuses the previous session. */
retval = UA_Client_connect(client, "opc.tcp://localhost:4840");
ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD);
/* Read the variable. That reactivates the session first. */
retval = UA_Client_readValueAttribute(client, nodeId, &val);
ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD);
UA_Variant_clear(&val);
ck_assert(UA_NodeId_equal(&oldAuthToken, &client->authenticationToken));
UA_Client_disconnect(client);
UA_Client_delete(client);
}
END_TEST
static Suite* testSuite_encryption(void) {
Suite *s = suite_create("Encryption");
TCase *tc_encryption = tcase_create("Encryption basic256sha256");
tcase_add_checked_fixture(tc_encryption, setup, teardown);
tcase_add_test(tc_encryption, encryption_reconnect_session);
suite_add_tcase(s,tc_encryption);
return s;
}
int main(void) {
Suite *s = testSuite_encryption();
SRunner *sr = srunner_create(s);
srunner_set_fork_status(sr, CK_NOFORK);
srunner_run_all(sr,CK_NORMAL);
int number_failed = srunner_ntests_failed(sr);
srunner_free(sr);
return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,647 @@
/* 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/.
*
* Copyright 2018 (c) basysKom GmbH <opensource@basyskom.com> (Author: Peter Rustler)
*/
#include <open62541/client.h>
#include <open62541/client_config_default.h>
#include <open62541/plugin/historydata/history_data_backend.h>
#include <open62541/plugin/historydata/history_data_backend_memory.h>
#include <open62541/plugin/historydata/history_data_gathering_default.h>
#include <open62541/plugin/historydata/history_database_default.h>
#include <open62541/plugin/historydatabase.h>
#include <open62541/server.h>
#include <open62541/server_config_default.h>
#include "client/ua_client_internal.h"
#include <check.h>
#include <stdlib.h>
#include <stddef.h>
#include <stdio.h>
#include "testing_clock.h"
#include "testing_networklayers.h"
#include "thread_wrapper.h"
#include "historical_read_test_data.h"
static UA_Server *server;
static UA_HistoryDataGathering *gathering;
static UA_Boolean running;
static THREAD_HANDLE server_thread;
static UA_Client *client;
static UA_NodeId parentNodeId;
static UA_NodeId parentReferenceNodeId;
static UA_NodeId outNodeId;
static UA_HistoryDataBackend serverBackend;
// to receive data after we inserted data, we need in datavalue more space
struct ReceiveTupel {
UA_DateTime timestamp;
UA_Int64 value;
};
static const size_t receivedDataSize = (sizeof(testData) / sizeof(testData[0])) + 10;
static struct ReceiveTupel receivedTestData[(sizeof(testData) / sizeof(testData[0])) + 10];
static size_t receivedTestDataPos;
THREAD_CALLBACK(serverloop) {
while(running)
UA_Server_run_iterate(server, true);
return 0;
}
static UA_Boolean
fillHistoricalDataBackend(UA_HistoryDataBackend backend);
static void resetReceiveBuffer(void) {
receivedTestDataPos = 0;
memset(receivedTestData, 0, sizeof(receivedTestData));
}
static void fillInt64DataValue(UA_DateTime timestamp, UA_Int64 value,
UA_DataValue *dataValue) {
UA_DataValue_init(dataValue);
dataValue->hasValue = true;
UA_Int64 d = value;
UA_Variant_setScalarCopy(&dataValue->value, &d, &UA_TYPES[UA_TYPES_INT64]);
dataValue->hasSourceTimestamp = true;
dataValue->sourceTimestamp = timestamp;
dataValue->hasServerTimestamp = true;
dataValue->serverTimestamp = timestamp;
dataValue->hasStatus = true;
dataValue->status = UA_STATUSCODE_GOOD;
}
static void setup(void) {
running = true;
server = UA_Server_new();
ck_assert(server != NULL);
UA_ServerConfig *config = UA_Server_getConfig(server);
UA_ServerConfig_setDefault(config);
#ifdef UA_ENABLE_HISTORIZING
resetReceiveBuffer();
gathering = (UA_HistoryDataGathering*)UA_calloc(1, sizeof(UA_HistoryDataGathering));
*gathering = UA_HistoryDataGathering_Default(1);
config->historyDatabase = UA_HistoryDatabase_default(*gathering);
#endif
UA_StatusCode retval = UA_Server_run_startup(server);
ck_assert_str_eq(UA_StatusCode_name(retval), UA_StatusCode_name(UA_STATUSCODE_GOOD));
THREAD_CREATE(server_thread, serverloop);
/* Define the attribute of the uint32 variable node */
UA_VariableAttributes attr = UA_VariableAttributes_default;
UA_UInt32 myUint32 = 40;
UA_Variant_setScalar(&attr.value, &myUint32, &UA_TYPES[UA_TYPES_UINT32]);
attr.description = UA_LOCALIZEDTEXT("en-US","the answer");
attr.displayName = UA_LOCALIZEDTEXT("en-US","the answer");
attr.dataType = UA_TYPES[UA_TYPES_UINT32].typeId;
attr.accessLevel = UA_ACCESSLEVELMASK_READ | UA_ACCESSLEVELMASK_WRITE | UA_ACCESSLEVELMASK_HISTORYREAD | UA_ACCESSLEVELMASK_HISTORYWRITE;
attr.historizing = true;
/* Add the variable node to the information model */
UA_NodeId uint32NodeId = UA_NODEID_STRING(1, "the.answer");
UA_QualifiedName uint32Name = UA_QUALIFIEDNAME(1, "the answer");
parentNodeId = UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER);
parentReferenceNodeId = UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES);
UA_NodeId_init(&outNodeId);
ck_assert_uint_eq(UA_Server_addVariableNode(server,
uint32NodeId,
parentNodeId,
parentReferenceNodeId,
uint32Name,
UA_NODEID_NUMERIC(0, UA_NS0ID_BASEDATAVARIABLETYPE),
attr,
NULL,
&outNodeId)
, UA_STATUSCODE_GOOD);
UA_HistorizingNodeIdSettings setting;
serverBackend = UA_HistoryDataBackend_Memory(1, 100);
setting.historizingBackend = serverBackend;
setting.maxHistoryDataResponseSize = 100;
setting.historizingUpdateStrategy = UA_HISTORIZINGUPDATESTRATEGY_USER;
retval = gathering->registerNodeId(server, gathering->context, &outNodeId, setting);
ck_assert_str_eq(UA_StatusCode_name(retval), UA_StatusCode_name(UA_STATUSCODE_GOOD));
ck_assert(fillHistoricalDataBackend(setting.historizingBackend));
client = UA_Client_new();
UA_ClientConfig_setDefault(UA_Client_getConfig(client));
retval = UA_Client_connect(client, "opc.tcp://localhost:4840");
ck_assert_str_eq(UA_StatusCode_name(retval), UA_StatusCode_name(UA_STATUSCODE_GOOD));
}
static void
teardown(void) {
/* cleanup */
UA_HistoryDataBackend_Memory_clear(&serverBackend);
UA_Client_disconnect(client);
UA_Client_delete(client);
UA_NodeId_clear(&parentNodeId);
UA_NodeId_clear(&parentReferenceNodeId);
UA_NodeId_clear(&outNodeId);
running = false;
THREAD_JOIN(server_thread);
UA_Server_run_shutdown(server);
UA_Server_delete(server);
UA_free(gathering);
}
static UA_Boolean
fillHistoricalDataBackend(UA_HistoryDataBackend backend) {
fprintf(stderr, "Adding to historical data backend: ");
for (size_t i = 0; i < testDataSize; ++i) {
fprintf(stderr, "%lld, ", (long long)testData[i]);
UA_DataValue value;
fillInt64DataValue(testData[i], testData[i], &value);
if (backend.serverSetHistoryData(server, backend.context, NULL, NULL,
&outNodeId, UA_FALSE, &value) != UA_STATUSCODE_GOOD) {
fprintf(stderr, "\n");
UA_DataValue_clear(&value);
return false;
}
UA_DataValue_clear(&value);
}
fprintf(stderr, "\n");
return true;
}
static UA_Boolean
checkTestData(UA_Boolean inverse, UA_DateTime *dataA,
struct ReceiveTupel *dataB, size_t dataSize) {
for (size_t i = 0; i < dataSize; ++i) {
if (!inverse && dataA[i] != dataB[i].timestamp)
return false;
if (inverse && dataA[i] != dataB[dataSize-i-1].timestamp)
return false;
}
return true;
}
static UA_Boolean
checkModifiedData(UA_DateTime *dataA, size_t dataASize,
struct ReceiveTupel *dataB, size_t dataBSize) {
for (size_t i = 0; i < dataBSize; ++i) {
UA_Boolean found = UA_FALSE;
for (size_t j = 0; j < dataASize; ++j) {
if (dataA[j] == dataB[i].timestamp)
found = UA_TRUE;
}
if (found && dataB[i].timestamp == dataB[i].value) {
return false;
}
if (!found && dataB[i].timestamp != dataB[i].value) {
return false;
}
}
return true;
}
static UA_Boolean
receiveCallback(UA_Client *clt,
const UA_NodeId *nodeId,
UA_Boolean moreDataAvailable,
const UA_ExtensionObject *_data,
void *callbackContext) {
UA_HistoryData *data = (UA_HistoryData*)_data->content.decoded.data;
fprintf(stderr, "Received %lu at pos %lu. moreDataAvailable %d. Data: ", (unsigned long)data->dataValuesSize, (unsigned long)receivedTestDataPos, moreDataAvailable);
if (receivedTestDataPos + data->dataValuesSize > receivedDataSize)
return false;
for (size_t i = 0; i < data->dataValuesSize; ++i) {
receivedTestData[i+receivedTestDataPos].timestamp = data->dataValues[i].sourceTimestamp;
receivedTestData[i+receivedTestDataPos].value = *((UA_Int64*)data->dataValues[i].value.data);
fprintf(stderr, "%lld/%lld, ",
(long long)receivedTestData[i+receivedTestDataPos].timestamp,
(long long)receivedTestData[i+receivedTestDataPos].value);
}
fprintf(stderr, "\n");
receivedTestDataPos += data->dataValuesSize;
return true;
}
START_TEST(Client_HistorizingReadRawAll) {
UA_StatusCode ret = UA_Client_HistoryRead_raw(client,
&outNodeId,
receiveCallback,
TESTDATA_START_TIME,
TESTDATA_STOP_TIME,
UA_STRING_NULL,
false,
100,
UA_TIMESTAMPSTORETURN_BOTH,
(void*)false);
ck_assert_str_eq(UA_StatusCode_name(ret), UA_StatusCode_name(UA_STATUSCODE_GOOD));
ck_assert_uint_eq(testDataSize, receivedTestDataPos);
ck_assert(checkTestData(false, testData, receivedTestData, testDataSize));
}
END_TEST
START_TEST(Client_HistorizingReadRawOne) {
UA_StatusCode ret = UA_Client_HistoryRead_raw(client,
&outNodeId,
receiveCallback,
TESTDATA_START_TIME,
TESTDATA_STOP_TIME,
UA_STRING_NULL,
false,
1,
UA_TIMESTAMPSTORETURN_BOTH,
(void*)false);
ck_assert_str_eq(UA_StatusCode_name(ret), UA_StatusCode_name(UA_STATUSCODE_GOOD));
ck_assert_uint_eq(testDataSize, receivedTestDataPos);
ck_assert(checkTestData(false, testData, receivedTestData, testDataSize));
}
END_TEST
START_TEST(Client_HistorizingReadRawTwo)
{
UA_StatusCode ret = UA_Client_HistoryRead_raw(client,
&outNodeId,
receiveCallback,
TESTDATA_START_TIME,
TESTDATA_STOP_TIME,
UA_STRING_NULL,
false,
2,
UA_TIMESTAMPSTORETURN_BOTH,
(void*)false);
ck_assert_str_eq(UA_StatusCode_name(ret), UA_StatusCode_name(UA_STATUSCODE_GOOD));
ck_assert_uint_eq(testDataSize, receivedTestDataPos);
ck_assert(checkTestData(false, testData, receivedTestData, testDataSize));
}
END_TEST
START_TEST(Client_HistorizingReadRawAllInv)
{
UA_StatusCode ret = UA_Client_HistoryRead_raw(client,
&outNodeId,
receiveCallback,
TESTDATA_STOP_TIME,
TESTDATA_START_TIME,
UA_STRING_NULL,
false,
100,
UA_TIMESTAMPSTORETURN_BOTH,
(void*)true);
ck_assert_str_eq(UA_StatusCode_name(ret), UA_StatusCode_name(UA_STATUSCODE_GOOD));
ck_assert_uint_eq(testDataSize, receivedTestDataPos);
ck_assert(checkTestData(true, testData, receivedTestData, testDataSize));
}
END_TEST
START_TEST(Client_HistorizingReadRawOneInv)
{
UA_StatusCode ret = UA_Client_HistoryRead_raw(client,
&outNodeId,
receiveCallback,
TESTDATA_STOP_TIME,
TESTDATA_START_TIME,
UA_STRING_NULL,
false,
1,
UA_TIMESTAMPSTORETURN_BOTH,
(void*)true);
ck_assert_str_eq(UA_StatusCode_name(ret), UA_StatusCode_name(UA_STATUSCODE_GOOD));
ck_assert_uint_eq(testDataSize, receivedTestDataPos);
ck_assert(checkTestData(true, testData, receivedTestData, testDataSize));
}
END_TEST
START_TEST(Client_HistorizingReadRawTwoInv)
{
UA_StatusCode ret = UA_Client_HistoryRead_raw(client,
&outNodeId,
receiveCallback,
TESTDATA_STOP_TIME,
TESTDATA_START_TIME,
UA_STRING_NULL,
false,
2,
UA_TIMESTAMPSTORETURN_BOTH,
(void*)true);
ck_assert_str_eq(UA_StatusCode_name(ret), UA_StatusCode_name(UA_STATUSCODE_GOOD));
ck_assert_uint_eq(testDataSize, receivedTestDataPos);
ck_assert(checkTestData(true, testData, receivedTestData, testDataSize));
}
END_TEST
START_TEST(Client_HistorizingInsertRawSuccess)
{
UA_StatusCode ret = UA_Client_HistoryRead_raw(client,
&outNodeId,
receiveCallback,
TESTDATA_START_TIME,
TESTDATA_STOP_TIME,
UA_STRING_NULL,
false,
100,
UA_TIMESTAMPSTORETURN_BOTH,
(void*)false);
ck_assert_str_eq(UA_StatusCode_name(ret), UA_StatusCode_name(UA_STATUSCODE_GOOD));
ck_assert(checkTestData(false, testData, receivedTestData, testDataSize));
resetReceiveBuffer();
// insert values to the database
for (size_t i = 0; i < testInsertDataSuccessSize; ++i) {
UA_DataValue value;
fillInt64DataValue(testInsertDataSuccess[i], 0, &value);
ret = UA_Client_HistoryUpdate_insert(client, &outNodeId, &value);
ck_assert_str_eq(UA_StatusCode_name(ret), UA_StatusCode_name(UA_STATUSCODE_GOOD));
UA_DataValue_clear(&value);
}
// check result
ret = UA_Client_HistoryRead_raw(client,
&outNodeId,
receiveCallback,
TESTDATA_START_TIME,
TESTDATA_STOP_TIME,
UA_STRING_NULL,
false,
100,
UA_TIMESTAMPSTORETURN_BOTH,
(void*)false);
ck_assert_str_eq(UA_StatusCode_name(ret), UA_StatusCode_name(UA_STATUSCODE_GOOD));
ck_assert_uint_eq(receivedTestDataPos, testInsertResultDataSize);
ck_assert(checkTestData(false, testInsertResultData, receivedTestData, receivedTestDataPos));
ck_assert(checkModifiedData(testInsertDataSuccess, testInsertDataSuccessSize, receivedTestData, receivedTestDataPos));
}
END_TEST
START_TEST(Client_HistorizingReplaceRawSuccess)
{
UA_StatusCode ret = UA_Client_HistoryRead_raw(client,
&outNodeId,
receiveCallback,
TESTDATA_START_TIME,
TESTDATA_STOP_TIME,
UA_STRING_NULL,
false,
100,
UA_TIMESTAMPSTORETURN_BOTH,
(void*)false);
ck_assert_str_eq(UA_StatusCode_name(ret), UA_StatusCode_name(UA_STATUSCODE_GOOD));
ck_assert(checkTestData(false, testData, receivedTestData, testDataSize));
resetReceiveBuffer();
// replace values to the database
for (size_t i = 0; i < testReplaceDataSuccessSize; ++i) {
UA_DataValue value;
fillInt64DataValue(testReplaceDataSuccess[i], 0, &value);
ret = UA_Client_HistoryUpdate_replace(client, &outNodeId, &value);
ck_assert_str_eq(UA_StatusCode_name(ret), UA_StatusCode_name(UA_STATUSCODE_GOOD));
UA_DataValue_clear(&value);
}
// check result
ret = UA_Client_HistoryRead_raw(client,
&outNodeId,
receiveCallback,
TESTDATA_START_TIME,
TESTDATA_STOP_TIME,
UA_STRING_NULL,
false,
100,
UA_TIMESTAMPSTORETURN_BOTH,
(void*)false);
ck_assert_str_eq(UA_StatusCode_name(ret), UA_StatusCode_name(UA_STATUSCODE_GOOD));
ck_assert_uint_eq(receivedTestDataPos, testDataSize);
ck_assert(checkTestData(false, testData, receivedTestData, receivedTestDataPos));
ck_assert(checkModifiedData(testReplaceDataSuccess, testReplaceDataSuccessSize, receivedTestData, receivedTestDataPos));
}
END_TEST
START_TEST(Client_HistorizingUpdateRawSuccess)
{
UA_StatusCode ret = UA_Client_HistoryRead_raw(client,
&outNodeId,
receiveCallback,
TESTDATA_START_TIME,
TESTDATA_STOP_TIME,
UA_STRING_NULL,
false,
100,
UA_TIMESTAMPSTORETURN_BOTH,
(void*)false);
ck_assert_str_eq(UA_StatusCode_name(ret), UA_StatusCode_name(UA_STATUSCODE_GOOD));
ck_assert(checkTestData(false, testData, receivedTestData, testDataSize));
resetReceiveBuffer();
// insert values to the database
for (size_t i = 0; i < testInsertDataSuccessSize; ++i) {
UA_DataValue value;
fillInt64DataValue(testInsertDataSuccess[i], 0, &value);
ret = UA_Client_HistoryUpdate_update(client, &outNodeId, &value);
ck_assert_str_eq(UA_StatusCode_name(ret), UA_StatusCode_name(UA_STATUSCODE_GOODENTRYINSERTED));
UA_DataValue_clear(&value);
}
// replace values to the database
for (size_t i = 0; i < testReplaceDataSuccessSize; ++i) {
UA_DataValue value;
fillInt64DataValue(testReplaceDataSuccess[i], 0, &value);
ret = UA_Client_HistoryUpdate_update(client, &outNodeId, &value);
ck_assert_str_eq(UA_StatusCode_name(ret), UA_StatusCode_name(UA_STATUSCODE_GOODENTRYREPLACED));
UA_DataValue_clear(&value);
}
// check result
ret = UA_Client_HistoryRead_raw(client,
&outNodeId,
receiveCallback,
TESTDATA_START_TIME,
TESTDATA_STOP_TIME,
UA_STRING_NULL,
false,
100,
UA_TIMESTAMPSTORETURN_BOTH,
(void*)false);
ck_assert_str_eq(UA_StatusCode_name(ret), UA_StatusCode_name(UA_STATUSCODE_GOOD));
ck_assert_uint_eq(receivedTestDataPos, testInsertResultDataSize);
ck_assert(checkTestData(false, testInsertResultData, receivedTestData, receivedTestDataPos));
}
END_TEST
START_TEST(Client_HistorizingDeleteRaw)
{
for (size_t i = 0; i < testDeleteRangeDataSize; ++i) {
fprintf(stderr, "Client_HistorizingDeleteRaw: Testing %lu: {%lld, %lld, %lu, %s}\n",
(unsigned long)i,
(long long)testDeleteRangeData[i].start,
(long long)testDeleteRangeData[i].end,
(unsigned long)testDeleteRangeData[i].historySize,
UA_StatusCode_name(testDeleteRangeData[i].statusCode));
resetReceiveBuffer();
serverBackend.removeDataValue(server,
serverBackend.context,
NULL,
NULL,
&outNodeId,
TESTDATA_START_TIME,
TESTDATA_STOP_TIME);
fillHistoricalDataBackend(serverBackend);
// check result
UA_StatusCode ret = UA_Client_HistoryRead_raw(client,
&outNodeId,
receiveCallback,
TESTDATA_START_TIME,
TESTDATA_STOP_TIME,
UA_STRING_NULL,
false,
100,
UA_TIMESTAMPSTORETURN_BOTH,
(void*)false);
ck_assert_str_eq(UA_StatusCode_name(ret), UA_StatusCode_name(UA_STATUSCODE_GOOD));
ck_assert(checkTestData(false, testData, receivedTestData, receivedTestDataPos));
resetReceiveBuffer();
ret = UA_Client_HistoryUpdate_deleteRaw(client,
&outNodeId,
testDeleteRangeData[i].start,
testDeleteRangeData[i].end);
if (ret != testDeleteRangeData[i].statusCode)
fprintf(stderr, "Error: ret %s != statusCode%s\n", UA_StatusCode_name(ret), UA_StatusCode_name(testDeleteRangeData[i].statusCode));
ck_assert_str_eq(UA_StatusCode_name(ret), UA_StatusCode_name(testDeleteRangeData[i].statusCode));
// check result
ret = UA_Client_HistoryRead_raw(client,
&outNodeId,
receiveCallback,
TESTDATA_START_TIME,
TESTDATA_STOP_TIME,
UA_STRING_NULL,
false,
100,
UA_TIMESTAMPSTORETURN_BOTH,
(void*)false);
ck_assert_str_eq(UA_StatusCode_name(ret), UA_StatusCode_name(UA_STATUSCODE_GOOD));
if (receivedTestDataPos != testDeleteRangeData[i].historySize)
fprintf(stderr, "Error: receivedTestDataPos != testDeleteRangeData[i].historySize\n");
ck_assert_uint_eq(receivedTestDataPos, testDeleteRangeData[i].historySize);
}
}
END_TEST
START_TEST(Client_HistorizingInsertRawFail)
{
UA_StatusCode ret = UA_Client_HistoryRead_raw(client,
&outNodeId,
receiveCallback,
TESTDATA_START_TIME,
TESTDATA_STOP_TIME,
UA_STRING_NULL,
false,
100,
UA_TIMESTAMPSTORETURN_BOTH,
(void*)false);
ck_assert_str_eq(UA_StatusCode_name(ret), UA_StatusCode_name(UA_STATUSCODE_GOOD));
ck_assert(checkTestData(false, testData, receivedTestData, testDataSize));
resetReceiveBuffer();
// insert values to the database
for (size_t i = 0; i < testReplaceDataSuccessSize; ++i) {
UA_DataValue value;
fillInt64DataValue(testReplaceDataSuccess[i], 0, &value);
ret = UA_Client_HistoryUpdate_insert(client, &outNodeId, &value);
ck_assert_str_eq(UA_StatusCode_name(ret), UA_StatusCode_name(UA_STATUSCODE_BADENTRYEXISTS));
UA_DataValue_clear(&value);
}
// check result
ret = UA_Client_HistoryRead_raw(client,
&outNodeId,
receiveCallback,
TESTDATA_START_TIME,
TESTDATA_STOP_TIME,
UA_STRING_NULL,
false,
100,
UA_TIMESTAMPSTORETURN_BOTH,
(void*)false);
ck_assert_str_eq(UA_StatusCode_name(ret), UA_StatusCode_name(UA_STATUSCODE_GOOD));
ck_assert_uint_eq(receivedTestDataPos, testDataSize);
ck_assert(checkTestData(false, testData, receivedTestData, receivedTestDataPos));
ck_assert(checkModifiedData(NULL, 0, receivedTestData, receivedTestDataPos));
}
END_TEST
START_TEST(Client_HistorizingReplaceRawFail)
{
UA_StatusCode ret = UA_Client_HistoryRead_raw(client,
&outNodeId,
receiveCallback,
TESTDATA_START_TIME,
TESTDATA_STOP_TIME,
UA_STRING_NULL,
false,
100,
UA_TIMESTAMPSTORETURN_BOTH,
(void*)false);
ck_assert_str_eq(UA_StatusCode_name(ret), UA_StatusCode_name(UA_STATUSCODE_GOOD));
ck_assert(checkTestData(false, testData, receivedTestData, testDataSize));
resetReceiveBuffer();
// replace values to the database
for (size_t i = 0; i < testInsertDataSuccessSize; ++i) {
UA_DataValue value;
fillInt64DataValue(testInsertDataSuccess[i], 0, &value);
ret = UA_Client_HistoryUpdate_replace(client, &outNodeId, &value);
ck_assert_str_eq(UA_StatusCode_name(ret), UA_StatusCode_name(UA_STATUSCODE_BADNOENTRYEXISTS));
UA_DataValue_clear(&value);
}
// check result
ret = UA_Client_HistoryRead_raw(client,
&outNodeId,
receiveCallback,
TESTDATA_START_TIME,
TESTDATA_STOP_TIME,
UA_STRING_NULL,
false,
100,
UA_TIMESTAMPSTORETURN_BOTH,
(void*)false);
ck_assert_str_eq(UA_StatusCode_name(ret), UA_StatusCode_name(UA_STATUSCODE_GOOD));
ck_assert_uint_eq(receivedTestDataPos, testDataSize);
ck_assert(checkTestData(false, testData, receivedTestData, receivedTestDataPos));
ck_assert(checkModifiedData(NULL, 0, receivedTestData, receivedTestDataPos));
}
END_TEST
static Suite *
testSuite_Client(void) {
Suite *s = suite_create("Client Historical Data");
TCase *tc_client = tcase_create("Client Historical Data read_raw");
tcase_add_checked_fixture(tc_client, setup, teardown);
tcase_add_test(tc_client, Client_HistorizingReadRawAll);
tcase_add_test(tc_client, Client_HistorizingReadRawOne);
tcase_add_test(tc_client, Client_HistorizingReadRawTwo);
tcase_add_test(tc_client, Client_HistorizingReadRawAllInv);
tcase_add_test(tc_client, Client_HistorizingReadRawOneInv);
tcase_add_test(tc_client, Client_HistorizingReadRawTwoInv);
tcase_add_test(tc_client, Client_HistorizingInsertRawSuccess);
tcase_add_test(tc_client, Client_HistorizingReplaceRawSuccess);
tcase_add_test(tc_client, Client_HistorizingUpdateRawSuccess);
tcase_add_test(tc_client, Client_HistorizingDeleteRaw);
tcase_add_test(tc_client, Client_HistorizingInsertRawFail);
tcase_add_test(tc_client, Client_HistorizingReplaceRawFail);
suite_add_tcase(s, tc_client);
return s;
}
int main(void) {
Suite *s = testSuite_Client();
SRunner *sr = srunner_create(s);
srunner_set_fork_status(sr, CK_NOFORK);
srunner_run_all(sr,CK_NORMAL);
int number_failed = srunner_ntests_failed(sr);
srunner_free(sr);
return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
}

View File

@@ -0,0 +1,242 @@
/* 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/. */
#include <open62541/client.h>
#include <open62541/client_config_default.h>
#include <open62541/client_highlevel.h>
#include <open62541/server.h>
#include <open62541/server_config_default.h>
#include "client/ua_client_internal.h"
#include <check.h>
#include <stdlib.h>
#include "testing_clock.h"
#include "thread_wrapper.h"
UA_Server *server;
UA_Boolean running;
THREAD_HANDLE server_thread;
THREAD_CALLBACK(serverloop) {
while(running)
UA_Server_run_iterate(server, true);
return 0;
}
static void runServer(void) {
running = true;
THREAD_CREATE(server_thread, serverloop);
}
static void pauseServer(void) {
running = false;
THREAD_JOIN(server_thread);
}
static void setup(void) {
server = UA_Server_new();
ck_assert(server != NULL);
UA_ServerConfig_setDefault(UA_Server_getConfig(server));
UA_Server_run_startup(server);
runServer();
}
static void teardown(void) {
pauseServer();
UA_Server_run_shutdown(server);
UA_Server_delete(server);
}
START_TEST(SecureChannel_timeout_max) {
UA_Client *client = UA_Client_new();
UA_ClientConfig_setDefault(UA_Client_getConfig(client));
UA_StatusCode retval = UA_Client_connect(client, "opc.tcp://localhost:4840");
ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD);
UA_ClientConfig *cconfig = UA_Client_getConfig(client);
UA_fakeSleep(cconfig->secureChannelLifeTime);
UA_Variant val;
UA_NodeId nodeId = UA_NODEID_NUMERIC(0, UA_NS0ID_SERVER_SERVERSTATUS_STATE);
retval = UA_Client_readValueAttribute(client, nodeId, &val);
ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD);
UA_Variant_clear(&val);
UA_Client_disconnect(client);
UA_Client_delete(client);
}
END_TEST
START_TEST(SecureChannel_renew) {
UA_Client *client = UA_Client_new();
UA_ClientConfig_setDefault(UA_Client_getConfig(client));
UA_StatusCode retval = UA_Client_connect(client, "opc.tcp://localhost:4840");
ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD);
pauseServer();
/* Get the channel id */
UA_UInt32 channelId = client->channel.securityToken.channelId;
/* Renew the channel for the first time */
UA_fakeSleep((UA_UInt32)(client->channel.securityToken.revisedLifetime * 0.8));
UA_Client_run_iterate(client, 1);
UA_Server_run_iterate(server, false);
UA_Client_run_iterate(client, 1);
UA_Server_run_iterate(server, false);
/* Renew the channel for the second time */
UA_fakeSleep((UA_UInt32)(client->channel.securityToken.revisedLifetime * 0.8));
UA_Client_run_iterate(client, 1);
UA_Server_run_iterate(server, false);
UA_Client_run_iterate(client, 1);
UA_Server_run_iterate(server, false);
/* We are still on the same channel */
ck_assert_uint_eq(channelId, client->channel.securityToken.channelId);
runServer();
UA_Client_disconnect(client);
UA_Client_delete(client);
}
END_TEST
/* Send the next message after the securechannel timed out */
START_TEST(SecureChannel_timeout_fail) {
UA_Client *client = UA_Client_new();
UA_ClientConfig_setDefault(UA_Client_getConfig(client));
UA_StatusCode retval = UA_Client_connect(client, "opc.tcp://localhost:4840");
ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD);
UA_ClientConfig *cconfig = UA_Client_getConfig(client);
UA_fakeSleep(cconfig->secureChannelLifeTime + 1);
UA_realSleep(200 + 1); // UA_MAXTIMEOUT+1 wait to be sure UA_Server_run_iterate can be completely executed
UA_Variant val;
UA_Variant_init(&val);
UA_NodeId nodeId = UA_NODEID_NUMERIC(0, UA_NS0ID_SERVER_SERVERSTATUS_STATE);
retval = UA_Client_readValueAttribute(client, nodeId, &val);
ck_assert(retval != UA_STATUSCODE_GOOD);
UA_Variant_clear(&val);
UA_Client_disconnect(client);
UA_Client_delete(client);
}
END_TEST
/* Send an async message and receive the response when the securechannel timed out */
START_TEST(SecureChannel_networkfail) {
UA_Client *client = UA_Client_new();
UA_ClientConfig_setDefault(UA_Client_getConfig(client));
UA_StatusCode retval = UA_Client_connect(client, "opc.tcp://localhost:4840");
ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD);
UA_ReadRequest rq;
UA_ReadRequest_init(&rq);
UA_ReadValueId rvi;
UA_ReadValueId_init(&rvi);
rvi.attributeId = UA_ATTRIBUTEID_VALUE;
rvi.nodeId = UA_NODEID_NUMERIC(0, UA_NS0ID_SERVER_SERVERSTATUS_STATE);
rq.nodesToRead = &rvi;
rq.nodesToReadSize = 1;
/* Manually close the TCP connection */
UA_ConnectionManager *cm = client->channel.connectionManager;
cm->closeConnection(cm, client->channel.connectionId);
UA_EventLoop *el = client->config.eventLoop;
el->run(el, 0);
/* The connection is re-established automatically */
UA_Variant val;
UA_Variant_init(&val);
UA_NodeId nodeId = UA_NODEID_NUMERIC(0, UA_NS0ID_SERVER_SERVERSTATUS_STATE);
retval = UA_Client_readValueAttribute(client, nodeId, &val);
ck_assert(retval == UA_STATUSCODE_GOOD);
UA_Variant_clear(&val);
UA_Client_disconnect(client);
UA_Client_delete(client);
}
END_TEST
START_TEST(SecureChannel_reconnect) {
UA_Client *client = UA_Client_new();
UA_ClientConfig_setDefault(UA_Client_getConfig(client));
UA_StatusCode retval = UA_Client_connect(client, "opc.tcp://localhost:4840");
ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD);
UA_Client_disconnectSecureChannel(client);
UA_ClientConfig *cconfig = UA_Client_getConfig(client);
UA_fakeSleep(cconfig->secureChannelLifeTime + 1);
UA_realSleep(50 + 1);
retval = UA_Client_connect(client, "opc.tcp://localhost:4840");
ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD);
UA_Client_delete(client);
}
END_TEST
START_TEST(SecureChannel_cableunplugged) {
UA_Client *client = UA_Client_new();
UA_ClientConfig_setDefault(UA_Client_getConfig(client));
UA_StatusCode retval = UA_Client_connect(client, "opc.tcp://localhost:4840");
ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD);
UA_Variant val;
UA_Variant_init(&val);
UA_NodeId nodeId = UA_NODEID_NUMERIC(0, UA_NS0ID_SERVER_SERVERSTATUS_STATE);
retval = UA_Client_readValueAttribute(client, nodeId, &val);
ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD);
UA_Variant_clear(&val);
/* Manually close the connection. The connection is internally closed at the
* next iteration of the EventLoop. Hence the next request is sent out. But
* the connection "actually closes" before receiving the response. */
UA_ConnectionManager *cm = client->channel.connectionManager;
uintptr_t connId = client->channel.connectionId;
cm->closeConnection(cm, connId);
UA_Variant_init(&val);
retval = UA_Client_readValueAttribute(client, nodeId, &val);
ck_assert_uint_eq(retval, UA_STATUSCODE_BADCONNECTIONCLOSED);
UA_Client_delete(client);
}
END_TEST
int main(void) {
TCase *tc_sc = tcase_create("Client SecureChannel");
tcase_add_checked_fixture(tc_sc, setup, teardown);
tcase_add_test(tc_sc, SecureChannel_renew);
tcase_add_test(tc_sc, SecureChannel_timeout_max);
tcase_add_test(tc_sc, SecureChannel_timeout_fail);
tcase_add_test(tc_sc, SecureChannel_networkfail);
tcase_add_test(tc_sc, SecureChannel_reconnect);
tcase_add_test(tc_sc, SecureChannel_cableunplugged);
Suite *s = suite_create("Client");
suite_add_tcase(s, tc_sc);
SRunner *sr = srunner_create(s);
srunner_set_fork_status(sr, CK_NOFORK);
srunner_run_all(sr,CK_NORMAL);
int number_failed = srunner_ntests_failed(sr);
srunner_free(sr);
return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,277 @@
/* 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/. */
#include <open62541/client.h>
#include <open62541/client_highlevel_async.h>
#include <open62541/client_config_default.h>
#include <open62541/server.h>
#include <open62541/server_config_default.h>
#include "client/ua_client_internal.h"
#include "server/ua_server_internal.h"
#include <stdio.h>
#include <stdlib.h>
#include "check.h"
#include "testing_clock.h"
#include "thread_wrapper.h"
UA_Server *server;
UA_Boolean running;
THREAD_HANDLE server_thread;
static UA_Boolean noNewSubscription; /* Don't create a subscription when the
session activates */
#define VARLENGTH 16366
static void
addVariable(size_t size) {
/* Define the attribute of the myInteger variable node */
UA_VariableAttributes attr = UA_VariableAttributes_default;
UA_Int32* array = (UA_Int32*)UA_malloc(size * sizeof(UA_Int32));
for(size_t i = 0; i < size; i++)
array[i] = (UA_Int32)i;
UA_Variant_setArray(&attr.value, array, size, &UA_TYPES[UA_TYPES_INT32]);
char name[] = "my.variable";
attr.description = UA_LOCALIZEDTEXT("en-US", name);
attr.displayName = UA_LOCALIZEDTEXT("en-US", name);
attr.dataType = UA_TYPES[UA_TYPES_INT32].typeId;
/* Add the variable node to the information model */
UA_NodeId myIntegerNodeId = UA_NODEID_STRING(1, name);
UA_QualifiedName myIntegerName = UA_QUALIFIEDNAME(1, name);
UA_NodeId parentNodeId = UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER);
UA_NodeId parentReferenceNodeId = UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES);
UA_Server_addVariableNode(server, myIntegerNodeId, parentNodeId,
parentReferenceNodeId, myIntegerName,
UA_NODEID_NUMERIC(0, UA_NS0ID_BASEDATAVARIABLETYPE),
attr, NULL, NULL);
/* add displayname to variable */
UA_Server_writeDisplayName(server, myIntegerNodeId,
UA_LOCALIZEDTEXT("de", "meine.Variable"));
UA_free(array);
}
THREAD_CALLBACK(serverloop) {
while(running)
UA_Server_run_iterate(server, true);
return 0;
}
static void setup(void) {
noNewSubscription = false;
running = true;
server = UA_Server_new();
ck_assert(server != NULL);
UA_ServerConfig *config = UA_Server_getConfig(server);
UA_ServerConfig_setDefault(config);
config->maxPublishReqPerSession = 5;
UA_Server_run_startup(server);
addVariable(VARLENGTH);
THREAD_CREATE(server_thread, serverloop);
}
static void teardown(void) {
if(!server)
return;
running = false;
THREAD_JOIN(server_thread);
UA_Server_run_shutdown(server);
UA_Server_delete(server);
server = NULL;
}
UA_Boolean notificationReceived = false;
UA_UInt32 countNotificationReceived = 0;
UA_Double publishingInterval = 500.0;
static void
dataChangeHandler(UA_Client *client, UA_UInt32 subId, void *subContext,
UA_UInt32 monId, void *monContext, UA_DataValue *value) {
notificationReceived = true;
countNotificationReceived++;
}
static void clearLocale(UA_ClientConfig *config) {
if(config->sessionLocaleIdsSize > 0 && config->sessionLocaleIds) {
UA_Array_delete(config->sessionLocaleIds,
config->sessionLocaleIdsSize, &UA_TYPES[UA_TYPES_LOCALEID]);
}
config->sessionLocaleIds = NULL;
config->sessionLocaleIdsSize = 0;
}
static void changeLocale(UA_Client *client) {
UA_LocalizedText loc;
UA_ClientConfig *config = UA_Client_getConfig(client);
clearLocale(config);
config->sessionLocaleIdsSize = 2;
config->sessionLocaleIds = (UA_LocaleId *)UA_Array_new(2, &UA_TYPES[UA_TYPES_LOCALEID]);
config->sessionLocaleIds[0] = UA_STRING_ALLOC("en-US");
config->sessionLocaleIds[1] = UA_STRING_ALLOC("de");
UA_StatusCode retval = UA_Client_activateCurrentSession(client);
ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD);
const UA_NodeId nodeIdString = UA_NODEID_STRING(1, "my.variable");
retval = UA_Client_readDisplayNameAttribute(client, nodeIdString, &loc);
ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD);
UA_LocalizedText newLocaleEng = UA_LOCALIZEDTEXT("en-US", "my.variable");
ck_assert(UA_String_equal(&newLocaleEng.locale, &loc.locale));
ck_assert(UA_String_equal(&newLocaleEng.text, &loc.text));
UA_LocalizedText_clear(&loc);
clearLocale(config);
config->sessionLocaleIdsSize = 2;
config->sessionLocaleIds = (UA_LocaleId *)UA_Array_new(2, &UA_TYPES[UA_TYPES_LOCALEID]);
config->sessionLocaleIds[0] = UA_STRING_ALLOC("de");
config->sessionLocaleIds[1] = UA_STRING_ALLOC("en-US");
retval = UA_Client_activateCurrentSession(client);
ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD);
retval = UA_Client_readDisplayNameAttribute(client, nodeIdString, &loc);
ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD);
UA_LocalizedText newLocaleGerm = UA_LOCALIZEDTEXT("de", "meine.Variable");
ck_assert(UA_String_equal(&newLocaleGerm.locale, &loc.locale));
ck_assert(UA_String_equal(&newLocaleGerm.text, &loc.text));
UA_LocalizedText_clear(&loc);
}
START_TEST(Client_subscription_createDataChanges) {
UA_Client *client = UA_Client_new();
UA_ClientConfig_setDefault(UA_Client_getConfig(client));
UA_StatusCode retval = UA_Client_connect(client, "opc.tcp://localhost:4840");
ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD);
UA_CreateSubscriptionRequest request = UA_CreateSubscriptionRequest_default();
UA_CreateSubscriptionResponse response = UA_Client_Subscriptions_create(client, request,
NULL, NULL, NULL);
ck_assert_uint_eq(response.responseHeader.serviceResult, UA_STATUSCODE_GOOD);
changeLocale(client);
UA_UInt32 subId = response.subscriptionId;
UA_MonitoredItemCreateRequest items[3];
UA_UInt32 newMonitoredItemIds[3];
UA_Client_DataChangeNotificationCallback callbacks[3];
UA_Client_DeleteMonitoredItemCallback deleteCallbacks[3];
void *contexts = NULL;
changeLocale(client);
/* monitor the server state */
items[0] = UA_MonitoredItemCreateRequest_default(UA_NODEID_NUMERIC(0, UA_NS0ID_SERVER_SERVERSTATUS_STATE));
callbacks[0] = dataChangeHandler;
deleteCallbacks[0] = NULL;
/* monitor invalid node */
items[1] = UA_MonitoredItemCreateRequest_default(UA_NODEID_NUMERIC(0, 999999));
callbacks[1] = dataChangeHandler;
deleteCallbacks[1] = NULL;
/* monitor current time */
items[2] = UA_MonitoredItemCreateRequest_default(UA_NODEID_NUMERIC(0, UA_NS0ID_SERVER_SERVERSTATUS_CURRENTTIME));
callbacks[2] = dataChangeHandler;
deleteCallbacks[2] = NULL;
UA_CreateMonitoredItemsRequest createRequest;
UA_CreateMonitoredItemsRequest_init(&createRequest);
createRequest.subscriptionId = subId;
createRequest.timestampsToReturn = UA_TIMESTAMPSTORETURN_BOTH;
createRequest.itemsToCreate = items;
createRequest.itemsToCreateSize = 3;
UA_CreateMonitoredItemsResponse createResponse =
UA_Client_MonitoredItems_createDataChanges(client, createRequest, NULL,
callbacks, deleteCallbacks);
ck_assert_uint_eq(createResponse.responseHeader.serviceResult, UA_STATUSCODE_GOOD);
ck_assert_uint_eq(createResponse.resultsSize, 3);
ck_assert_uint_eq(createResponse.results[0].statusCode, UA_STATUSCODE_GOOD);
newMonitoredItemIds[0] = createResponse.results[0].monitoredItemId;
ck_assert_uint_eq(createResponse.results[1].statusCode, UA_STATUSCODE_BADNODEIDUNKNOWN);
newMonitoredItemIds[1] = createResponse.results[1].monitoredItemId;
ck_assert_uint_eq(newMonitoredItemIds[1], 0);
ck_assert_uint_eq(createResponse.results[2].statusCode, UA_STATUSCODE_GOOD);
newMonitoredItemIds[2] = createResponse.results[2].monitoredItemId;
ck_assert_uint_eq(createResponse.results[2].statusCode, UA_STATUSCODE_GOOD);
UA_CreateMonitoredItemsResponse_clear(&createResponse);
changeLocale(client);
/* manually control the server thread */
running = false;
THREAD_JOIN(server_thread);
retval = UA_Client_run_iterate(client, 1);
ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD);
UA_fakeSleep((UA_UInt32)publishingInterval + 1);
UA_Server_run_iterate(server, true);
notificationReceived = false;
countNotificationReceived = 0;
UA_fakeSleep((UA_UInt32)publishingInterval + 1);
retval = UA_Client_run_iterate(client, 1);
ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD);
ck_assert_uint_eq(notificationReceived, true);
ck_assert_uint_eq(countNotificationReceived, 2);
UA_fakeSleep((UA_UInt32)publishingInterval + 1);
UA_Server_run_iterate(server, true);
notificationReceived = false;
retval = UA_Client_run_iterate(client, 1);
ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD);
ck_assert_uint_eq(notificationReceived, true);
ck_assert_uint_eq(countNotificationReceived, 3);
/* run the server in an independent thread again */
running = true;
THREAD_CREATE(server_thread, serverloop);
UA_DeleteMonitoredItemsRequest deleteRequest;
UA_DeleteMonitoredItemsRequest_init(&deleteRequest);
deleteRequest.subscriptionId = subId;
deleteRequest.monitoredItemIds = newMonitoredItemIds;
deleteRequest.monitoredItemIdsSize = 3;
UA_DeleteMonitoredItemsResponse deleteResponse =
UA_Client_MonitoredItems_delete(client, deleteRequest);
ck_assert_uint_eq(deleteResponse.responseHeader.serviceResult, UA_STATUSCODE_GOOD);
ck_assert_uint_eq(deleteResponse.resultsSize, 3);
ck_assert_uint_eq(deleteResponse.results[0], UA_STATUSCODE_GOOD);
ck_assert_uint_eq(deleteResponse.results[1], UA_STATUSCODE_BADMONITOREDITEMIDINVALID);
ck_assert_uint_eq(deleteResponse.results[2], UA_STATUSCODE_GOOD);
UA_DeleteMonitoredItemsResponse_clear(&deleteResponse);
retval = UA_Client_Subscriptions_deleteSingle(client, subId);
ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD);
UA_Client_delete(client);
}
END_TEST
static Suite* testSuite_Client(void) {
Suite *s = suite_create("Client Subscription");
TCase *tc_client = tcase_create("Client Subscription Basic");
tcase_add_checked_fixture(tc_client, setup, teardown);
tcase_add_test(tc_client, Client_subscription_createDataChanges);
suite_add_tcase(s, tc_client);
return s;
}
int main(void) {
Suite *s = testSuite_Client();
SRunner *sr = srunner_create(s);
srunner_set_fork_status(sr, CK_NOFORK);
srunner_run_all(sr,CK_NORMAL);
int number_failed = srunner_ntests_failed(sr);
srunner_free(sr);
return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
}

View File

@@ -0,0 +1,89 @@
/* 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/.
*
* Copyright 2018 (c) basysKom GmbH <opensource@basyskom.com> (Author: Peter Rustler)
*/
/* Data in this header is gathered from OPC Unified Architecture, Part 11, Release
1.03 Page 5-6 from OPC Foundation */
#ifndef UA_HISTORICAL_READ_TEST_DATA_H_
#define UA_HISTORICAL_READ_TEST_DATA_H_
#include <open62541/types.h>
#include <limits.h>
#define TESTDATA_START_TIME 1
#define TESTDATA_STOP_TIME 601
static UA_DateTime testData[] = {
100,
200,
300,
400,
500
};
static const size_t testDataSize = (sizeof(testData) / sizeof(testData[0]));
static UA_DateTime testInsertDataSuccess[] = {
50,
250,
550
};
static const size_t testInsertDataSuccessSize = (sizeof(testInsertDataSuccess) / sizeof(testInsertDataSuccess[0]));
static UA_DateTime testInsertResultData[] = {
50,
100,
200,
250,
300,
400,
500,
550
};
static size_t testInsertResultDataSize = (sizeof(testInsertResultData) / sizeof(testInsertResultData[0]));
static UA_DateTime testReplaceDataSuccess[] = {
100,
300,
500
};
static const size_t testReplaceDataSuccessSize = (sizeof(testReplaceDataSuccess) / sizeof(testReplaceDataSuccess[0]));
struct DeleteRange {
UA_DateTime start;
UA_DateTime end;
size_t historySize;
UA_StatusCode statusCode;
};
static struct DeleteRange testDeleteRangeData[] = {
{200, 400, 3, UA_STATUSCODE_GOOD},
{100, 400, 2, UA_STATUSCODE_GOOD},
{200, 500, 2, UA_STATUSCODE_GOOD},
{100, 500, 1, UA_STATUSCODE_GOOD},
{100, 550, 0, UA_STATUSCODE_GOOD},
{50, 550, 0, UA_STATUSCODE_GOOD},
{500, 550, 4, UA_STATUSCODE_GOOD},
{50, 150, 4, UA_STATUSCODE_GOOD},
{100, 100, 4, UA_STATUSCODE_GOOD},
{500, 500, 4, UA_STATUSCODE_GOOD},
{200, 200, 4, UA_STATUSCODE_GOOD},
{50, 50, 5, UA_STATUSCODE_BADNODATA},
{550, 550, 5, UA_STATUSCODE_BADNODATA},
{150, 150, 5, UA_STATUSCODE_BADNODATA},
{200, 100, 5, UA_STATUSCODE_BADTIMESTAMPNOTSUPPORTED},
{LLONG_MIN, LLONG_MAX, 0, UA_STATUSCODE_GOOD},
{0, LLONG_MAX, 0, UA_STATUSCODE_GOOD},
{LLONG_MIN, 0, 5, UA_STATUSCODE_BADNODATA},
{0, 0, 5, UA_STATUSCODE_BADNODATA},
{50, 75, 5, UA_STATUSCODE_BADNODATA},
{50, 100, 5, UA_STATUSCODE_BADNODATA},
{550, 600, 5, UA_STATUSCODE_BADNODATA}
};
static const size_t testDeleteRangeDataSize = (sizeof(testDeleteRangeData) / sizeof(testDeleteRangeData[0]));
#endif /*UA_HISTORICAL_READ_TEST_DATA_H_*/