From 281d51ebb6d05ea7f26f21d66eedab6ac84c3905 Mon Sep 17 00:00:00 2001 From: Gematik <52454541+gematik1@users.noreply.github.com> Date: Tue, 30 Jul 2024 15:15:30 +0200 Subject: [PATCH] Version 5.9.0 (#26) Co-authored-by: Gematik --- .github/README.adoc | 15 +- .gitignore | 2 - .spi.yml | 4 + CardSimulationTestKit/.jazzy.yml | 14 + CardSimulationTestKit/.swiftlint.yml | 59 + CardSimulationTestKit/README.adoc | 164 ++ .../Resources/AEXMLExt_Info.plist | 22 + ...ardSimulationCardReaderProvider_Info.plist | 22 + .../Resources/CardSimulationLoader_Info.plist | 22 + .../CardSimulationTerminalTestCase_Info.plist | 22 + .../Resources/Documenation_Info.plist | 22 + .../Sources/AEXMLExt/AEXMLElement+Root.swift | 48 + .../Card/SimulatorCard.swift | 84 + .../Card/SimulatorCardChannel.swift | 199 ++ .../SimulatorCardReaderProvider.swift | 36 + .../Terminal/SimulatorCardReader.swift | 92 + .../SimulatorCardReaderController.swift | 80 + .../internal/Data+BerTLV.swift | 44 + .../internal/InputStreaming.swift | 23 + .../internal/OutputStreaming.swift | 23 + .../internal/TCPClient+Streaming.swift | 54 + .../KeepAliveRunLoop.swift | 66 + .../Resources.bundle/pom.xml | 22 + .../SimulationLoaderError.swift | 31 + .../SimulationManager.swift | 314 +++ .../SimulationProcessMode.swift | 114 ++ .../SimulationRunner.swift | 152 ++ .../SimulationRunnerType+Ext.swift | 29 + .../internal/JavaProcess.swift | 165 ++ .../internal/SimulationManager+Internal.swift | 146 ++ ...SimulationRunner+JavaProcessDelegate.swift | 78 + .../internal/TempFilePathGeneratorType.swift | 33 + .../CardSimulationLoader/static/Maven.swift | 54 + .../xml/AEXMLDocument+XMLManipulation.swift | 51 + .../xml/URL+ConfigurationFileProcessor.swift | 52 + .../CardSimulationLoader/xml/XMLPath.swift | 154 ++ .../xml/XMLPathManipulator.swift | 111 + .../Sources/CardSimulationRunner/main.swift | 63 + .../AEXMLElementExtRootTest.swift | 44 + .../Card/SimulatorCardChannelTest.swift | 218 ++ .../Card/SimulatorCardTest.swift | 65 + .../MockSimulationManager.swift | 52 + .../MockSimulationRunner.swift | 25 + .../SimulatorCardReaderProviderTest.swift | 43 + .../SimulatorCardReaderControllerTest.swift | 110 + .../Reader/SimulatorCardReaderTest.swift | 95 + .../XCTestManifests.swift | 32 + .../internal/DataExtBerTLVTest.swift | 244 +++ .../internal/TCPClientExtStreamingTest.swift | 98 + .../channelcontexts/ChannelContext_G2_eGK.xml | 632 ++++++ ...n_EGKG2_80276883110000017222_gema5_TCP.xml | 44 + ...n_EGKG2_80276883110000017333_gema5_TCP.xml | 44 + .../EGKG2_80276883110000017222_gema5.xml | 1807 +++++++++++++++++ .../EGKG2_80276883110000017333_gema5.xml | 1614 +++++++++++++++ .../KeepAliveRunLoopTest.swift | 47 + .../Resources.bundle/configuration.xml | 44 + .../Resources.bundle/pom.xml | 22 + .../Resources.bundle/soapRequest.xml | 17 + .../SimulationManagerTest.swift | 196 ++ .../SimulationProcessModeTest.swift | 98 + .../SimulationRunnerTest.swift | 116 ++ .../XCTestManifests.swift | 35 + .../internal/JavaProcessTest.swift | 52 + .../SimulationManagerExtInternalTest.swift | 103 + .../AEXMLDocumentExtXMLManipulationTest.swift | 54 + ...URLExtConfigurationFileProcessorTest.swift | 60 + .../xml/XMLElementManipulatorTest.swift | 51 + .../xml/XMLPathTest.swift | 123 ++ Package.resolved | 18 + Package.swift | 7 +- README.adoc | 6 + ReleaseNotes.md | 5 + .../Reader/CoreNFCError.swift | 5 + devops/Jenkinsfile | 93 + doc/userguide/OHCKIT_GettingStarted.adoc | 2 +- doc/userguide/OHCKIT_Overview.adoc | 3 +- 76 files changed, 8997 insertions(+), 13 deletions(-) create mode 100644 .spi.yml create mode 100644 CardSimulationTestKit/.jazzy.yml create mode 100644 CardSimulationTestKit/.swiftlint.yml create mode 100644 CardSimulationTestKit/README.adoc create mode 100644 CardSimulationTestKit/Resources/AEXMLExt_Info.plist create mode 100644 CardSimulationTestKit/Resources/CardSimulationCardReaderProvider_Info.plist create mode 100644 CardSimulationTestKit/Resources/CardSimulationLoader_Info.plist create mode 100644 CardSimulationTestKit/Resources/CardSimulationTerminalTestCase_Info.plist create mode 100644 CardSimulationTestKit/Resources/Documenation_Info.plist create mode 100644 CardSimulationTestKit/Sources/AEXMLExt/AEXMLElement+Root.swift create mode 100644 CardSimulationTestKit/Sources/CardSimulationCardReaderProvider/Card/SimulatorCard.swift create mode 100644 CardSimulationTestKit/Sources/CardSimulationCardReaderProvider/Card/SimulatorCardChannel.swift create mode 100644 CardSimulationTestKit/Sources/CardSimulationCardReaderProvider/Provider/SimulatorCardReaderProvider.swift create mode 100644 CardSimulationTestKit/Sources/CardSimulationCardReaderProvider/Terminal/SimulatorCardReader.swift create mode 100644 CardSimulationTestKit/Sources/CardSimulationCardReaderProvider/Terminal/SimulatorCardReaderController.swift create mode 100644 CardSimulationTestKit/Sources/CardSimulationCardReaderProvider/internal/Data+BerTLV.swift create mode 100644 CardSimulationTestKit/Sources/CardSimulationCardReaderProvider/internal/InputStreaming.swift create mode 100644 CardSimulationTestKit/Sources/CardSimulationCardReaderProvider/internal/OutputStreaming.swift create mode 100644 CardSimulationTestKit/Sources/CardSimulationCardReaderProvider/internal/TCPClient+Streaming.swift create mode 100644 CardSimulationTestKit/Sources/CardSimulationLoader/KeepAliveRunLoop.swift create mode 100644 CardSimulationTestKit/Sources/CardSimulationLoader/Resources.bundle/pom.xml create mode 100644 CardSimulationTestKit/Sources/CardSimulationLoader/SimulationLoaderError.swift create mode 100644 CardSimulationTestKit/Sources/CardSimulationLoader/SimulationManager.swift create mode 100644 CardSimulationTestKit/Sources/CardSimulationLoader/SimulationProcessMode.swift create mode 100644 CardSimulationTestKit/Sources/CardSimulationLoader/SimulationRunner.swift create mode 100644 CardSimulationTestKit/Sources/CardSimulationLoader/SimulationRunnerType+Ext.swift create mode 100644 CardSimulationTestKit/Sources/CardSimulationLoader/internal/JavaProcess.swift create mode 100644 CardSimulationTestKit/Sources/CardSimulationLoader/internal/SimulationManager+Internal.swift create mode 100644 CardSimulationTestKit/Sources/CardSimulationLoader/internal/SimulationRunner+JavaProcessDelegate.swift create mode 100644 CardSimulationTestKit/Sources/CardSimulationLoader/internal/TempFilePathGeneratorType.swift create mode 100644 CardSimulationTestKit/Sources/CardSimulationLoader/static/Maven.swift create mode 100644 CardSimulationTestKit/Sources/CardSimulationLoader/xml/AEXMLDocument+XMLManipulation.swift create mode 100644 CardSimulationTestKit/Sources/CardSimulationLoader/xml/URL+ConfigurationFileProcessor.swift create mode 100644 CardSimulationTestKit/Sources/CardSimulationLoader/xml/XMLPath.swift create mode 100644 CardSimulationTestKit/Sources/CardSimulationLoader/xml/XMLPathManipulator.swift create mode 100644 CardSimulationTestKit/Sources/CardSimulationRunner/main.swift create mode 100644 CardSimulationTestKit/Tests/AEXMLExtTests/AEXMLElementExtRootTest.swift create mode 100644 CardSimulationTestKit/Tests/CardSimulationCardReaderProviderTests/Card/SimulatorCardChannelTest.swift create mode 100644 CardSimulationTestKit/Tests/CardSimulationCardReaderProviderTests/Card/SimulatorCardTest.swift create mode 100644 CardSimulationTestKit/Tests/CardSimulationCardReaderProviderTests/MockSimulationManager.swift create mode 100644 CardSimulationTestKit/Tests/CardSimulationCardReaderProviderTests/MockSimulationRunner.swift create mode 100644 CardSimulationTestKit/Tests/CardSimulationCardReaderProviderTests/Provider/SimulatorCardReaderProviderTest.swift create mode 100644 CardSimulationTestKit/Tests/CardSimulationCardReaderProviderTests/Reader/SimulatorCardReaderControllerTest.swift create mode 100644 CardSimulationTestKit/Tests/CardSimulationCardReaderProviderTests/Reader/SimulatorCardReaderTest.swift create mode 100644 CardSimulationTestKit/Tests/CardSimulationCardReaderProviderTests/XCTestManifests.swift create mode 100644 CardSimulationTestKit/Tests/CardSimulationCardReaderProviderTests/internal/DataExtBerTLVTest.swift create mode 100644 CardSimulationTestKit/Tests/CardSimulationCardReaderProviderTests/internal/TCPClientExtStreamingTest.swift create mode 100755 CardSimulationTestKit/Tests/CardSimulationLoaderTests/Configuration.bundle/channelcontexts/ChannelContext_G2_eGK.xml create mode 100755 CardSimulationTestKit/Tests/CardSimulationLoaderTests/Configuration.bundle/configuration_EGKG2_80276883110000017222_gema5_TCP.xml create mode 100755 CardSimulationTestKit/Tests/CardSimulationLoaderTests/Configuration.bundle/configuration_EGKG2_80276883110000017333_gema5_TCP.xml create mode 100755 CardSimulationTestKit/Tests/CardSimulationLoaderTests/Configuration.bundle/images/EGKG2_80276883110000017222_gema5.xml create mode 100755 CardSimulationTestKit/Tests/CardSimulationLoaderTests/Configuration.bundle/images/EGKG2_80276883110000017333_gema5.xml create mode 100644 CardSimulationTestKit/Tests/CardSimulationLoaderTests/KeepAliveRunLoopTest.swift create mode 100755 CardSimulationTestKit/Tests/CardSimulationLoaderTests/Resources.bundle/configuration.xml create mode 100644 CardSimulationTestKit/Tests/CardSimulationLoaderTests/Resources.bundle/pom.xml create mode 100644 CardSimulationTestKit/Tests/CardSimulationLoaderTests/Resources.bundle/soapRequest.xml create mode 100644 CardSimulationTestKit/Tests/CardSimulationLoaderTests/SimulationManagerTest.swift create mode 100644 CardSimulationTestKit/Tests/CardSimulationLoaderTests/SimulationProcessModeTest.swift create mode 100644 CardSimulationTestKit/Tests/CardSimulationLoaderTests/SimulationRunnerTest.swift create mode 100644 CardSimulationTestKit/Tests/CardSimulationLoaderTests/XCTestManifests.swift create mode 100644 CardSimulationTestKit/Tests/CardSimulationLoaderTests/internal/JavaProcessTest.swift create mode 100644 CardSimulationTestKit/Tests/CardSimulationLoaderTests/internal/SimulationManagerExtInternalTest.swift create mode 100644 CardSimulationTestKit/Tests/CardSimulationLoaderTests/xml/AEXMLDocumentExtXMLManipulationTest.swift create mode 100644 CardSimulationTestKit/Tests/CardSimulationLoaderTests/xml/URLExtConfigurationFileProcessorTest.swift create mode 100644 CardSimulationTestKit/Tests/CardSimulationLoaderTests/xml/XMLElementManipulatorTest.swift create mode 100644 CardSimulationTestKit/Tests/CardSimulationLoaderTests/xml/XMLPathTest.swift create mode 100644 devops/Jenkinsfile diff --git a/.github/README.adoc b/.github/README.adoc index c4831b6..8e4560d 100644 --- a/.github/README.adoc +++ b/.github/README.adoc @@ -21,9 +21,11 @@ when implementing a system that performs the communication between an iOS based and a German Health Card (elektronische Gesundheitskarte) using an NFC, Blue Tooth oder USB interface. This document describes the functionalitiy and structure of OpenHealthCardKit. + == API Documentation Generated API docs are available at https://gematik.github.io/ref-OpenHealthCardKit. + == Getting Started OpenHealthCardKit requires Swift 5.6. @@ -32,7 +34,7 @@ OpenHealthCardKit requires Swift 5.6. - **Swift Package Manager:** Put this in your `Package.swift`: - `.package(url: "https://github.com/gematik/ref-OpenHealthCardKit", from: "5.6.0"),` + .package(url: "https://github.com/gematik/ref-OpenHealthCardKit", from: "5.6.0"), - **Carthage:** Put this in your `Cartfile`: @@ -57,12 +59,13 @@ OpenHealthCardKit consists of the submodules - HealthCardControl - NFCCardReaderProvider -As a reference for each submodule see also the `IntegrationTests`. -Also see a https://github.com/gematik/ref-OpenHealthCardApp-iOS[Demo App] on GitHub using this framework. +As a reference for the usage of each submodule see also the `IntegrationTests`. + [#CardReaderProviderApi] === CardReaderProviderApi (Smart)CardReader protocols for interacting with `HealthCardAccess`. + [#HealthCardAccess] === HealthCardAccess This library contains the classes for cards, commands, card file systems and error handling. @@ -124,7 +127,7 @@ In the next example we use a `HealthCard` object representing an eGK (elektronis as one kind of a `HealthCardType` implementing the `CardType` protocol and then send the command to the card (or card's channel): [source,swift] ---- -let healthCardResponse = try await selectEsignCommand.transmit(to: Self.healthCard) +let healthCardResponse = try await selectEsignCommand.transmitAsync(to: Self.healthCard) guard healthCardResponse.responseStatus == ResponseStatus.success else { throw HealthCard.Error.operational // TO-DO: handle this or throw a meaningful Error } @@ -199,6 +202,7 @@ readCertificate } ) ---- + [#HealthCardControl] === HealthCardControl @@ -223,7 +227,7 @@ Take the necessary preparatory steps for signing a challenge on the Health Card, let challenge = Data([0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8]) let format2Pin = try Format2Pin(pincode: "123456") _ = try await Self.healthCard.verify(pin: format2Pin, type: EgkFileSystem.Pin.mrpinHome) -let signResponse = try await Self.healthCard.sign(data: challenge) +let signResponse = try await Self.healthCard.signAsync(data: challenge) expect(signResponse.responseStatus) == ResponseStatus.success ---- @@ -243,6 +247,7 @@ let secureMessaging = try await KeyAgreement.Algorithm.idPaceEcdhGmAesCbcCmac128 See the integration tests link:include::{integrationtestdir}/HealthCardControl/[IntegrationTests/HealthCardControl/] for more already implemented use cases. + [#NFCCardReaderProvider] === NFCCardReaderProvider diff --git a/.gitignore b/.gitignore index ecb5a1e..0ce96d9 100644 --- a/.gitignore +++ b/.gitignore @@ -98,8 +98,6 @@ fastlane/test_output iOSInjectionProject/ -CardSimulationTestKit -devops jenkinsfiles diff --git a/.spi.yml b/.spi.yml new file mode 100644 index 0000000..e6558fc --- /dev/null +++ b/.spi.yml @@ -0,0 +1,4 @@ +version: 1 +builder: + configs: + - documentation_targets: [HealthCardControl, HealthCardAccess, NFCCardReaderProvider, CardReaderProviderApi] \ No newline at end of file diff --git a/CardSimulationTestKit/.jazzy.yml b/CardSimulationTestKit/.jazzy.yml new file mode 100644 index 0000000..2b6f689 --- /dev/null +++ b/CardSimulationTestKit/.jazzy.yml @@ -0,0 +1,14 @@ +output: docs +author: gematik GmbH +author_url: http://www.gematik.de +exclude: /*/internal* +# module references the 'Documentation' targets PRODUCT_NAME +module: CardSimulationTestKit +github_url: https://gematik.github.io +theme: jony +swift_build_tool: xcodebuild +xcodebuild_arguments: + - "-project" + - 'CardSimulationTestKit.xcodeproj' + - "-scheme" + - 'Documentation' diff --git a/CardSimulationTestKit/.swiftlint.yml b/CardSimulationTestKit/.swiftlint.yml new file mode 100644 index 0000000..db60cff --- /dev/null +++ b/CardSimulationTestKit/.swiftlint.yml @@ -0,0 +1,59 @@ +opt_in_rules: + - attributes + - empty_count + - force_unwrapping + - unneeded_parentheses_in_closure_argument + - unavailable_function + - trailing_closure + - strict_fileprivate + - sorted_imports + - sorted_first_last + - single_test_class + - required_enum_case + - redundant_type_annotation + - redundant_nil_coalescing + - prohibited_super_call + - override_in_extension + - overridden_super_call + - operator_usage_whitespace + - no_extension_access_modifier + - multiline_function_chains + - multiline_arguments + - modifier_order + - missing_docs + - lower_acl_than_parent + - literal_expression_end_indentation + - first_where + - file_name + - fatal_error_message + - explicit_init + - empty_string + - discouraged_optional_collection + - closure_end_indentation + - file_header +excluded: # paths to ignore during linting. Takes precedence over `included`. + - Package.swift + - .build/ + - vendor/ + - Carthage/ +custom_rules: + nimble_fail_with_description: + included: ".*Test\\.swift" + name: "Fail with description" + regex: "(Nimble.fail\\(\\))" + message: "Failures need a description" + severity: warning + must_not_contain_author: + included: + - ".*Test\\.swift" + - ".*Sources\\.swift" + name: "must not contain author" + regex: "(\/\/[[:space:]]*Created by)" + message: "Source must not contain author" + severity: warning + +file_header: + required_pattern: | + \/\/ + \/\/ Copyright \(c\) \d{4} gematik GmbH + \/\/ \ No newline at end of file diff --git a/CardSimulationTestKit/README.adoc b/CardSimulationTestKit/README.adoc new file mode 100644 index 0000000..d02436f --- /dev/null +++ b/CardSimulationTestKit/README.adoc @@ -0,0 +1,164 @@ += CardSimulationTestKit + +NOTE: This framework rather is meant to be used for gematik-internal development purposes (since the actual CardSimulation application can neither be open sourced nor provided as of now). We publish this code anyway for further reference/usage. + +CardSimulationTestKit provides an easy-to-use interface for testing against a German Health Card Simulator. +It comes bundled with + +* `CardSimulationLoader`: loads and starts a card simulation as a Java process listening on a TCP port +* `CardSimulationCardReaderProvider`: implements the `CardReaderProviderApi` interface +* `CardSimulationTerminalTestCase`: provides a fully initialized and functional `HealthCard` object to send commands to and receive responses from. + + +The intended usage of this project is to ease integration and use the G2-Kartensimulation with Swift projects, specifically the test cases in this project. +This guide is separated in two (2) main parts. Describing + +. the usage of the `CardSimulation-Loader` framework (How-to) and +. how to maintain the technical consideration(s) and implementation(s). + +== Frameworks + +=== CardSimulation-Loader + +The sole purpose of this framework is to launch and monitor a G2-Kartensimulation Java process. +For detailed usage information see the inlined documentation on `SimulationManager` +and `SimulationRunner`. + +*Starting the simulator*: + +Of course the best way to find out how-to use the CardSimulation-Loader is by checking the `SimulationManagerTest` and `SimulationRunnerTest` to see their intended and tested use-cases. +Next to checking the test-cases you also find some (example) configuration files in the _Configuration.bundle_ file. + +In general, you would prepare such a *card-configuration* XML as in the Configuration.bundle and pass it to the `SimulationManager.shared` by invoking its: + +[source,Swift] +---- +func createSimulation( + configFile: URL, + preprocessor manipulators: [XMLPathManipulator] = [], + simulatorVersion: String = "2.7.6-352", + simulatorDirectory: String = "simulator", +) +---- + +Note: you can specify the G2-Kartensimulation version it needs to download/use. + +The returned `SimulationRunnerType` can be used to monitor the newly started G2-Kartensimulation instance. To - for instance - figure out on which TLV-port the simulator is registered, just check the `SimulationRunnerType.mode`. When `running` the TLV TCP/IP port is projected there. And for convenience reasons made available through `var tlvPort: Int?` on SimulationRunnerType(s). + +This SimulationRunnerType instance will need a CardTerminalControllerType to expose this G2-Kartensimulation virtual `HealthCard` to the HealthCardAccess/Control realm. + +*Example*: + +[source,Swift] +---- +/// Read configFile from included Resources Bundle +let simulatorConfig = Bundle(for: MyClass.self) + .resourceFilePath(in: "Configuration", for: "configuration_EGKG2_80276883110000017222_gema5_TCP.xml") + .asURL +/// Launch a G2-Kartensimulation with this configuration file +let runner = try SimulationManager.shared.startSimulation( + configFile: simulatorConfig, + preprocessor: [ + XMLPathManipulatorHolder.TLVPortManipulator(port: "0"), + XMLPathManipulatorHolder.RelativeToAbsolutePathManipulator(with: XMLPathManipulatorHolder.CardConfigFileXMLPath, absolutePath: simulatorConfig.deletingLastPathComponent()), + XMLPathManipulatorHolder.RelativeToAbsolutePathManipulator(with: XMLPathManipulatorHolder.ChannelConfigFileXMLPath, absolutePath: simulatorConfig.deletingLastPathComponent()) + ], + waitUntilLaunched: true +) + +// ... Do amazing things with the runner + +/// Stop the runner when done +runner.stop(waitUntilTerminated: true) +---- + +==== Technical overview + +As described in the previous section(s) the CardSimulationLoader provides an easy-to-use API to launch and manage a G2-Kartensimulation. +In order to achieve this we need to combine some various technologies/environments (read: Nexus <--> Java <--> Swift -> CardSimulationLoader API). + +The main components for this project to work: + +* Download G2-Kartensimulation Nexus artifacts +* Launch and monitor Java Process + +These two (2) steps are taken care of when using the `SimulationManager` to launch a simulation. + +==== Maven step + +The `SimulationManager` reads the `pom.xml` and executes a shell script to run `mvn dependency:copy-dependencies`. +And puts these artifacts in the same transient environment to be cleaned (manually) by calling `SimulationManager.clean` upon +finishing with the simulator(s). Reason for this is to not download the artifacts for every simulator instance in case they +are launch sequentially - which is reasonable to assume. + +==== Java process + +When the artifacts are in place, the `SimulationRunner` creates a JavaProcess that will be launched/forked in a separate process. +And monitors this process by reading/parsing the `stdout` and `stderr` to detect the tlv-port number and successful initialization. + +To start developing the project follow the Project Setup section below 👇. + +=== CardSimulation-CardReaderProvider + +CardTerminalProvider for communication with G2-Kartensimulation + +=== CardSimulationTerminalTestCase + +CardSimulationTerminalTestCase provides a fully initialized and functional `HealthCard` object to send commands +against and receive responses from. + +== Getting Started + +CardSimulationLoader requires Swift 5.1. + +=== Usage + +In your Test class, derive from the `CardSimulationTerminalTestCase` which itself is a `XCTestCase`. +You then have a `HealthCard` and a `CardTerminal` object directly link to an up and running CardSimulation at your disposal. + +[source,Swift] +---- +final class SelectCommandIntegrationTest: CardSimulationTerminalTestCase { + func testSelectRoot() { + let healthCard = CardSimulationTerminalTestCase.healthCard + HealthCardCommand.Select.selectRoot() + .execute(on: healthCard) + .run(on: Executor.trampoline) + } +} +---- + +CardSimulationTestKit comes with various CardImage configuration files. +You can choose between the following images + +* configuration_EGK_G2_1_80276883110000095711_GuD_TCP.xml (default) +* configuration_EGK_G2_1_ecc.xml +* configuration_EGKG2_80276883110000017222_gema5_TCP.xml +* configuration_HBA_G2_1_80276883110000205690_gema5_TCP.xml +* configuration_HBAG2_80276883110000017289_gema5_TCP.xml +* configuration_TLK_COS_image-kontaktlos128.xml + +by overwriting the `class func configFile() -> URL?` like this: + +[source,Swift] +---- +final class SelectCommandIntegrationTest: CardSimulationTerminalTestCase { + override class func configFile() -> URL? { + let bundle = Bundle(for: CardSimulationTerminalTestCase.self) + let path = bundle.resourceFilePath(in: "Resources", for: "Configuration/configuration_EGK_G2_1_ecc.xml") + return path.asURL + } +} +---- +or bring your own image: + +[source,Swift] +---- +final class SelectCommandIntegrationTest: CardSimulationTerminalTestCase { + override class func configFile() -> URL? { + // this assumes, your use a test class and have a resource bundle called "Resources2.bundle" + let bundle = Bundle(for: self) + let path = bundle.testResourceFilePath(in: "Resources2", for: "Configuration/configuration_EGK_G2_1_ecc.xml") + return path.asURL + } +} \ No newline at end of file diff --git a/CardSimulationTestKit/Resources/AEXMLExt_Info.plist b/CardSimulationTestKit/Resources/AEXMLExt_Info.plist new file mode 100644 index 0000000..323e5ec --- /dev/null +++ b/CardSimulationTestKit/Resources/AEXMLExt_Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + + diff --git a/CardSimulationTestKit/Resources/CardSimulationCardReaderProvider_Info.plist b/CardSimulationTestKit/Resources/CardSimulationCardReaderProvider_Info.plist new file mode 100644 index 0000000..323e5ec --- /dev/null +++ b/CardSimulationTestKit/Resources/CardSimulationCardReaderProvider_Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + + diff --git a/CardSimulationTestKit/Resources/CardSimulationLoader_Info.plist b/CardSimulationTestKit/Resources/CardSimulationLoader_Info.plist new file mode 100644 index 0000000..323e5ec --- /dev/null +++ b/CardSimulationTestKit/Resources/CardSimulationLoader_Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + + diff --git a/CardSimulationTestKit/Resources/CardSimulationTerminalTestCase_Info.plist b/CardSimulationTestKit/Resources/CardSimulationTerminalTestCase_Info.plist new file mode 100644 index 0000000..7032226 --- /dev/null +++ b/CardSimulationTestKit/Resources/CardSimulationTerminalTestCase_Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleVersion + 8 + + diff --git a/CardSimulationTestKit/Resources/Documenation_Info.plist b/CardSimulationTestKit/Resources/Documenation_Info.plist new file mode 100644 index 0000000..323e5ec --- /dev/null +++ b/CardSimulationTestKit/Resources/Documenation_Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + + diff --git a/CardSimulationTestKit/Sources/AEXMLExt/AEXMLElement+Root.swift b/CardSimulationTestKit/Sources/AEXMLExt/AEXMLElement+Root.swift new file mode 100644 index 0000000..16e743e --- /dev/null +++ b/CardSimulationTestKit/Sources/AEXMLExt/AEXMLElement+Root.swift @@ -0,0 +1,48 @@ +// +// Copyright (c) 2023 gematik GmbH +// +// Licensed under the Apache License, Version 2.0 (the License); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an 'AS IS' BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import AEXML + +extension AEXMLElement { + /// Returns true if this `AEXMLElement` has no parent element. + public var isRoot: Bool { + self.parent == nil + } + + /// Replace a child element with `child` at specified `index` and return the original replaced element. + /// + /// - Parameters: + /// - index: the index at which to place the new child + /// - child: the new element to replace the old one + /// - Note: The replaced child keeps the reference to its parent but is no longer referenced from the parent. + /// + /// - Return: the previous element at `index` + open func replaceChild(at index: Int, with child: AEXMLElement) -> AEXMLElement { + let prev = children[index] + var childrenCopied = children + + // Remove all children from self + children.forEach { elem in + elem.removeFromParent() + } + childrenCopied[index] = child + childrenCopied.forEach { childCopied in + self.addChild(childCopied) + } + + return prev + } +} diff --git a/CardSimulationTestKit/Sources/CardSimulationCardReaderProvider/Card/SimulatorCard.swift b/CardSimulationTestKit/Sources/CardSimulationCardReaderProvider/Card/SimulatorCard.swift new file mode 100644 index 0000000..2fe3bef --- /dev/null +++ b/CardSimulationTestKit/Sources/CardSimulationCardReaderProvider/Card/SimulatorCard.swift @@ -0,0 +1,84 @@ +// +// Copyright (c) 2023 gematik GmbH +// +// Licensed under the Apache License, Version 2.0 (the License); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an 'AS IS' BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import CardReaderProviderApi +import Foundation +import GemCommonsKit +import SwiftSocket + +public class SimulatorCard: CardType { + public private(set) var atr: ATR + public private(set) var `protocol`: CardProtocol + let host: String + let port: Int32 + let connectTimeout: Int + var basicChannel: SimulatorCardChannel? { + didSet { + try? oldValue?.close() + } + } + + public var maxMessageLength: Int = 4096 + public var maxResponseLength: Int = 4096 + + required init(host: String, port: Int32, channel protocol: CardProtocol = .t1, timeout: Int = 10) { + self.protocol = `protocol` + atr = Data.empty + self.host = host + self.port = port + connectTimeout = timeout + } + + public func openBasicChannel() throws -> CardChannelType { + let client = TCPClient(address: host, port: port) + switch client.connect(timeout: connectTimeout) { + case .success: + basicChannel = SimulatorCardChannel( + card: self, + client: client, + messageLength: maxMessageLength, + responseLength: maxResponseLength + ) + return basicChannel! // swiftlint:disable:this force_unwrapping + case let .failure(error): + throw CardError.connectionError(error) + } + } + + public func openLogicChannel() throws -> CardChannelType { + throw CardError.connectionError(CommonError.notImplementedError) + } + + public func openLogicChannelAsync() async throws -> CardChannelType { + throw CardError.connectionError(CommonError.notImplementedError) + } + + public func disconnect(reset _: Bool) throws { + do { + try basicChannel?.close() + } catch { + ALog("Error while closing basicChannel: [\(error)]") + } + } + + deinit { + do { + try disconnect(reset: false) + } catch { + ALog("Error while deinit: [\(error)]") + } + } +} diff --git a/CardSimulationTestKit/Sources/CardSimulationCardReaderProvider/Card/SimulatorCardChannel.swift b/CardSimulationTestKit/Sources/CardSimulationCardReaderProvider/Card/SimulatorCardChannel.swift new file mode 100644 index 0000000..bb64a2c --- /dev/null +++ b/CardSimulationTestKit/Sources/CardSimulationCardReaderProvider/Card/SimulatorCardChannel.swift @@ -0,0 +1,199 @@ +// +// Copyright (c) 2023 gematik GmbH +// +// Licensed under the Apache License, Version 2.0 (the License); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an 'AS IS' BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import CardReaderProviderApi +import Foundation +import GemCommonsKit +import SwiftSocket + +protocol TCPClientType: InputStreaming, OutputStreaming { + func close() throws +} + +public class SimulatorCardChannel: CardChannelType { + public enum SimulatorError: Swift.Error, Equatable { + case outputStreamUnavailable + case noResponse + case invalidResponse + case asn1coding(Swift.Error) + case commandSizeTooLarge(maxSize: Int, length: Int) + case responseSizeTooLarge(maxSize: Int, length: Int) + + public var connectionError: CardError { + CardError.connectionError(self) + } + + public var illegalState: CardError { + CardError.illegalState(self) + } + + // swiftlint:disable:next operator_whitespace + public static func ==(lhs: SimulatorError, rhs: SimulatorError) -> Bool { + switch (lhs, rhs) { + case (.outputStreamUnavailable, .outputStreamUnavailable): return true + case (.noResponse, .noResponse): return true + case (.asn1coding, .asn1coding): return true + case let (.commandSizeTooLarge(lhsMax, lhsSize), .commandSizeTooLarge(rhsMax, rhsSize)): + return lhsMax == rhsMax && lhsSize == rhsSize + case let (.responseSizeTooLarge(lhsMax, lhsSize), .responseSizeTooLarge(rhsMax, rhsSize)): + return lhsMax == rhsMax && lhsSize == rhsSize + default: + return false + } + } + } + + public private(set) var card: CardType + public private(set) var channelNumber: Int = 0 + public private(set) var extendedLengthSupported: Bool + public private(set) var maxMessageLength: Int + public private(set) var maxResponseLength: Int + let tcpClient: TCPClientType + var inputStream: InputStreaming { + tcpClient + } + + var outputStream: OutputStreaming { + tcpClient + } + + init(card: CardType, + client: TCPClientType, + messageLength: Int, + responseLength: Int, + extendedLengthSupport: Bool = true) { + self.card = card + tcpClient = client + maxMessageLength = messageLength + maxResponseLength = responseLength + extendedLengthSupported = extendedLengthSupport + } + + /// Transmit a command and return the response + /// - Parameters: + /// - command: the command gets berTlv encoded and send to the Kartensimulation + /// - throws: + /// - SimulatorError.outputStreamUnavailable.illegalState when the stream has no space available to write + /// - Returns: the berTlv decoded response APDU + public func transmit(command: CommandType, writeTimeout _: TimeInterval, readTimeout: TimeInterval) throws + -> ResponseType { + guard outputStream.hasSpaceAvailable else { + throw SimulatorError.outputStreamUnavailable.illegalState + } + guard command.bytes.count <= maxMessageLength else { + throw SimulatorError.commandSizeTooLarge(maxSize: maxMessageLength, length: command.bytes.count) + .illegalState + } + let message = try command.bytes.berTlvEncoded() + DLog("SEND: \(message.map { String(format: "%02hhX", $0) }.joined())") // hexString + _ = message.withUnsafeBytes { + outputStream.write($0, maxLength: message.count) + } + + var buffer = [UInt8](repeating: 0x0, count: maxResponseLength) + var responseData = Data() + let timeoutTime = (readTimeout == 0) ? Date.distantFuture : Date(timeIntervalSinceNow: readTimeout) + repeat { + guard inputStream.hasBytesAvailable else { + RunLoop.current.run(mode: .default, before: Date(timeIntervalSinceNow: 0.05)) + continue + } + let readBytes = inputStream.read(&buffer, maxLength: maxResponseLength) + guard readBytes != -1 else { + throw SimulatorError.noResponse.connectionError + } + buffer.withContiguousStorageIfAvailable { bytes in + // swiftlint:disable:next force_unwrapping + responseData.append(bytes.baseAddress!, count: readBytes) + } + } while inputStream.hasBytesAvailable || (responseData.isEmpty && Date() < timeoutTime) + + guard !responseData.isEmpty else { + ALog("Error when reading the response from the CardSimulator connection" + + " or there were no bytes available to be read.") + throw SimulatorError.noResponse.connectionError + } + + DLog("RESPONSE: \(responseData.map { String(format: "%02hhX", $0) }.joined())") // hexString + let extractedResponseData = try responseData.berTlvDecoded() + guard extractedResponseData.count <= maxResponseLength else { + throw SimulatorError.responseSizeTooLarge(maxSize: maxResponseLength, length: responseData.count) + .illegalState + } + + return try APDU.Response(apdu: extractedResponseData) + } + + public func transmitAsync( + command: CardReaderProviderApi.CommandType, + writeTimeout _: TimeInterval, + readTimeout: TimeInterval + ) async throws -> CardReaderProviderApi.ResponseType { + guard outputStream.hasSpaceAvailable else { + throw SimulatorError.outputStreamUnavailable.illegalState + } + guard command.bytes.count <= maxMessageLength else { + throw SimulatorError.commandSizeTooLarge(maxSize: maxMessageLength, length: command.bytes.count) + .illegalState + } + let message = try command.bytes.berTlvEncoded() + DLog("SEND: \(message.map { String(format: "%02hhX", $0) }.joined())") // hexString + _ = message.withUnsafeBytes { + outputStream.write($0, maxLength: message.count) + } + + var buffer = [UInt8](repeating: 0x0, count: maxResponseLength) + var responseData = Data() + let timeoutTime = (readTimeout == 0) ? Date.distantFuture : Date(timeIntervalSinceNow: readTimeout) + repeat { + guard inputStream.hasBytesAvailable else { + RunLoop.current.run(mode: .default, before: Date(timeIntervalSinceNow: 0.05)) + continue + } + let readBytes = inputStream.read(&buffer, maxLength: maxResponseLength) + guard readBytes != -1 else { + throw SimulatorError.noResponse.connectionError + } + buffer.withContiguousStorageIfAvailable { bytes in + // swiftlint:disable:next force_unwrapping + responseData.append(bytes.baseAddress!, count: readBytes) + } + } while inputStream.hasBytesAvailable || (responseData.isEmpty && Date() < timeoutTime) + + guard !responseData.isEmpty else { + ALog("Error when reading the response from the CardSimulator connection" + + " or there were no bytes available to be read.") + throw SimulatorError.noResponse.connectionError + } + + DLog("RESPONSE: \(responseData.map { String(format: "%02hhX", $0) }.joined())") // hexString + let extractedResponseData = try responseData.berTlvDecoded() + guard extractedResponseData.count <= maxResponseLength else { + throw SimulatorError.responseSizeTooLarge(maxSize: maxResponseLength, length: responseData.count) + .illegalState + } + + return try APDU.Response(apdu: extractedResponseData) + } + + public func close() throws { + try tcpClient.close() + } + + public func closeAsync() async throws { + try tcpClient.close() + } +} diff --git a/CardSimulationTestKit/Sources/CardSimulationCardReaderProvider/Provider/SimulatorCardReaderProvider.swift b/CardSimulationTestKit/Sources/CardSimulationCardReaderProvider/Provider/SimulatorCardReaderProvider.swift new file mode 100644 index 0000000..789b64d --- /dev/null +++ b/CardSimulationTestKit/Sources/CardSimulationCardReaderProvider/Provider/SimulatorCardReaderProvider.swift @@ -0,0 +1,36 @@ +// +// Copyright (c) 2023 gematik GmbH +// +// Licensed under the Apache License, Version 2.0 (the License); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an 'AS IS' BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import CardReaderProviderApi +import CardSimulationLoader +import Foundation + +public class SimulatorCardReaderProvider: NSObject, CardReaderProviderType { + public static let name = "cardsim" + + public static let descriptor: ProviderDescriptorType = ProviderDescriptor( + SimulatorCardReaderProvider.name, + "(c) Gematik 2019", + "TCP channel Card Reader Provider for the G2-Kartensimulator.", + "G2-Kartensimulator CRP", + "CardSimulationCardReaderProvider.SimulatorCardTerminalControllerProvider" + ) + + public class func provideCardReaderController() -> CardReaderControllerObjcWrapper { + let controller = SimulatorCardReaderController(manager: SimulationManager.shared) + return CardReaderControllerObjcWrapper(controller) + } +} diff --git a/CardSimulationTestKit/Sources/CardSimulationCardReaderProvider/Terminal/SimulatorCardReader.swift b/CardSimulationTestKit/Sources/CardSimulationCardReaderProvider/Terminal/SimulatorCardReader.swift new file mode 100644 index 0000000..72941d6 --- /dev/null +++ b/CardSimulationTestKit/Sources/CardSimulationCardReaderProvider/Terminal/SimulatorCardReader.swift @@ -0,0 +1,92 @@ +// +// Copyright (c) 2023 gematik GmbH +// +// Licensed under the Apache License, Version 2.0 (the License); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an 'AS IS' BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import CardReaderProviderApi +import CardSimulationLoader +import Foundation +import GemCommonsKit + +public class SimulatorCardReader: CardReaderType { + public enum CardReaderError: Error { + case simulatorNotRunning + } + + typealias CardPresentBlock = (CardReaderType) -> Void + + public var name: String { + mode.simulationName(on: _host) + } + + public var cardPresent: Bool { + mode.isRunning + } + + internal let simulationRunner: SimulationRunnerType + private var _prevMode: SimulationProcessMode? + private var _cardPresentBlock: CardPresentBlock? + private let _host: String + + var mode: SimulationProcessMode { + simulationRunner.mode + } + + init(cardReader runner: SimulationRunnerType, host: String = "localhost") { + simulationRunner = runner + _host = host + checkRunnerModeDidChange() + } + + public func onCardPresenceChanged(_ block: @escaping (CardReaderType) -> Void) { + _cardPresentBlock = block + if mode.isRunning { + block(self) + } + } + + public func connect(_: [String: Any]) throws -> CardType? { + try connect(protocol: .t1) + } + + public func connect(protocol: CardProtocol) throws -> CardType { + guard let port = simulationRunner.mode.tlvPort else { + throw CardReaderError.simulatorNotRunning + } + return SimulatorCard(host: _host, port: port, channel: `protocol`) + } + + internal func checkRunnerModeDidChange() { + let currentMode = mode + if currentMode != _prevMode { + defer { + _prevMode = currentMode + } + if currentMode.isRunning { + _cardPresentBlock?(self) + } + } + } +} + +extension SimulationProcessMode { + internal func simulationName(prefix: String = "cardsim", on host: String) -> String { + switch self { + case let .running(onTCPPort): return "\(prefix)-\(host)-\(onTCPPort)" + case .terminated: return "\(prefix)-\(host)-x" + case .initializing: return "\(prefix)-\(host)-?" + case .notStarted: return "\(prefix)-\(host)-?" + } + } +} diff --git a/CardSimulationTestKit/Sources/CardSimulationCardReaderProvider/Terminal/SimulatorCardReaderController.swift b/CardSimulationTestKit/Sources/CardSimulationCardReaderProvider/Terminal/SimulatorCardReaderController.swift new file mode 100644 index 0000000..596808e --- /dev/null +++ b/CardSimulationTestKit/Sources/CardSimulationCardReaderProvider/Terminal/SimulatorCardReaderController.swift @@ -0,0 +1,80 @@ +// +// Copyright (c) 2023 gematik GmbH +// +// Licensed under the Apache License, Version 2.0 (the License); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an 'AS IS' BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import CardReaderProviderApi +import CardSimulationLoader +import Foundation +import GemCommonsKit + +public class SimulatorCardReaderController: CardReaderControllerType { + public let name = SimulatorCardReaderProvider.name + + private let simulationManager: SimulationManagerType + private let cardReaderDelegates = WeakArray() + private var simulatorCardReaders = [SimulatorCardReader]() + + init(manager: SimulationManagerType) { + simulationManager = manager + + simulationManager.register(delegate: self) + } + + deinit { + simulationManager.deregister(delegate: self) + } + + public var cardReaders: [CardReaderType] { + simulatorCardReaders.map { $0 } + } + + public func add(delegate: CardReaderControllerDelegate) { + if cardReaderDelegates.index(of: delegate) == nil { + cardReaderDelegates.add(object: delegate) + simulatorCardReaders.forEach { cardReader in + delegate.cardReader(controller: self, didConnect: cardReader) + } + } + } + + public func remove(delegate: CardReaderControllerDelegate) { + guard let index = cardReaderDelegates.index(of: delegate) else { + return + } + cardReaderDelegates.removeObject(at: index) + } +} + +extension SimulatorCardReaderController: SimulationManagerDelegate { + public func simulation(manager _: SimulationManagerType, didStart simulator: SimulationRunnerType) { + let cardReader = SimulatorCardReader(cardReader: simulator) + simulatorCardReaders.append(cardReader) + cardReaderDelegates.array.forEach { + $0.cardReader(controller: self, didConnect: cardReader) + } + } + + public func simulation(manager _: SimulationManagerType, didEnd simulator: SimulationRunnerType) { + let predicate: (SimulatorCardReader) -> Bool = { cardReader in cardReader.simulationRunner === simulator } + if let cardReader = simulatorCardReaders.first(where: predicate) { + cardReaderDelegates.array.forEach { delegate in + delegate.cardReader(controller: self, didDisconnect: cardReader) + } + } + simulatorCardReaders.removeAll { + $0.simulationRunner === simulator + } + } +} diff --git a/CardSimulationTestKit/Sources/CardSimulationCardReaderProvider/internal/Data+BerTLV.swift b/CardSimulationTestKit/Sources/CardSimulationCardReaderProvider/internal/Data+BerTLV.swift new file mode 100644 index 0000000..99dcb2c --- /dev/null +++ b/CardSimulationTestKit/Sources/CardSimulationCardReaderProvider/internal/Data+BerTLV.swift @@ -0,0 +1,44 @@ +// +// Copyright (c) 2023 gematik GmbH +// +// Licensed under the Apache License, Version 2.0 (the License); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an 'AS IS' BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import ASN1Kit +import Foundation + +extension Data { + /// Decode the data by stripping the Ber TLV prefix header + /// - Throws: `SimulatorCardReader.SimulatorError` + /// - Returns: The decoded part of the data when a Ber TLV header was found, otherwise self is returned + public func berTlvDecoded() throws -> Data { + do { + let asn1object = try ASN1Decoder.decode(asn1: self) + guard let data = asn1object.data.primitive else { + throw SimulatorCardChannel.SimulatorError.asn1coding("Illegal BER-TLV Data structure") + } + return data + } catch { + throw SimulatorCardChannel.SimulatorError.asn1coding(error) + } + } + + /// Add a Ber TLV header to the Data blob + /// - Throws: `SimulatorCardReader.SimulatorError` + /// - Returns: the data with the Ber TLV header in front + public func berTlvEncoded() throws -> Data { + try asn1encode(tag: .taggedTag(0)).serialize() + } +} + +extension String: Error {} diff --git a/CardSimulationTestKit/Sources/CardSimulationCardReaderProvider/internal/InputStreaming.swift b/CardSimulationTestKit/Sources/CardSimulationCardReaderProvider/internal/InputStreaming.swift new file mode 100644 index 0000000..d0673b8 --- /dev/null +++ b/CardSimulationTestKit/Sources/CardSimulationCardReaderProvider/internal/InputStreaming.swift @@ -0,0 +1,23 @@ +// +// Copyright (c) 2023 gematik GmbH +// +// Licensed under the Apache License, Version 2.0 (the License); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an 'AS IS' BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import Foundation + +protocol InputStreaming { + var hasBytesAvailable: Bool { get } + + func read(_ buffer: UnsafeMutablePointer, maxLength len: Int) -> Int +} diff --git a/CardSimulationTestKit/Sources/CardSimulationCardReaderProvider/internal/OutputStreaming.swift b/CardSimulationTestKit/Sources/CardSimulationCardReaderProvider/internal/OutputStreaming.swift new file mode 100644 index 0000000..327d70b --- /dev/null +++ b/CardSimulationTestKit/Sources/CardSimulationCardReaderProvider/internal/OutputStreaming.swift @@ -0,0 +1,23 @@ +// +// Copyright (c) 2023 gematik GmbH +// +// Licensed under the Apache License, Version 2.0 (the License); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an 'AS IS' BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import Foundation + +protocol OutputStreaming { + var hasSpaceAvailable: Bool { get } + + func write(_ buffer: UnsafePointer, maxLength len: Int) -> Int +} diff --git a/CardSimulationTestKit/Sources/CardSimulationCardReaderProvider/internal/TCPClient+Streaming.swift b/CardSimulationTestKit/Sources/CardSimulationCardReaderProvider/internal/TCPClient+Streaming.swift new file mode 100644 index 0000000..606977d --- /dev/null +++ b/CardSimulationTestKit/Sources/CardSimulationCardReaderProvider/internal/TCPClient+Streaming.swift @@ -0,0 +1,54 @@ +// +// Copyright (c) 2023 gematik GmbH +// +// Licensed under the Apache License, Version 2.0 (the License); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an 'AS IS' BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import Foundation +import GemCommonsKit +import SwiftSocket + +extension TCPClient: TCPClientType { + var hasBytesAvailable: Bool { + guard let availableBytes = bytesAvailable() else { + return false + } + return availableBytes > 0 + } + + func read(_ buffer: UnsafeMutablePointer, maxLength len: Int) -> Int { + guard let availableBytes = bytesAvailable() else { + return 0 + } + + let bufferSize = min(Int(availableBytes), len) + guard let bytes = read(bufferSize) else { + ALog("Read error") + return -1 + } + buffer.assign(from: bytes, count: bytes.count) + return bytes.count + } + + var hasSpaceAvailable: Bool { + fd != nil + } + + func write(_ buffer: UnsafePointer, maxLength len: Int) -> Int { + let data = Data(bytes: buffer, count: len) + switch send(data: data) { + case .failure: return -1 + case .success: return data.count + } + } +} diff --git a/CardSimulationTestKit/Sources/CardSimulationLoader/KeepAliveRunLoop.swift b/CardSimulationTestKit/Sources/CardSimulationLoader/KeepAliveRunLoop.swift new file mode 100644 index 0000000..16d9aba --- /dev/null +++ b/CardSimulationTestKit/Sources/CardSimulationLoader/KeepAliveRunLoop.swift @@ -0,0 +1,66 @@ +// +// Copyright (c) 2023 gematik GmbH +// +// Licensed under the Apache License, Version 2.0 (the License); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an 'AS IS' BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import Foundation +import GemCommonsKit + +/** + KeepAliveRunLoop keeps a thread running in .default until the thread gets cancelled + + Actions can be scheduled on this thread's RunLoop to be executed on this Thread. + */ +public class KeepAliveRunLoop: Thread { + private let _runloop = BlockingVar() + + /** + Get the runloop for this thread. + + Caution: make sure the Thread has been started before calling the runloop + Note: this is a blocking call + + - Returns: the thread's RunLoop + */ + public private(set) var runloop: RunLoop { + get { + _runloop.value + } + set { + _runloop.value = newValue + } + } + + /// Do not call directly + override public func main() { + DLog("KeepAliveRunLoop started") + runloop = RunLoop.current + let port = Port() + RunLoop.current.add(port, forMode: .common) + while !isCancelled { + RunLoop.current.run(mode: .default, before: Date.distantFuture) + } + RunLoop.current.remove(port, forMode: .common) + port.invalidate() + DLog("Port invalidated and thread ended") + } + + /// Cancel the Thread and RunLoop + override public func cancel() { + let cfRl = runloop.getCFRunLoop() + CFRunLoopStop(cfRl) + + super.cancel() + } +} diff --git a/CardSimulationTestKit/Sources/CardSimulationLoader/Resources.bundle/pom.xml b/CardSimulationTestKit/Sources/CardSimulationLoader/Resources.bundle/pom.xml new file mode 100644 index 0000000..17fc8c8 --- /dev/null +++ b/CardSimulationTestKit/Sources/CardSimulationLoader/Resources.bundle/pom.xml @@ -0,0 +1,22 @@ + + 4.0.0 + + CardSimulation-test + cardsimulation.exec + de.gematik.ti + [Do not edit - will be overriden] + + + + de.gematik + de.gematik.egk.g2sim.product + ${project.version} + + + + + ${project.artifactId} + ./${project.name}-${project.version} + + diff --git a/CardSimulationTestKit/Sources/CardSimulationLoader/SimulationLoaderError.swift b/CardSimulationTestKit/Sources/CardSimulationLoader/SimulationLoaderError.swift new file mode 100644 index 0000000..c62bb0b --- /dev/null +++ b/CardSimulationTestKit/Sources/CardSimulationLoader/SimulationLoaderError.swift @@ -0,0 +1,31 @@ +// +// Copyright (c) 2023 gematik GmbH +// +// Licensed under the Apache License, Version 2.0 (the License); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an 'AS IS' BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import Foundation + +/// CardSimulationLoader error cases +public enum SimulationLoaderError: Error { + /// when a bash script terminated with non-0 status. + /// - Parameter status: the termination status code + case shellProcessTerminatedUnexpected(status: Int32) + /// This project is only suitable for non-iOS platforms, since forking processes is forbidden on iOS + /// - Parameter name: The current platform name + case unsupportedPlatform(name: String) + /// When resource data is non-existing or unusable + case resourceNotFound(String) + /// When configuration files and/or pom files are missing mandatory information + case malformedConfiguration +} diff --git a/CardSimulationTestKit/Sources/CardSimulationLoader/SimulationManager.swift b/CardSimulationTestKit/Sources/CardSimulationLoader/SimulationManager.swift new file mode 100644 index 0000000..094c22d --- /dev/null +++ b/CardSimulationTestKit/Sources/CardSimulationLoader/SimulationManager.swift @@ -0,0 +1,314 @@ +// +// Copyright (c) 2023 gematik GmbH +// +// Licensed under the Apache License, Version 2.0 (the License); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an 'AS IS' BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import Foundation +import GemCommonsKit + +/// Protocol that describes G2-Kartensimulation Configuration files (pre-)processors +public protocol ConfigurationFileProcessor { + /// The return type after preparing the config file + associatedtype Processed + + /** + Prepare the configuration for the simulation runtime by mutating its original contents with the `manipulators`. + + - Parameters: + - manipulators: The XMLManipulators for the specified XML paths + + - Returns: Result + */ + func prepareXMLConfigFile(with manipulators: [XMLPathManipulator]) -> Result +} + +/// Delegate protocol to inform about start/stopped SimulationRunners +public protocol SimulationManagerDelegate: AnyObject { + /** + Invoked when a `SimulationManagerType` has started a `SimulationRunnerType` + + - Parameters: + - manager: the managing manager + - simulator: the newly started simulation + */ + func simulation(manager: SimulationManagerType, didStart simulator: SimulationRunnerType) + + /** + Invoked when a `SimulationRunnerType` has terminated or 'failed' to launch and therefore terminated. + + - Note: that it is possible to get a 'didEnd' notification without a prior 'didStart' notification. + + - Parameters: + - manager: the managing manager + - simulator: the terminated simulation + */ + func simulation(manager: SimulationManagerType, didEnd simulator: SimulationRunnerType) +} + +/// SimulationManagerType that allows delegates to register for `SimulationRunnerType` updates +public protocol SimulationManagerType { + /// Register a delegate to get updated on `SimulationRunnerType`s + /// - Parameter delegate: the delegate to add + func register(delegate: SimulationManagerDelegate) + /// De-register a delegate to get updated on `SimulationRunnerType`s + /// - Parameter delegate: the delegate to remove + func deregister(delegate: SimulationManagerDelegate) + + /** + Create a simulator runner instance. + + - Note: The Simulation should be configured and dependencies may have been downloaded/running. + But the SimulationRunnerType itself should not have been launched yet. + + - Parameters: + - configFile: the URL to the main G2-Kartensimulation configFile + - manipulators: list of `XMLPathManipulator`s to manipulate configFile + - simulatorVersion: the *de.gematik.egk.g2sim.product* artifacts version to download/use + - simulatorDirectory: the path to append to the transient directory where the artifacts need to be stored + - flag: indicate whether to wait until the JavaProcess has finished launching and initializing. + + - Throws: when the configuration in malformed and/or the simulator couldn't be launched. + + - Returns: the SimulationRunner instance that monitors the launched simulator. + */ + func createSimulation( + configFile: URL, + preprocessor manipulators: [XMLPathManipulator], + simulatorVersion: String, + simulatorDirectory: String + ) throws -> SimulationRunnerType + + /** + Stop the passed simulation and deregister from the manager when needed. + + - Parameters: + - simulation: the simulation (process) to stop + - flag: indicate whether this function should wait until the process has terminated + */ + func stop(simulation: SimulationRunnerType, waitUntilDone flag: Bool) + + /** + Stop all simulation instances registered with this manager. + + - Parameter flag: indicate whether this function should wait until all the processes have been terminated + */ + func stopAll(waitUntilDone flag: Bool) +} + +/** + Main class that provides `SimulationRunner`s when launching G2-Kartensimulations. + */ +public class SimulationManager { + /// Singleton instance of `SimulationManager` + public static let shared = { + SimulationManager() + }() + + /// The default G2-Kartensimulation version + public static let defaultVersion = "2.8.4-436" + + private var _delegates = WeakArray() + + private var _runners: [(url: URL, simulator: SimulationRunnerType)] = [] + + /// Currently running `SimulationRunnerType`s + public var runners: [SimulationRunnerType] { + _runners.map(\.simulator) + } + + private let tempDirectory: URL + + /// Initialize a SimulationManager with a custom tempDir if needed. + /// + /// - SeeAlso: `SimulationManager.shared` for general purpose use + /// + /// - Parameters: + /// - tempDir: path to a directory to be used as temporary directory for storing dependencies and configuration. + /// - Returns: a new SimulationManger + public init(tempDir: URL = NSTemporaryDirectory().asURL.appendingPathComponent( + ProcessInfo.processInfo.globallyUniqueString, isDirectory: true + )) { + DLog("Init with tempDir: [\(tempDir)]") + tempDirectory = tempDir + } + + /** + Start a simulation instance. + + - Parameters: + - configFile: the URL to the main G2-Kartensimulation configFile + - manipulators: list of `XMLPathManipulator`s to manipulate configFile + - simulatorVersion: the *de.gematik.egk.g2sim.product* artifacts version to download/use + - simulatorDirectory: the path to append to the transient directory where the artifacts need to be stored + - flag: indicate whether to wait until the JavaProcess has finished launching and initializing. + + - Throws: when the configuration in malformed and/or the simulator couldn't be launched. + + - Returns: the SimulationRunner instance that monitors the launched simulator. + */ + public func createSimulation( + configFile: URL, + preprocessor manipulators: [XMLPathManipulator] = [], + simulatorVersion: String = defaultVersion, + simulatorDirectory: String = "simulator" + ) throws -> SimulationRunnerType { + let simPath = tempDirectory.appendingPathComponent(simulatorDirectory, isDirectory: true) + let pomXml = try Data(contentsOf: Bundle(for: SimulationManager.self) + .resourceFilePath(in: "Resources", for: "pom.xml").asURL) + + // Load simulator dependencies + return try SimulationManager.loadCardSimulatorDependencies( + version: simulatorVersion, + outputDirectory: simPath, + pom: pomXml + ) + .flatMap { dependencyInfo in + // Prepare Simulator XML configuration + configFile.prepareXMLConfigFile(with: manipulators) + .flatMap { [unowned self] simConfigDoc in + Result { + try simConfigDoc.createXML() + } + .flatMap { (xmlData: Data) in + xmlData.save(to: self.tempFile(for: configFile)) + .flatMap { [unowned self] result in + // Start/Run the simulator instance + Result { + try self.manageSimulation(simulator: result.url, dependency: dependencyInfo) + } + } + } + } + } + .get() + } + + // Create and Manage the SimulationRunner (but not yet launch it) + func manageSimulation( + simulator file: URL, dependency info: SimulationManager.DependencyInfo + ) throws -> SimulationRunnerType { + guard let simClassPath = info.simulatorClassPath else { + throw SimulationLoaderError.malformedConfiguration + } + let simulator = SimulationRunner(simulator: file, classPath: simClassPath) + simulator.delegate = self + _runners.append((url: file, simulator: simulator)) + return simulator + } + + /** + Stop the passed simulation and deregister from the manager when needed. + + - Parameters: + - simulation: the simulation (process) to stop + - flag: indicate whether this function should wait until the process has terminated + */ + public func stop(simulation: SimulationRunnerType, waitUntilDone flag: Bool = true) { + simulation.stop(waitUntilTerminated: flag) + remove(simulation: simulation) + } + + /** + Stop all simulation instances registered with this manager. + + - Parameter flag: indicate whether this function should wait until all the processes have been terminated + */ + public func stopAll(waitUntilDone flag: Bool = true) { + DLog("Stop all simulators") + runners.forEach { [unowned self] in + self.stop(simulation: $0, waitUntilDone: flag) + } + } + + private func remove(simulation: SimulationRunnerType) { + /// clean the temp files for this SimulationRunnerType + _runners.filter { + $0.1 === simulation + } + .forEach { + DLog("Cleaning: \($0.url)") + do { + try FileManager.default.removeItem(at: $0.url) + } catch { + ALog("Failed to clean simulator runner environment: [\(error)]") + } + } + /// Remove the simulation from the runners array + _runners.removeAll { + $0.1 === simulation + } + /// Inform delegates + _delegates.array.forEach { + $0.simulation(manager: self, didEnd: simulation) + } + } + + /** + Clean and remove all transient files and artifacts associated with this instance. + */ + public func clean() { + do { + try FileManager.default.removeItem(at: tempDirectory) + } catch { + ALog("Failed to clean [\(error)]") + } + } +} + +extension SimulationManager: SimulationManagerType { + /// Register a delegate to get updated on `SimulationRunnerType`s + /// - Parameter delegate: the delegate to add + public func register(delegate: SimulationManagerDelegate) { + if _delegates.index(of: delegate) == nil { + _delegates.add(object: delegate) + _runners.forEach { [unowned self] in + delegate.simulation(manager: self, didStart: $0.simulator) + } + } + } + + /// De-register a delegate to get updated on `SimulationRunnerType`s + /// - Parameter delegate: the delegate to remove + public func deregister(delegate: SimulationManagerDelegate) { + guard let index = _delegates.index(of: delegate) else { + return // Not in delegate array + } + _delegates.removeObject(at: index) + } +} + +extension SimulationManager: TempFilePathGeneratorType { + func tempFile(for path: URL) -> URL { + tempDirectory + .appendingPathComponent(ProcessInfo.processInfo.globallyUniqueString, isDirectory: true) + .appendingPathComponent(path.lastPathComponent) + } +} + +extension SimulationManager: SimulationRunnerDelegate { + /** + Simulation manager's delegate for the runner. + */ + public func simulation(runner: SimulationRunnerType, changed mode: SimulationProcessMode) { + DLog("Simulation: \(runner) -> [\(mode)]") + if mode.isRunning { + /// Inform delegates + _delegates.array.forEach { + $0.simulation(manager: self, didStart: runner) + } + } else if mode.isTerminated { + remove(simulation: runner) + } + } +} diff --git a/CardSimulationTestKit/Sources/CardSimulationLoader/SimulationProcessMode.swift b/CardSimulationTestKit/Sources/CardSimulationLoader/SimulationProcessMode.swift new file mode 100644 index 0000000..345c83d --- /dev/null +++ b/CardSimulationTestKit/Sources/CardSimulationLoader/SimulationProcessMode.swift @@ -0,0 +1,114 @@ +// +// Copyright (c) 2023 gematik GmbH +// +// Licensed under the Apache License, Version 2.0 (the License); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an 'AS IS' BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import Foundation + +/// SimulationRunner state cases. +public enum SimulationProcessMode { + /// Freshly created SimulationRunner that has not been used at all + case notStarted + /// Launched the process and is processing the initialization + case initializing + /// Process is successfully initialized and accessible through port number + /// - Parameter onTCPPort: accessible through port number + case running(onTCPPort: Int32) + /// Process has been launched and terminated + /// - Parameter terminationStatus: the process' termination status code + case terminated(terminationStatus: Int32) +} + +extension SimulationProcessMode: Equatable { + // swiftlint:disable operator_whitespace + public static func ==(lhs: SimulationProcessMode, rhs: SimulationProcessMode) -> Bool { + switch lhs { + case let .running(onTCPPort): return rhs.tlvPort == onTCPPort + case .notStarted: return rhs.isNotRunning + case .initializing: return rhs.isInitializing + case let .terminated(terminationStatus): return rhs.terminationStatus == terminationStatus + } + } + + // swiftlint:enable operator_whitespace +} + +extension SimulationProcessMode { + /// true when `.terminated` + public var isTerminated: Bool { + if case .terminated = self { + return true + } + return false + } + + /// true when `.notStarted` + public var isNotRunning: Bool { + if case .notStarted = self { + return true + } + return false + } + + /// true when `.running` + public var isRunning: Bool { + if case .running = self { + return true + } + return false + } + + /// true when `.initializing` + public var isInitializing: Bool { + if case .initializing = self { + return true + } + return false + } + + /// when running the port number is returned else nil + public var tlvPort: Int32? { + switch self { + case let .running(onTCPPort): return onTCPPort + default: return nil + } + } + + /// when terminated the termination status code else nil + public var terminationStatus: Int32? { + switch self { + case let .terminated(terminationStatus): return terminationStatus + default: return nil + } + } +} + +extension SimulationProcessMode: CustomDebugStringConvertible { + /// Debug info + public var debugDescription: String { + description + } +} + +extension SimulationProcessMode: CustomStringConvertible { + /// String-value + public var description: String { + switch self { + case .notStarted: return "Not Started" + case .initializing: return "Initializing" + case let .running(port): return "Running on TCP: [\(port)]" + case let .terminated(terminationStatus): return "Terminated (exit: [\(terminationStatus))]" + } + } +} diff --git a/CardSimulationTestKit/Sources/CardSimulationLoader/SimulationRunner.swift b/CardSimulationTestKit/Sources/CardSimulationLoader/SimulationRunner.swift new file mode 100644 index 0000000..6523ab5 --- /dev/null +++ b/CardSimulationTestKit/Sources/CardSimulationLoader/SimulationRunner.swift @@ -0,0 +1,152 @@ +// +// Copyright (c) 2023 gematik GmbH +// +// Licensed under the Apache License, Version 2.0 (the License); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an 'AS IS' BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import Foundation +import GemCommonsKit +import StreamReader + +/// Protocol that describes `SimulationRunnerType` behaviour. +public protocol SimulationRunnerType: AnyObject { + /// The mode the runner is currently in + var mode: SimulationProcessMode { get } + + /// Launch the `SimulationRunnerType` - assuming did not run before + /// - Parameter waitUntilLaunched: + /// indicate whether the function should wait until the process has finished launching + func start(waitUntilLaunched: Bool) + + /// Stop the `SimulationRunnerType` + /// - Parameter waitUntilLaunched: + /// indicate whether the function should wait until the process has finished terminating + func stop(waitUntilTerminated: Bool) +} + +/// Delegate protocol gets informed on `SimulationProcessMode` changes for a given `SimulationRunnerType` +public protocol SimulationRunnerDelegate: AnyObject { + /** + Invoked on a delegate when the run mode changes. + + - Parameters: + - runner: the simulation for which the mode has changed + - mode: the new/current process mode + */ + func simulation(runner: SimulationRunnerType, changed mode: SimulationProcessMode) +} + +/** + This class takes care of launching a `JavaProcess` and building its configuration + and thereafter monitor its process state. + */ +public class SimulationRunner { + private let _mode = SynchronizedVar(.notStarted) + private let javaClassPath: URL + private let simulatorConfig: URL + private let workingDirectory: URL + internal let processThread: KeepAliveRunLoop + internal var processLoader: JavaProcess? + internal lazy var stdoutInfo: (pipe: Pipe, reader: StreamReader) = { + let pipe = Pipe() + + let delimiterData = "\n".data(using: .utf8) ?? Data() + // Note chunkSize = 1 else the StreamReader will block until the chunk is filled, blocking this Runner to + // detect a successful start indefinitely + return (pipe, StreamReader(fileHandle: pipe.fileHandleForReading, + delimiterData: delimiterData, + encoding: .utf8, + chunkSize: 1)) + }() + + internal var streamThread: KeepAliveRunLoop! + + /// The delegate that gets informed when `self.mode` changes + public weak var delegate: SimulationRunnerDelegate? + + /** + The designated initializer. + + - Parameters: + - file: configuration file + - classPath: the path to the G2-Kartensimulation artifacts + - dir: the working directory for the JavaProcess to be launched. Default is `FileManager.currentDirectory` + - thread: the thread wherein to monitor the process' state and (initialization) progress. Default a new + `KeepAliveRunLoop`. + */ + public required init(simulator file: URL, + classPath: URL, + workingDirectory dir: URL = FileManager.default.currentDirectoryPath.asURL, + in thread: KeepAliveRunLoop = KeepAliveRunLoop()) { + simulatorConfig = file + javaClassPath = classPath + processThread = thread + workingDirectory = dir + } + + internal lazy var config = JavaProcess.Config.build( + workingDirectory: workingDirectory.absoluteURL.path, + classPath: javaClassPath.absoluteURL.path + "/*", + arguments: ["-configFile", simulatorConfig.absoluteURL.path] + ) + + /// Deinit + deinit { + if mode.isRunning { + stop(waitUntilTerminated: false) + } + } +} + +extension SimulationRunner: SimulationRunnerType { + /// Current runner mode + public internal(set) var mode: SimulationProcessMode { + get { + _mode.value + } + set { + _mode.set { _ in newValue } + delegate?.simulation(runner: self, changed: newValue) + } + } + + /// Start the simulation runner + /// - Parameter flag: whether to pause further execution until the JavaProcess has been (successfully) launched. + public func start(waitUntilLaunched flag: Bool) { + guard mode.isNotRunning else { + DLog("WARN: double start") + return + } + mode = .initializing + + let process = JavaProcess(config: config, stdout: stdoutInfo.pipe, stderr: stdoutInfo.pipe) + processThread.start() + process.run(in: processThread.runloop, delegate: self) + processLoader = process + + if flag { + while !mode.isRunning && !mode.isTerminated { + RunLoop.current.run(mode: .default, before: Date(timeIntervalSinceNow: 0.05)) + } + } + + DLog("start END") + } + + /// Stop the simulation runner + /// - Parameter flag: whether to pause further execution until the JavaProcess has been terminated. + public func stop(waitUntilTerminated flag: Bool) { + DLog("Simulator runner STOP [wait:\(String(describing: flag))]") + processLoader?.terminate(waitUntilDone: flag) + } +} diff --git a/CardSimulationTestKit/Sources/CardSimulationLoader/SimulationRunnerType+Ext.swift b/CardSimulationTestKit/Sources/CardSimulationLoader/SimulationRunnerType+Ext.swift new file mode 100644 index 0000000..d039bd8 --- /dev/null +++ b/CardSimulationTestKit/Sources/CardSimulationLoader/SimulationRunnerType+Ext.swift @@ -0,0 +1,29 @@ +// +// Copyright (c) 2023 gematik GmbH +// +// Licensed under the Apache License, Version 2.0 (the License); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an 'AS IS' BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import Foundation + +extension SimulationRunnerType { + /// TLC port when running + public var tlvPort: Int32? { + mode.tlvPort + } + + /// The termination status code when terminated/ended + public var exitCode: Int32? { + mode.terminationStatus + } +} diff --git a/CardSimulationTestKit/Sources/CardSimulationLoader/internal/JavaProcess.swift b/CardSimulationTestKit/Sources/CardSimulationLoader/internal/JavaProcess.swift new file mode 100644 index 0000000..a5e5122 --- /dev/null +++ b/CardSimulationTestKit/Sources/CardSimulationLoader/internal/JavaProcess.swift @@ -0,0 +1,165 @@ +// +// Copyright (c) 2023 gematik GmbH +// +// Licensed under the Apache License, Version 2.0 (the License); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an 'AS IS' BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import Foundation +import GemCommonsKit + +protocol JavaProcessConfig { + #if os(macOS) || os(Linux) + func makeTask() -> Process + #endif +} + +/** + Process wrapper for launching, monitoring Java processes. + */ +class JavaProcess { + internal struct Config: JavaProcessConfig { + let classPath: String + let mainClass: String + let arguments: [String] + let workingDirectory: String + let launchPath: String + + static func build( + workingDirectory: String, + classPath: String, + mainClass: String = "com.achelos.egk.g2sim.application.Application", + arguments: [String] = [], + launchPath: String = "/usr/bin/java" + ) -> Config { + Config(classPath: classPath, + mainClass: mainClass, + arguments: arguments, + workingDirectory: workingDirectory, + launchPath: launchPath) + } + + #if os(macOS) || os(Linux) + func makeTask() -> Process { + let task = Process() + task.currentDirectoryPath = workingDirectory + task.arguments = ["-cp", classPath, mainClass] + arguments + task.launchPath = launchPath + return task + } + #endif + } + + private let config: JavaProcessConfig + #if os(macOS) || os(Linux) + private var process: Process? + #endif + private let runloop = KeepAliveRunLoop() + + let stdout: Pipe? + let stderr: Pipe? + let stdin: Pipe? + + init(config: JavaProcessConfig, stdout: Pipe? = nil, stderr: Pipe? = nil, stdin: Pipe? = nil) { + self.config = config + self.stdout = stdout + self.stderr = stderr + self.stdin = stdin + } +} + +protocol JavaProcessUpdateDelegate: AnyObject { + func processDidLaunch(_ process: JavaProcess, pid: Int32) + func processDidTerminate(_ process: JavaProcess, with status: Int32) +} + +extension JavaProcessUpdateDelegate { + /// Allow method to be optional + func processDidLaunch(_: JavaProcess, pid _: Int32) {} + + /// Allow method to be optional + func processDidTerminate(_: JavaProcess, with _: Int32) {} +} + +extension JavaProcess { + /// Runs the Java process + public func run(in runloop: RunLoop = RunLoop.current, + mode: RunLoop.Mode = .default, + delegate: JavaProcessUpdateDelegate? = nil) { + #if os(macOS) || os(Linux) + guard process == nil else { + ALog("WARN: double start. Process already started/initialized") + return + } + #endif + runloop.perform(inModes: [mode]) { + let terminationStatusCode = self.launch(delegate) + // Safe-callback on main-thread without blocking the current RunLoop + DispatchQueue.global().async { [weak self, delegate] in + DispatchQueue.main.sync { + if let sSelf = self { + delegate?.processDidTerminate(sSelf, with: terminationStatusCode) + } + } + } + } + } + + private func launch(_ delegate: JavaProcessUpdateDelegate? = nil) -> Int32 { + #if os(macOS) || os(Linux) + let task = config.makeTask() + + if let stderr = self.stderr { + task.standardError = stderr + } + if let stdout = self.stdout { + task.standardOutput = stdout + } + if let stdin = self.stdin { + task.standardInput = stdin + } else { + /// Avoid that the host process Standard Input is piped through to this process + task.standardInput = Pipe() + } + + task.launch() + DLog("JavaProcess launched PID: [\(task.processIdentifier)]") + process = task + DispatchQueue.global().async { + DispatchQueue.main.sync { + delegate?.processDidLaunch(self, pid: task.processIdentifier) + } + } + task.waitUntilExit() + return task.terminationStatus + #else + return 1 + #endif + } + + var isRunning: Bool { + #if os(macOS) || os(Linux) + return process?.isRunning ?? false + #else + return false + #endif + } + + func terminate(waitUntilDone: Bool = false) { + #if os(macOS) || os(Linux) + process?.terminate() + if waitUntilDone { + process?.waitUntilExit() + } + #endif + } +} diff --git a/CardSimulationTestKit/Sources/CardSimulationLoader/internal/SimulationManager+Internal.swift b/CardSimulationTestKit/Sources/CardSimulationLoader/internal/SimulationManager+Internal.swift new file mode 100644 index 0000000..06b9dd2 --- /dev/null +++ b/CardSimulationTestKit/Sources/CardSimulationLoader/internal/SimulationManager+Internal.swift @@ -0,0 +1,146 @@ +// +// Copyright (c) 2023 gematik GmbH +// +// Licensed under the Apache License, Version 2.0 (the License); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an 'AS IS' BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import AEXML +import Foundation +import GemCommonsKit + +extension SimulationManager { + struct DependencyInfo { + let config: AEXMLDocument + private let output: URL + + init(xml: AEXMLDocument, output directory: URL) { + config = xml + output = directory + } + + func simulatorName() throws -> String { + guard let name = config["project"]["name"].value, + let version = config["project"]["version"].value else { + throw SimulationLoaderError.malformedConfiguration + } + return "\(name)-\(version)" + } + + private var simulatorPath: URL { + let version: String + if let projectVersion = config["project"]["version"].value { + version = projectVersion + } else { + version = "0.0.0" + } + return output.appendingPathComponent(version, isDirectory: true) + } + + var simulatorClassPath: URL? { + guard let simName = try? simulatorName() else { + return nil + } + return simulatorPath.appendingPathComponent(simName, isDirectory: true) + .appendingPathComponent("dependency", isDirectory: true) + } + + var pom: URL { + simulatorPath.appendingPathComponent("pom.xml") + } + + var script: URL { + simulatorPath.appendingPathComponent("runMaven.sh") + } + + var simulatorExists: Bool { + FileManager.default.fileExists(atPath: simulatorPath.absoluteURL.path) + } + } + + static func loadCardSimulatorDependencies( + version: String, + outputDirectory: URL, + pom pomXml: Data, + script runMaven: String = runMavenSh + ) -> Result { + let manipulator = XMLPathManipulatorHolder(path: "project.version") { _, element in + element.value = version + return element + } + + return Result { + #if os(iOS) + throw SimulationLoaderError.unsupportedPlatform(name: "iOS") + #else + return try AEXMLDocument(xml: pomXml) + #endif + } + .flatMap { (pom: AEXMLDocument) in + Result { + try pom.manipulateXMLDocument(with: [manipulator]) + } + } + .map { xmlDoc in + DependencyInfo(xml: xmlDoc, output: outputDirectory) + } + .flatMap { dependencyInfo in + guard !dependencyInfo.simulatorExists else { + // Skip (consecutive) downloading of same/existing simulator version + DLog("Skip (consecutive) download of same/existing simulator version.\n* classPath: " + + "[\(String(describing: dependencyInfo.simulatorClassPath?.absoluteString))]") + return Result.success(dependencyInfo) + } + + return Result { + try dependencyInfo.config.createXML() + }.flatMap { xmlData -> Result in + // Save POM + xmlData.save(to: dependencyInfo.pom) + .flatMap { _ -> Result in + Result { + guard let scriptData = runMaven.data(using: .utf8) else { + throw SimulationLoaderError.resourceNotFound("Maven.swift") + } + return scriptData + }.flatMap { (scriptData: Data) in + // Save runMaven.sh + scriptData.save(to: dependencyInfo.script).flatMap { _ in + Result { + try SimulationManager.downloadMavenDependencies(dependencyInfo) + return dependencyInfo + } + } + } + } + } + } + } + + @discardableResult + private static func downloadMavenDependencies(_ dependency: DependencyInfo, launchPath: String = "/bin/bash") + throws -> Int32 { + #if os(macOS) || os(Linux) + let shellProcess = Process() + shellProcess.arguments = [dependency.script.absoluteURL.path, dependency.pom.absoluteURL.path] + shellProcess.launchPath = launchPath + shellProcess.launch() + shellProcess.waitUntilExit() + guard shellProcess.terminationStatus == 0 else { + throw SimulationLoaderError.shellProcessTerminatedUnexpected(status: shellProcess.terminationStatus) + } + return 0 + #else + throw SimulationLoaderError.unsupportedPlatform(name: "iOS|tvOS|watchOS") + #endif + } +} diff --git a/CardSimulationTestKit/Sources/CardSimulationLoader/internal/SimulationRunner+JavaProcessDelegate.swift b/CardSimulationTestKit/Sources/CardSimulationLoader/internal/SimulationRunner+JavaProcessDelegate.swift new file mode 100644 index 0000000..6bacccd --- /dev/null +++ b/CardSimulationTestKit/Sources/CardSimulationLoader/internal/SimulationRunner+JavaProcessDelegate.swift @@ -0,0 +1,78 @@ +// +// Copyright (c) 2023 gematik GmbH +// +// Licensed under the Apache License, Version 2.0 (the License); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an 'AS IS' BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import Foundation +import GemCommonsKit +import ObjCCommonsKit + +extension SimulationRunner: JavaProcessUpdateDelegate { + func processDidLaunch(_: JavaProcess, pid: Int32) { + DLog("Simulator process launched PID: [\(pid)]") + streamThread = KeepAliveRunLoop() + streamThread.start() + streamThread.runloop.perform(inModes: [.default]) { [unowned self] in + if Thread.current === Thread.main { + preconditionFailure("New thread runs on Main thread") + } + + DLog("Card simulator: [STREAM START]") + + var tcpPort: Int32? + var successfullyLaunched = false + // Add NSException handler around stdout reader since it can throw NSFileHandleOperationException + // that are not caught by Swift's try + if let exception = gemTryBlock({ + var line = self.stdoutInfo.reader.nextLine() + repeat { + DLog("Card simulator: [\(String(describing: line))]") + if let line = line, !successfullyLaunched { + // Check for TCP TLV interface port + if tcpPort == nil, let port = line.match(pattern: "TCPIP: TLV Interface at Port (\\d*)$", + group: 1) { + tcpPort = Int32(port) + } + successfullyLaunched = line == "Simulation started successfully." + } + + // !mode.isRunning means mode.isInitializing = true + if !self.mode.isRunning, successfullyLaunched, let tcpPort = tcpPort { + DLog("Simulator started successfully in port [\(tcpPort)]") + self.mode = .running(onTCPPort: tcpPort) + } else if successfullyLaunched { + tcpPort = 12350 // G2-Kartensimulation does not log default TLV port 12350 + } + + line = self.stdoutInfo.reader.nextLine() + } while line != nil + }) { + // Caught NSException + ALog("Raised NSException while reading Process stdout") + DLog("NSException: \(exception)") + } + + DLog("Card simulator: [STREAM END]") + } + } + + func processDidTerminate(_: JavaProcess, with status: Int32) { + mode = .terminated(terminationStatus: status) + DLog("Simulator process ended with: [\(status)] - [CONFIG: \(config)]") + processThread.cancel() + streamThread.cancel() + stdoutInfo.reader.close() + processLoader = nil + } +} diff --git a/CardSimulationTestKit/Sources/CardSimulationLoader/internal/TempFilePathGeneratorType.swift b/CardSimulationTestKit/Sources/CardSimulationLoader/internal/TempFilePathGeneratorType.swift new file mode 100644 index 0000000..f777d54 --- /dev/null +++ b/CardSimulationTestKit/Sources/CardSimulationLoader/internal/TempFilePathGeneratorType.swift @@ -0,0 +1,33 @@ +// +// Copyright (c) 2023 gematik GmbH +// +// Licensed under the Apache License, Version 2.0 (the License); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an 'AS IS' BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import Foundation + +protocol TempFilePathGeneratorType { + func tempFile(for path: URL) -> URL +} + +extension TempFilePathGeneratorType { + func tempFile(for path: URL) -> URL { + generateTempFile(for: path) + } + + private func generateTempFile(for path: URL) -> URL { + NSTemporaryDirectory().asURL + .appendingPathComponent(ProcessInfo.processInfo.globallyUniqueString, isDirectory: true) + .appendingPathComponent(path.lastPathComponent) + } +} diff --git a/CardSimulationTestKit/Sources/CardSimulationLoader/static/Maven.swift b/CardSimulationTestKit/Sources/CardSimulationLoader/static/Maven.swift new file mode 100644 index 0000000..ad02306 --- /dev/null +++ b/CardSimulationTestKit/Sources/CardSimulationLoader/static/Maven.swift @@ -0,0 +1,54 @@ +// +// Copyright (c) 2023 gematik GmbH +// +// Licensed under the Apache License, Version 2.0 (the License); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an 'AS IS' BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +// +// This static shell script is supposed to be run by the SimulationManager when installing +// the G2-Kartensimulation jar files. Unfortunately we cannot add this as a script file in a Bundle resource as the +// SwiftPM won't include it in the target's framework + +internal let runMavenSh = """ +#!/bin/bash + +#set -x + +# Check for mvn availability +export PATH=$PATH:/usr/bin/:/usr/local/bin/:/opt/homebrew/bin/ +hash mvn >/dev/null 2>&1 || { + echo >&2 "For running CardSimulation we need to download Maven dependencies. + But maven was not found. Looked in PATH: ${PATH}). + Please check your shell environment settings or Xcode Run scheme for mvn command. + If maven is not installed, please install maven. For instance with brew: $ brew install maven. + Aborting."; + exit 1; +} + +# Check POM_PATH parameter +if [ -z "$1" ]; then + echo "Please specify a POM path." + exit 1 +fi + +POM_DIR="$(dirname $1)" + +MVN_COMMAND="mvn dependency:copy-dependencies" || { + echo >&2 "Before executing a Maven goal, Maven has to be configured accordingly. + Please check your whether the correct settings.xml and settings-security.xml exist in $HOME/.m2 directory. + Aborting."; + exit 1; +} + +cd "${POM_DIR}" && ${MVN_COMMAND} +""" diff --git a/CardSimulationTestKit/Sources/CardSimulationLoader/xml/AEXMLDocument+XMLManipulation.swift b/CardSimulationTestKit/Sources/CardSimulationLoader/xml/AEXMLDocument+XMLManipulation.swift new file mode 100644 index 0000000..ed2c10b --- /dev/null +++ b/CardSimulationTestKit/Sources/CardSimulationLoader/xml/AEXMLDocument+XMLManipulation.swift @@ -0,0 +1,51 @@ +// +// Copyright (c) 2023 gematik GmbH +// +// Licensed under the Apache License, Version 2.0 (the License); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an 'AS IS' BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import AEXML +import Foundation + +extension AEXMLDocument { + enum ConfigurationError: Error { + case encodingFailed + case manipulationFailed(XMLPath) + } + + /** + Manipulate XML Elements in the Document. + + - Parameter manipulators: List of XMLPathManipulators + + - Returns: self as the Result XML upon success + */ + internal func manipulateXMLDocument(with manipulators: [XMLPathManipulator] = []) throws -> AEXMLDocument { + try manipulators.forEach { manipulator in + let path = manipulator.path + if let element = self.resolve(path: path) { + if !self.replace(path: path, with: manipulator.manipulate(path: path, with: element)) { + throw ConfigurationError.manipulationFailed(path) + } + } + } + return self + } + + internal func createXML(using encoding: String.Encoding = .utf8) throws -> Data { + guard let configOutputXml = xml.data(using: encoding, allowLossyConversion: false) else { + throw ConfigurationError.encodingFailed + } + return configOutputXml + } +} diff --git a/CardSimulationTestKit/Sources/CardSimulationLoader/xml/URL+ConfigurationFileProcessor.swift b/CardSimulationTestKit/Sources/CardSimulationLoader/xml/URL+ConfigurationFileProcessor.swift new file mode 100644 index 0000000..8319d56 --- /dev/null +++ b/CardSimulationTestKit/Sources/CardSimulationLoader/xml/URL+ConfigurationFileProcessor.swift @@ -0,0 +1,52 @@ +// +// Copyright (c) 2023 gematik GmbH +// +// Licensed under the Apache License, Version 2.0 (the License); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an 'AS IS' BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import AEXML +import Foundation +import GemCommonsKit + +/** + This extension is supposed to copy the configuration file to a tmp path + while giving the delegate the option to manipulate the config values ad hoc. + */ +extension URL: ConfigurationFileProcessor { + /** + Prepare the configuration for the simulation runtime by mutating its original contents by the `manipulators`. + + - Note: The contents of the file at the URL path needs to be XML formatted. + + - Parameters: + - manipulators: The XMLManipulators for the specified XML paths + + - Returns: the with manipulators manipulated Result + */ + public func prepareXMLConfigFile(with manipulators: [XMLPathManipulator] = []) + -> Result { + Result { + try self.readFileContents() + } + .flatMap { configXmlData in + Result { + try AEXMLDocument(xml: configXmlData) + } + } + .flatMap { (configXml: AEXMLDocument) in + Result { + try configXml.manipulateXMLDocument(with: manipulators) + } + } + } +} diff --git a/CardSimulationTestKit/Sources/CardSimulationLoader/xml/XMLPath.swift b/CardSimulationTestKit/Sources/CardSimulationLoader/xml/XMLPath.swift new file mode 100644 index 0000000..a9224a2 --- /dev/null +++ b/CardSimulationTestKit/Sources/CardSimulationLoader/xml/XMLPath.swift @@ -0,0 +1,154 @@ +// +// Copyright (c) 2023 gematik GmbH +// +// Licensed under the Apache License, Version 2.0 (the License); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an 'AS IS' BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import AEXML +import AEXMLExt +import Foundation + +/** + XML paths specified as . separated Strings. + */ +public struct XMLPath { + /// XPath formatted path + public let path: String + + var components: [String] { + path.components(separatedBy: ".") + } +} + +extension XMLPath: ExpressibleByStringLiteral { + public typealias ExtendedGraphemeClusterLiteralType = StringLiteralType + public typealias UnicodeScalarLiteralType = StringLiteralType + + public init(stringLiteral value: StringLiteralType) { + path = value + } + + public init(extendedGraphemeClusterLiteral value: ExtendedGraphemeClusterLiteralType) { + path = value + } + + public init(unicodeScalarLiteral value: UnicodeScalarLiteralType) { + path = value + } +} + +extension XMLPath: Hashable { + // swiftlint:disable:next operator_whitespace + public static func ==(lhs: XMLPath, rhs: XMLPath) -> Bool { + lhs.path == rhs.path + } +} + +extension AEXMLDocument { + /** + Resolve a XMLPath from this XML document's root + + Example: + ``` + + + + Value + Value2 + Value2 + + + ``` + + To get out of this document use: + + ``` + "configuration.node.element" as XMLPath + ``` + + Or to get element with Value2: + ``` + "configuration.node.element[1]" as XMLPath + ``` + + And to get element id="123": + ``` + "configuration.node.element{id:123}" as XMLPath + ``` + + - Parameter path: The path to resolve + + - Returns: The XML element when found + */ + func resolve(path: XMLPath) -> AEXMLElement? { + let foundElement: AEXMLElement? = path.components + .reduce((0, nil)) { [unowned self] elementTuple, subPath -> (Int, AEXMLElement?) in + let firstElem = elementTuple.0 + 1 + guard let element = elementTuple.1 else { + // Verify root.name is equal to subPath[0] + if firstElem == 1, self.root.name == subPath { + return (firstElem, self.root) + } + return (firstElem, nil) + } + if let index = subPath.match(pattern: "^.*\\[(\\d*)\\]$"), let idx = Int(index) { + /// check for child element at index + return (firstElem, element.children[idx]) + } + /// Check for attribute matching + if let attribute = subPath.match(pattern: "^.*\\{([\\w]*:{1}[\\w]*)\\}$"), + let upTo = subPath.firstIndex(of: "{") { + let elementName = String(subPath.prefix(upTo: upTo)) + let mElement = element[elementName] + let attributeComponents = attribute.components(separatedBy: ":") + let attributeName = attributeComponents[0] + let attributeValue = attributeComponents[1] + let found = mElement.all(withAttributes: [attributeName: attributeValue]) + guard found?.count ?? 0 > 0 else { + return (firstElem, nil) + } + return (firstElem, found?[0]) + } + return (firstElem, element[subPath]) + }.1 + + /// AEXMLDocument["key"] always returns an AEXMLElement, the only way to figure out whether + /// the path did not exists is checking for the error property + if let err = foundElement?.error, err == .elementNotFound { + return nil + } + return foundElement + } + + /** + Replace the element at path + + - Parameters: + - path: the XML path to replace + - element: the XML Element to change + + - Returns: true when path was found and replaced + */ + func replace(path: XMLPath, with element: AEXMLElement) -> Bool { + guard let elementBefore = resolve(path: path), let parentElement = elementBefore.parent, + !parentElement.isRoot else { + return false + } + guard let index = parentElement.children.firstIndex(where: { elem in elem === elementBefore }) else { + /// Child at index not found (impossible) + return false + } + _ = parentElement.replaceChild(at: index, with: element) + return true + } +} diff --git a/CardSimulationTestKit/Sources/CardSimulationLoader/xml/XMLPathManipulator.swift b/CardSimulationTestKit/Sources/CardSimulationLoader/xml/XMLPathManipulator.swift new file mode 100644 index 0000000..10bfd29 --- /dev/null +++ b/CardSimulationTestKit/Sources/CardSimulationLoader/xml/XMLPathManipulator.swift @@ -0,0 +1,111 @@ +// +// Copyright (c) 2023 gematik GmbH +// +// Licensed under the Apache License, Version 2.0 (the License); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an 'AS IS' BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import AEXML +import Foundation + +/// XML Element manipulator to supply a new value for the given path +public protocol XMLPathManipulator { + /// The path for this manipulator + var path: XMLPath { get } + + /** + Manipulate the given element. + + - Parameters: + - path: the current path for the passed in element + - element: the current element to modify + + - Returns: the modified XML element + */ + func manipulate(path: XMLPath, with element: AEXMLElement) -> AEXMLElement +} + +/// The actual function signature that get's invoked to manipulate a specific XML element at the specified path +/// - Parameters: +/// - path: the current path for the passed in element +/// - element: the current element to modify +/// - Returns: the modified XML element +public typealias XMLPathManipulatorFunction = (_ path: XMLPath, _ element: AEXMLElement) -> AEXMLElement + +/// XML Manipulator holder +public struct XMLPathManipulatorHolder { + /// The XML path for this manipulator to respond to + public let path: XMLPath + /// The manipulator function held by this holder + public let manipulator: XMLPathManipulatorFunction + + /// Initialize a Manipulator holder with path and manipulator + /// - Parameters: + /// - path: the current path for the passed in element + /// - element: the current element to modify + public init(path: XMLPath, manipulator: @escaping XMLPathManipulatorFunction) { + self.path = path + self.manipulator = manipulator + } +} + +extension XMLPathManipulatorHolder: XMLPathManipulator { + /// Execute the manipulator on a given element + /// - Parameters: + /// - path: the current path for the passed in element + /// - element: the current element to modify + /// - Returns: the modified XML element + public func manipulate(path: XMLPath, with element: AEXMLElement) -> AEXMLElement { + manipulator(path, element) + } +} + +extension XMLPathManipulatorHolder { + /// TLV Port XML Path + public static let TLVPortXMLPath = "configuration.ioConfiguration.port" as XMLPath + /// Card image file XML Path + public static let CardConfigFileXMLPath = "configuration.general.attribute{id:cardImageFile}" as XMLPath + /// Channel file XML Path + public static let ChannelConfigFileXMLPath = "configuration.general.attribute{id:channelContextFile}" as XMLPath + + /// Default TLV Manipulator + /// - Parameter port: the port to inject into `TLVPortXMLPath` element + /// - Returns: XML manipulator to set the port in the XML config file + public static func tlvPortManipulator(port: String) -> XMLPathManipulator { + XMLPathManipulatorHolder(path: TLVPortXMLPath) { _, element in + element.value = port + return element + } + } + + /** + Create an XML Path manipulator that translates relative paths to absolute paths with the given absolutePath + + - Parameters: + - path: the path for manipulator + - absolutePath: the absolute path the prepend to the relative path + + - Returns: XML manipulator that modifies relative path for the give path + */ + public static func relativeToAbsolutePathManipulator(with path: XMLPath, absolutePath: URL = FileManager.default + .currentDirectoryPath.asURL) -> XMLPathManipulator { + XMLPathManipulatorHolder(path: path) { _, element in + if var elementValue = element.value { + if elementValue.hasPrefix("../") || elementValue.hasPrefix("./") { + elementValue = absolutePath.appendingPathComponent(elementValue).absoluteURL.path + } + element.value = elementValue + } + return element + } + } +} diff --git a/CardSimulationTestKit/Sources/CardSimulationRunner/main.swift b/CardSimulationTestKit/Sources/CardSimulationRunner/main.swift new file mode 100644 index 0000000..0eb2158 --- /dev/null +++ b/CardSimulationTestKit/Sources/CardSimulationRunner/main.swift @@ -0,0 +1,63 @@ +// +// Copyright (c) 2023 gematik GmbH +// +// Licensed under the Apache License, Version 2.0 (the License); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an 'AS IS' BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import CardSimulationLoader +import Foundation +import GemCommonsKit + +func main() throws { + DLog("Cmdline working directory: [\(FileManager.default.currentDirectoryPath)]") + DLog("Cmdline argc: \(CommandLine.argc)") + DLog("Cmdline: \(CommandLine.arguments)") + guard CommandLine.arguments.count > 1 else { + ALog("No argument passed for configuration file") + exit(1) + } + + let simulatorManager = SimulationManager.shared + let configFile = CommandLine.arguments[1].asURL + let configPath = configFile.absoluteURL.deletingLastPathComponent() + let runner = try simulatorManager.createSimulation( + configFile: configFile, + preprocessor: [ + XMLPathManipulatorHolder.tlvPortManipulator(port: "0"), + XMLPathManipulatorHolder.relativeToAbsolutePathManipulator(with: XMLPathManipulatorHolder + .CardConfigFileXMLPath, absolutePath: configPath), + XMLPathManipulatorHolder.relativeToAbsolutePathManipulator(with: XMLPathManipulatorHolder + .ChannelConfigFileXMLPath, absolutePath: configPath), + ] + ) + runner.start(waitUntilLaunched: true) + + // Terminate all simulators + DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + DispatchTimeInterval.seconds(2)) { + SimulationManager.shared.stopAll() + SimulationManager.shared.clean() + } + + while !runner.mode.isTerminated { + RunLoop.current.run(mode: .default, before: Date.distantFuture) + } + + DLog("Sleep one seconds") + Thread.sleep(forTimeInterval: 1) +} + +do { + try main() +} catch { + ALog("Exception: \(error)") +} diff --git a/CardSimulationTestKit/Tests/AEXMLExtTests/AEXMLElementExtRootTest.swift b/CardSimulationTestKit/Tests/AEXMLExtTests/AEXMLElementExtRootTest.swift new file mode 100644 index 0000000..de713e2 --- /dev/null +++ b/CardSimulationTestKit/Tests/AEXMLExtTests/AEXMLElementExtRootTest.swift @@ -0,0 +1,44 @@ +// +// Copyright (c) 2023 gematik GmbH +// +// Licensed under the Apache License, Version 2.0 (the License); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an 'AS IS' BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import AEXML +@testable import AEXMLExt +import Nimble +import XCTest + +final class AEXMLElementExtRootTest: XCTestCase { + func testReplaceChild() { + let animals = AEXMLElement(name: "animals") + let dogs = AEXMLElement(name: "dogs") + dogs.addChild(AEXMLElement(name: "dog", value: "Blackie", attributes: ["breed": "Puppy", "color": "purple"])) + dogs.addChild(AEXMLElement(name: "dog", value: "Brain", attributes: ["breed": "Puppy", "color": "purple"])) + dogs.addChild(AEXMLElement(name: "dog", value: "Betty", attributes: ["breed": "Puppy", "color": "purple"])) + animals.addChild(dogs) + let xmlDocument = AEXMLDocument(root: animals) + let newDog = AEXMLElement(name: "dog", value: "Jacky", attributes: ["breed": "Puppy", "color": "purple"]) + + let dogsElement = xmlDocument.root["dogs"] + let oldDog = dogsElement.replaceChild(at: 2, with: newDog) + + expect(oldDog.value) == "Betty" + expect(dogsElement.children[2]) === newDog + expect(newDog.parent) === dogsElement + } + + static var allTests = [ + ("testReplaceChild", testReplaceChild), + ] +} diff --git a/CardSimulationTestKit/Tests/CardSimulationCardReaderProviderTests/Card/SimulatorCardChannelTest.swift b/CardSimulationTestKit/Tests/CardSimulationCardReaderProviderTests/Card/SimulatorCardChannelTest.swift new file mode 100644 index 0000000..ff6928c --- /dev/null +++ b/CardSimulationTestKit/Tests/CardSimulationCardReaderProviderTests/Card/SimulatorCardChannelTest.swift @@ -0,0 +1,218 @@ +// +// Copyright (c) 2023 gematik GmbH +// +// Licensed under the Apache License, Version 2.0 (the License); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an 'AS IS' BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import CardReaderProviderApi +@testable import CardSimulationCardReaderProvider +import Foundation +import GemCommonsKit +import Nimble +import XCTest + +final class SimulatorCardChannelTest: XCTestCase { + class MockSimulatorCard: CardType { + var atr: ATR = Data.empty + var `protocol`: CardProtocol = .t1 + + func openBasicChannel() throws -> CardChannelType { + throw CardError.illegalState("openBasicChannel() has not been implemented") + } + + func openLogicChannel() throws -> CardChannelType { + throw CardError.illegalState("openLogicChannel() has not been implemented") + } + + func openLogicChannelAsync() async throws -> CardChannelType { + throw CardError.illegalState("openLogicChannel() has not been implemented") + } + + func disconnect(reset _: Bool) throws {} + } + + class MockStreaming: TCPClientType { + var closedInputStream = false + var closedOutputStream = false + + var bytesWritten = Data() + /// When bytes have written, unlock responses + var availableBytes: Data? + + var hasBytesAvailable: Bool { + let writtenCount = bytesWritten.count + guard !closedInputStream, + writtenCount > 0, + (availableBytes?.count ?? 0) > 0 else { + return false + } + return true + } + + func read(_ buffer: UnsafeMutablePointer, maxLength len: Int) -> Int { + guard hasBytesAvailable, let bytes = availableBytes else { + return 0 + } + let count = Swift.min(bytes.count, len) + + bytes.withUnsafeBytes { + buffer.assign(from: $0, count: count) + } + availableBytes?.removeFirst(count) + return count + } + + var hasSpaceAvailable: Bool { + !closedOutputStream + } + + func write(_ buffer: UnsafePointer, maxLength len: Int) -> Int { + let data = Data(bytes: buffer, count: len) + bytesWritten.append(data) + return data.count + } + + func close() throws { + closedInputStream = true + closedOutputStream = true + } + } + + struct MockCommand: CommandType { + private(set) var data: Data? + // swiftlint:disable identifier_name + private(set) var ne: Int? + private(set) var nc: Int = 0 + private(set) var cla: UInt8 = 0 + private(set) var ins: UInt8 = 0 + private(set) var p1: UInt8 = 0 + private(set) var p2: UInt8 = 0 + // swiftlint:enable identifier_name + private(set) var bytes: Data + + init(bytes: Data) { + self.bytes = bytes + } + } + + func testTransmit() { + let stream = MockStreaming() + guard let responseData = try? Data([0x90, 0x00]).berTlvEncoded() else { + Nimble.fail("Failed to berTlv Encode responseData") + return + } + stream.availableBytes = responseData + let cardChannel = SimulatorCardChannel( + card: MockSimulatorCard(), + client: stream, + messageLength: 4096, + responseLength: 4096 + ) + let commandData = Data([0x1, 0x2, 0x3, 0x4]) + let command: CommandType = MockCommand(bytes: commandData) + do { + let response = try cardChannel.transmit(command: command, writeTimeout: 0, readTimeout: 0) + // Verify response has been decoded + expect(response.sw).to(equal(APDU.Response.OK.sw)) + // Verify command has been ber TLV encoded and written to output stream + let berTlvData = try commandData.berTlvEncoded() + expect(berTlvData).to(equal(stream.bytesWritten)) + // Close channel + try cardChannel.close() + expect(stream.closedInputStream).to(beTrue()) + expect(stream.closedOutputStream).to(beTrue()) + } catch { + Nimble.fail("Transmit failed: [\(error)]") + } + } + + func testCommandTooLarge() { + let stream = MockStreaming() + let cardChannel = SimulatorCardChannel( + card: MockSimulatorCard(), + client: stream, + messageLength: 10, + responseLength: 10 + ) + let commandData = Data([UInt8](repeating: 0x8, count: 11)) + let command: CommandType = MockCommand(bytes: commandData) + expect { + try cardChannel.transmit(command: command, writeTimeout: 0, readTimeout: 0) + }.to(throwError(SimulatorCardChannel.SimulatorError.commandSizeTooLarge(maxSize: 10, length: 11).illegalState)) + } + + func testResponseTooLarge() { + let stream = MockStreaming() + guard let responseData = try? Data([UInt8](repeating: 0x8, count: 11)).berTlvEncoded() else { + Nimble.fail("Failed to berTlv Encode responseData") + return + } + stream.availableBytes = responseData + + let cardChannel = SimulatorCardChannel( + card: MockSimulatorCard(), + client: stream, + messageLength: 10, + responseLength: 10 + ) + let commandData = Data([0x0, 0x2]) + let command: CommandType = MockCommand(bytes: commandData) + expect { + try cardChannel.transmit(command: command, writeTimeout: 0, readTimeout: 0) + }.to(throwError( + SimulatorCardChannel.SimulatorError.responseSizeTooLarge(maxSize: 10, length: responseData.count) + .illegalState + )) + } + + func testNoResponse() { + let stream = MockStreaming() + let cardChannel = SimulatorCardChannel( + card: MockSimulatorCard(), + client: stream, + messageLength: 10, + responseLength: 10 + ) + + let commandData = Data([0x0, 0x2]) + let command: CommandType = MockCommand(bytes: commandData) + expect { + try cardChannel.transmit(command: command, writeTimeout: 0, readTimeout: 0.5) + }.to(throwError(SimulatorCardChannel.SimulatorError.noResponse.connectionError)) + } + + func testEmptyResponse() { + let stream = MockStreaming() + let cardChannel = SimulatorCardChannel( + card: MockSimulatorCard(), + client: stream, + messageLength: 10, + responseLength: 10 + ) + stream.availableBytes = Data() + + let commandData = Data([0x0, 0x2]) + let command: CommandType = MockCommand(bytes: commandData) + expect { + try cardChannel.transmit(command: command, writeTimeout: 0, readTimeout: 0.5) + }.to(throwError(SimulatorCardChannel.SimulatorError.noResponse.connectionError)) + } + + static let allTests = [ + ("testTransmit", testTransmit), + ("testCommandTooLarge", testCommandTooLarge), + ("testResponseTooLarge", testResponseTooLarge), + ("testNoResponse", testNoResponse), + ("testEmptyResponse", testEmptyResponse), + ] +} diff --git a/CardSimulationTestKit/Tests/CardSimulationCardReaderProviderTests/Card/SimulatorCardTest.swift b/CardSimulationTestKit/Tests/CardSimulationCardReaderProviderTests/Card/SimulatorCardTest.swift new file mode 100644 index 0000000..74b44ad --- /dev/null +++ b/CardSimulationTestKit/Tests/CardSimulationCardReaderProviderTests/Card/SimulatorCardTest.swift @@ -0,0 +1,65 @@ +// +// Copyright (c) 2023 gematik GmbH +// +// Licensed under the Apache License, Version 2.0 (the License); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an 'AS IS' BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +@testable import CardSimulationCardReaderProvider +import Nimble +import SwiftSocket +import XCTest + +final class SimulatorCardTest: XCTestCase { + var serverSocket: TCPServer! + var listenPort: Int32 { + serverSocket.port + } + + override func setUp() { + super.setUp() + + serverSocket = TCPServer(address: "127.0.0.1", port: 0) + if case let .failure(error) = serverSocket.listen() { + Nimble.fail("Failed to setup TCP socket: [\(error)]") + } + } + + override func tearDown() { + serverSocket.close() + super.tearDown() + } + + func testSimulatorCard_open_basic_channel() { + let card = SimulatorCard(host: "localhost", port: listenPort, channel: .t1, timeout: 1) + do { + _ = try card.openBasicChannel() + } catch { + Nimble.fail("Could not open basic channel: \(error)") + } + } + + func testSimulatorCard_open_logic_channel() { + let card = SimulatorCard(host: "localhost", port: listenPort, channel: .t1, timeout: 1) + do { + _ = try card.openLogicChannel() + } catch { + // Ignore for now, since we know it's not implemented + // XCTFail("Could not open logic channel: \(error)") + } + } + + static var allTests = [ + ("testSimulatorCard_open_basic_channel", testSimulatorCard_open_basic_channel), + ("testSimulatorCard_open_logic_channel", testSimulatorCard_open_logic_channel), + ] +} diff --git a/CardSimulationTestKit/Tests/CardSimulationCardReaderProviderTests/MockSimulationManager.swift b/CardSimulationTestKit/Tests/CardSimulationCardReaderProviderTests/MockSimulationManager.swift new file mode 100644 index 0000000..d3c5012 --- /dev/null +++ b/CardSimulationTestKit/Tests/CardSimulationCardReaderProviderTests/MockSimulationManager.swift @@ -0,0 +1,52 @@ +// +// Copyright (c) 2023 gematik GmbH +// +// Licensed under the Apache License, Version 2.0 (the License); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an 'AS IS' BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import CardSimulationLoader +import Foundation +import GemCommonsKit + +class MockSimulationManager: SimulationManagerType { + var delegates = WeakArray() + + func register(delegate: SimulationManagerDelegate) { + delegates.add(object: delegate) + } + + func deregister(delegate: SimulationManagerDelegate) { + guard let index = delegates.index(of: delegate) else { + return + } + delegates.removeObject(at: index) + deregister(delegate: delegate) + } + + func createSimulation( + configFile _: URL, + preprocessor _: [XMLPathManipulator], + simulatorVersion _: String, + simulatorDirectory _: String + ) throws -> SimulationRunnerType { + throw "NotImplemented" + } + + func stop(simulation _: SimulationRunnerType, waitUntilDone _: Bool) { + // Do nothing + } + + func stopAll(waitUntilDone _: Bool) { + // Do nothing + } +} diff --git a/CardSimulationTestKit/Tests/CardSimulationCardReaderProviderTests/MockSimulationRunner.swift b/CardSimulationTestKit/Tests/CardSimulationCardReaderProviderTests/MockSimulationRunner.swift new file mode 100644 index 0000000..40691c0 --- /dev/null +++ b/CardSimulationTestKit/Tests/CardSimulationCardReaderProviderTests/MockSimulationRunner.swift @@ -0,0 +1,25 @@ +// +// Copyright (c) 2023 gematik GmbH +// +// Licensed under the Apache License, Version 2.0 (the License); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an 'AS IS' BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import CardSimulationLoader + +class MockSimulationRunner: SimulationRunnerType { + var mode: SimulationProcessMode = .notStarted + + func start(waitUntilLaunched _: Bool) {} + + func stop(waitUntilTerminated _: Bool) {} +} diff --git a/CardSimulationTestKit/Tests/CardSimulationCardReaderProviderTests/Provider/SimulatorCardReaderProviderTest.swift b/CardSimulationTestKit/Tests/CardSimulationCardReaderProviderTests/Provider/SimulatorCardReaderProviderTest.swift new file mode 100644 index 0000000..1596c4f --- /dev/null +++ b/CardSimulationTestKit/Tests/CardSimulationCardReaderProviderTests/Provider/SimulatorCardReaderProviderTest.swift @@ -0,0 +1,43 @@ +// +// Copyright (c) 2023 gematik GmbH +// +// Licensed under the Apache License, Version 2.0 (the License); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an 'AS IS' BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import CardReaderAccess +import CardReaderProviderApi +@testable import CardSimulationCardReaderProvider +import Nimble +import XCTest + +final class SimulatorCardReaderProviderTest: XCTestCase { + func testProvider() { + let wrappedController = SimulatorCardReaderProvider.provideCardReaderController() + expect(type(of: wrappedController.value)).to(beIdenticalTo(SimulatorCardReaderController.self)) + } + + func testProviderRegistration() { + let manager = CardReaderControllerManager.shared + let controllers: [CardReaderControllerType] = manager.cardReaderControllers + expect { + controllers.first { + type(of: $0) == SimulatorCardReaderController.self + } + }.toNot(beNil()) + } + + static var allTests = [ + ("testProvider", testProvider), + ("testProviderRegistration", testProviderRegistration), + ] +} diff --git a/CardSimulationTestKit/Tests/CardSimulationCardReaderProviderTests/Reader/SimulatorCardReaderControllerTest.swift b/CardSimulationTestKit/Tests/CardSimulationCardReaderProviderTests/Reader/SimulatorCardReaderControllerTest.swift new file mode 100644 index 0000000..1835610 --- /dev/null +++ b/CardSimulationTestKit/Tests/CardSimulationCardReaderProviderTests/Reader/SimulatorCardReaderControllerTest.swift @@ -0,0 +1,110 @@ +// +// Copyright (c) 2023 gematik GmbH +// +// Licensed under the Apache License, Version 2.0 (the License); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an 'AS IS' BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import CardReaderProviderApi +@testable import CardSimulationCardReaderProvider +import Nimble +import XCTest + +final class SimulatorCardReaderControllerTest: XCTestCase { + typealias ControllerDelegateParams = (controller: CardReaderControllerType, cardReader: CardReaderType) + + class TestCardReaderControllerDelegate: CardReaderControllerDelegate { + var connectCalls = [ControllerDelegateParams]() + var disconnectCalls = [ControllerDelegateParams]() + + func cardReader(controller: CardReaderControllerType, didConnect cardReader: CardReaderType) { + connectCalls.append((controller: controller, cardReader: cardReader)) + } + + func cardReader(controller: CardReaderControllerType, didDisconnect cardReader: CardReaderType) { + disconnectCalls.append((controller: controller, cardReader: cardReader)) + } + } + + func testCardReaderController_registers_as_delegate() { + let mockManager = MockSimulationManager() + var controller = SimulatorCardReaderController(manager: mockManager) + + /// make sure SimulatorCardTerminalController registers + expect(mockManager.delegates.array).to(containElementSatisfying({ $0 === controller }, "")) + + controller = SimulatorCardReaderController(manager: MockSimulationManager()) + /// make sure SimulatorCardTerminalController de-registers + expect(mockManager.delegates.count).to(equal(0)) + } + + func testCardReaderController_weak_delegate() { + let mockManager = MockSimulationManager() + let mockRunner = MockSimulationRunner() + let controller = SimulatorCardReaderController(manager: mockManager) + + expect(mockManager.delegates.array).to(containElementSatisfying({ $0 === controller }, "")) + + var delegate = TestCardReaderControllerDelegate() + weak var weakDelegate = delegate + + controller.add(delegate: delegate) + controller.simulation(manager: mockManager, didStart: mockRunner) + // Make sure delegate was registered + expect(delegate.connectCalls.count).to(equal(1)) + + delegate = TestCardReaderControllerDelegate() + expect(weakDelegate).to(beNil()) + } + + func testCardReaderController_registered_delegate_callbacks() { + let mockManager = MockSimulationManager() + let mockRunner = MockSimulationRunner() + let controller = SimulatorCardReaderController(manager: mockManager) + + expect(mockManager.delegates.array).to(containElementSatisfying({ $0 === controller }, "")) + + let delegate = TestCardReaderControllerDelegate() + controller.add(delegate: delegate) + expect(delegate.connectCalls.count).to(equal(0)) + expect(delegate.disconnectCalls.count).to(equal(0)) + expect(controller.cardReaders).to(beEmpty()) + controller.simulation(manager: mockManager, didStart: mockRunner) + expect(controller.cardReaders).to(haveCount(1)) + // Make sure delegate was registered + expect(delegate.connectCalls.count).to(equal(1)) + expect(delegate.disconnectCalls.count).to(equal(0)) + + controller.simulation(manager: mockManager, didEnd: mockRunner) + expect(controller.cardReaders).to(beEmpty()) + expect(delegate.connectCalls.count).to(equal(1)) + expect(delegate.disconnectCalls.count).to(equal(1)) + + controller.remove(delegate: delegate) + controller.simulation(manager: mockManager, didStart: mockRunner) + expect(delegate.connectCalls.count).to(equal(1)) + expect(delegate.disconnectCalls.count).to(equal(1)) + + /// Late delegate should still get the current available runner + let lateDelegate = TestCardReaderControllerDelegate() + controller.add(delegate: lateDelegate) + expect(lateDelegate.connectCalls.count).to(equal(1)) + expect(lateDelegate.disconnectCalls.count).to(equal(0)) + } + + static var allTests = [ + ("testCardReaderController_registers_as_delegate", testCardReaderController_registers_as_delegate), + ("testCardReaderController_weak_delegate", testCardReaderController_weak_delegate), + ("testCardReaderController_registered_delegate_callbacks", + testCardReaderController_registered_delegate_callbacks), + ] +} diff --git a/CardSimulationTestKit/Tests/CardSimulationCardReaderProviderTests/Reader/SimulatorCardReaderTest.swift b/CardSimulationTestKit/Tests/CardSimulationCardReaderProviderTests/Reader/SimulatorCardReaderTest.swift new file mode 100644 index 0000000..b2a8506 --- /dev/null +++ b/CardSimulationTestKit/Tests/CardSimulationCardReaderProviderTests/Reader/SimulatorCardReaderTest.swift @@ -0,0 +1,95 @@ +// +// Copyright (c) 2023 gematik GmbH +// +// Licensed under the Apache License, Version 2.0 (the License); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an 'AS IS' BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +@testable import CardSimulationCardReaderProvider +import Nimble +import XCTest + +final class SimulatorCardReaderTest: XCTestCase { + func testCardCardReader_properties() { + let mockRunner = MockSimulationRunner() + let cardReader = SimulatorCardReader(cardReader: mockRunner, host: "my-host") + + expect(cardReader.name).to(equal("cardsim-my-host-?")) + expect(cardReader.cardPresent).to(beFalse()) + + mockRunner.mode = .initializing + expect(cardReader.name).to(equal("cardsim-my-host-?")) + expect(cardReader.cardPresent).to(beFalse()) + + mockRunner.mode = .running(onTCPPort: 3000) + expect(cardReader.name).to(equal("cardsim-my-host-3000")) + expect(cardReader.cardPresent).to(beTrue()) + + mockRunner.mode = .terminated(terminationStatus: -1) + expect(cardReader.name).to(equal("cardsim-my-host-x")) + expect(cardReader.cardPresent).to(beFalse()) + } + + func testCardCardReader_on_card_present() { + var blockInvoked = 0 + let block: SimulatorCardReader.CardPresentBlock = { _ in + blockInvoked += 1 + } + var earlyBlockInvoked = 0 + let earlyBlock: SimulatorCardReader.CardPresentBlock = { _ in + earlyBlockInvoked += 1 + } + let mockRunner = MockSimulationRunner() + mockRunner.mode = .running(onTCPPort: 900) + let cardReader = SimulatorCardReader(cardReader: mockRunner) + cardReader.onCardPresenceChanged(earlyBlock) + expect(earlyBlockInvoked).to(equal(1)) + mockRunner.mode = .initializing + + cardReader.onCardPresenceChanged(block) + cardReader.checkRunnerModeDidChange() + expect(blockInvoked).to(equal(0)) + + mockRunner.mode = .running(onTCPPort: 1000) + expect(blockInvoked).to(equal(0)) + cardReader.checkRunnerModeDidChange() + expect(blockInvoked).to(equal(1)) + // make sure we have only one callback, so earlyBlock should not have been invoked + expect(earlyBlockInvoked).to(equal(1)) + mockRunner.mode = .initializing + cardReader.checkRunnerModeDidChange() + expect(blockInvoked).to(equal(1)) + mockRunner.mode = .running(onTCPPort: 1001) + cardReader.checkRunnerModeDidChange() + expect(blockInvoked).to(equal(2)) + } + + func testCardCardReader_connect() { + let mockRunner = MockSimulationRunner() + let cardReader = SimulatorCardReader(cardReader: mockRunner, host: "testhost") + + expect(try? cardReader.connect([:])).to(beNil()) + mockRunner.mode = .running(onTCPPort: 1000) + guard let card = try? cardReader.connect([:]), let simCard = card as? SimulatorCard else { + Nimble.fail("Could not connect to cardReader or is not type(of: SimulatorCard)") + return + } + expect(simCard.port).to(equal(1000)) + expect(simCard.host).to(equal("testhost")) + } + + static var allTests = [ + ("testCardCardReader_properties", testCardCardReader_properties), + ("testCardCardReader_on_card_present", testCardCardReader_on_card_present), + ("testCardCardReader_connect", testCardCardReader_connect), + ] +} diff --git a/CardSimulationTestKit/Tests/CardSimulationCardReaderProviderTests/XCTestManifests.swift b/CardSimulationTestKit/Tests/CardSimulationCardReaderProviderTests/XCTestManifests.swift new file mode 100644 index 0000000..f20f96e --- /dev/null +++ b/CardSimulationTestKit/Tests/CardSimulationCardReaderProviderTests/XCTestManifests.swift @@ -0,0 +1,32 @@ +// +// Copyright (c) 2023 gematik GmbH +// +// Licensed under the Apache License, Version 2.0 (the License); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an 'AS IS' BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import XCTest + +#if !os(macOS) && !os(iOS) +/// Runs all test cases for CardSimulationCardReaderProvider +public func allTests() -> [XCTestCaseEntry] { + [ + testCase(SimulatorCardChannelTest.allTests), + testCase(SimulatorCardTest.allTests), + testCase(SimulatorCardReaderProviderTest.allTests), + testCase(SimulatorCardReaderControllerTest.allTests), + testCase(TCPClientExtStreamingTest.allTests), + testCase(SimulatorCardTerminalTest.allTests), + testCase(DataExtBerTLVTest.allTests), + ] +} +#endif diff --git a/CardSimulationTestKit/Tests/CardSimulationCardReaderProviderTests/internal/DataExtBerTLVTest.swift b/CardSimulationTestKit/Tests/CardSimulationCardReaderProviderTests/internal/DataExtBerTLVTest.swift new file mode 100644 index 0000000..e2b6b7c --- /dev/null +++ b/CardSimulationTestKit/Tests/CardSimulationCardReaderProviderTests/internal/DataExtBerTLVTest.swift @@ -0,0 +1,244 @@ +// +// Copyright (c) 2023 gematik GmbH +// +// Licensed under the Apache License, Version 2.0 (the License); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an 'AS IS' BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import Foundation +import GemCommonsKit +import Nimble + +@testable import CardSimulationCardReaderProvider +import XCTest + +final class DataExtBerTLVTest: XCTestCase { + func testBerTLV_encode() { + let apdu = Data([0x00, 0xA4, 0x02, 0x0C, 0x02, 0x2F, 0x01]) + let expected = Data([0x80, 0x07, 0x00, 0xA4, 0x02, 0x0C, 0x02, 0x2F, 0x01]) + + expect { + try apdu.berTlvEncoded() + }.to(equal(expected)) + } + + func testBerTLV_encode_7f() { + let size = 0x7F + let header = Data([0x80, UInt8(size)]) + let apdu = Data([UInt8](repeating: 0x11, count: size)) + let expected = header + apdu + + expect { + try apdu.berTlvEncoded() + }.to(equal(expected)) + } + + func testBerTLV_encode_80() { + let size = 0x80 + let header = Data([0x80, 0x81, UInt8(size)]) + let apdu = Data([UInt8](repeating: 0x11, count: size)) + let expected = header + apdu + + expect { + try apdu.berTlvEncoded() + }.to(equal(expected)) + } + + func testBerTLV_encode_ff() { + let size = 0xFF + let header = Data([0x80, 0x81, UInt8(size)]) + let apdu = Data([UInt8](repeating: 0x11, count: size)) + let expected = header + apdu + + expect { + try apdu.berTlvEncoded() + }.to(equal(expected)) + } + + func testBerTLV_encode_100() { + let size = 0x100 + let header = Data([0x80, 0x82, 0x1, 0x0]) + let apdu = Data([UInt8](repeating: 0x11, count: size)) + let expected = header + apdu + + expect { + try apdu.berTlvEncoded() + }.to(equal(expected)) + } + + func testBerTLV_encode_ffff() { + let size = 0xFFFF + let header = Data([0x80, 0x82, 0xFF, 0xFF]) + let apdu = Data([UInt8](repeating: 0x11, count: size)) + let expected = header + apdu + + expect { + try apdu.berTlvEncoded() + }.to(equal(expected)) + } + + func testBerTLV_encode_10000() { + let size = 0x10000 + let header = Data([0x80, 0x83, 0x1, 0x0, 0x0]) + let apdu = Data([UInt8](repeating: 0x11, count: size)) + let expected = header + apdu + + expect { + try apdu.berTlvEncoded() + }.to(equal(expected)) + } + + func testBerTLV_encode_ffffff() { + let size = 0xFFFFFF + let header = Data([0x80, 0x83, 0xFF, 0xFF, 0xFF]) + let apdu = Data([UInt8](repeating: 0x11, count: size)) + let expected = header + apdu + + expect { + try apdu.berTlvEncoded() + }.to(equal(expected)) + } + + func testBerTLV_encode_1000000() { + let size = 0x1000000 + let header = Data([0x80, 0x84, 0x1, 0x0, 0x0, 0x0]) + let apdu = Data([UInt8](repeating: 0x11, count: size)) + let expected = header + apdu + + expect { + try apdu.berTlvEncoded() + }.to(equal(expected)) + } + + func testBerTLV_encode_1020415() { + let size = 0x1020415 + let header = Data([0x80, 0x84, 0x1, 0x2, 0x4, 0x15]) + let apdu = Data([UInt8](repeating: 0x11, count: size)) + let expected = header + apdu + + expect { + try apdu.berTlvEncoded() + }.to(equal(expected)) + } + + func testBerTLV_decode() { + let berTlvAPDU = Data([0x80, 0x07, 0x00, 0xA4, 0x02, 0x0C, 0x02, 0x2F, 0x01]) + let expected = Data([0x00, 0xA4, 0x02, 0x0C, 0x02, 0x2F, 0x01]) + + expect { + try berTlvAPDU.berTlvDecoded() + }.to(equal(expected)) + } + + func testBerTLV_decode_7f() { + let apdu = [UInt8](repeating: 0x11, count: 0x7F) + let berTlvAPDU = Data([0x80, 0x7F] + apdu) + + expect { + try berTlvAPDU.berTlvDecoded() + }.to(equal(Data(apdu))) + } + + func testBerTLV_decode_80() { + let apdu = [UInt8](repeating: 0x11, count: 0x80) + let berTlvAPDU = Data([0x80, 0x81, 0x80] + apdu) + + expect { + try berTlvAPDU.berTlvDecoded() + }.to(equal(Data(apdu))) + } + + func testBerTLV_decode_ff() { + let apdu = [UInt8](repeating: 0x11, count: 0xFF) + let berTlvAPDU = Data([0x80, 0x81, 0xFF] + apdu) + + expect { + try berTlvAPDU.berTlvDecoded() + }.to(equal(Data(apdu))) + } + + func testBerTLV_decode_100() { + let apdu = [UInt8](repeating: 0x11, count: 0x100) + let berTlvAPDU = Data([0x80, 0x82, 0x1, 0x0] + apdu) + + expect { + try berTlvAPDU.berTlvDecoded() + }.to(equal(Data(apdu))) + } + + func testBerTLV_decode_ffff() { + let apdu = [UInt8](repeating: 0x11, count: 0xFFFF) + let berTlvAPDU = Data([0x80, 0x82, 0xFF, 0xFF] + apdu) + + expect { + try berTlvAPDU.berTlvDecoded() + }.to(equal(Data(apdu))) + } + + func testBerTLV_decode_10000() { + let apdu = [UInt8](repeating: 0x11, count: 0x10000) + let berTlvAPDU = Data([0x80, 0x83, 0x1, 0x0, 0x0] + apdu) + + expect { + try berTlvAPDU.berTlvDecoded() + }.to(equal(Data(apdu))) + } + + func testBerTLV_decode_ffffff() { + let apdu = [UInt8](repeating: 0x11, count: 0xFFFFFF) + let berTlvAPDU = Data([0x80, 0x83, 0xFF, 0xFF, 0xFF] + apdu) + + expect { + try berTlvAPDU.berTlvDecoded() + }.to(equal(Data(apdu))) + } + + func testBerTLV_decode_1000000() { + let apdu = [UInt8](repeating: 0x11, count: 0x1000000) + let berTlvAPDU = Data([0x80, 0x84, 0x1, 0x0, 0x0, 0x0] + apdu) + + expect { + try berTlvAPDU.berTlvDecoded() + }.to(equal(Data(apdu))) + } + + func testBerTLV_decode_1020415() { + let apdu = [UInt8](repeating: 0x11, count: 0x1020415) + let berTlvAPDU = Data([0x80, 0x84, 0x1, 0x2, 0x4, 0x15] + apdu) + + expect { + try berTlvAPDU.berTlvDecoded() + }.to(equal(Data(apdu))) + } + + static var allTests = [ + ("testBerTLV_encode", testBerTLV_encode), + ("testBerTLV_encode_7f", testBerTLV_encode_7f), + ("testBerTLV_encode_80", testBerTLV_encode_80), + ("testBerTLV_encode_ff", testBerTLV_encode_ff), + ("testBerTLV_encode_100", testBerTLV_encode_100), + ("testBerTLV_encode_ffff", testBerTLV_encode_ffff), + ("testBerTLV_encode_10000", testBerTLV_encode_10000), + ("testBerTLV_encode_ffffff", testBerTLV_encode_ffffff), + ("testBerTLV_encode_1000000", testBerTLV_encode_1000000), + ("testBerTLV_encode_1020415", testBerTLV_encode_1020415), + ("testBerTLV_decode_7f", testBerTLV_decode_7f), + ("testBerTLV_decode_80", testBerTLV_decode_80), + ("testBerTLV_decode_ff", testBerTLV_decode_ff), + ("testBerTLV_decode_100", testBerTLV_decode_100), + ("testBerTLV_decode_ffff", testBerTLV_decode_ffff), + ("testBerTLV_decode_10000", testBerTLV_decode_10000), + ("testBerTLV_decode_ffffff", testBerTLV_decode_ffffff), + ("testBerTLV_decode_1000000", testBerTLV_decode_1000000), + ("testBerTLV_decode_1020415", testBerTLV_decode_1020415), + ] +} diff --git a/CardSimulationTestKit/Tests/CardSimulationCardReaderProviderTests/internal/TCPClientExtStreamingTest.swift b/CardSimulationTestKit/Tests/CardSimulationCardReaderProviderTests/internal/TCPClientExtStreamingTest.swift new file mode 100644 index 0000000..1abd61f --- /dev/null +++ b/CardSimulationTestKit/Tests/CardSimulationCardReaderProviderTests/internal/TCPClientExtStreamingTest.swift @@ -0,0 +1,98 @@ +// +// Copyright (c) 2023 gematik GmbH +// +// Licensed under the Apache License, Version 2.0 (the License); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an 'AS IS' BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +@testable import CardSimulationCardReaderProvider +import GemCommonsKit +import Nimble +import SwiftSocket +import XCTest + +final class TCPClientExtStreamingTest: XCTestCase { + var serverSocket: TCPServer! + var listenPort: Int32 { + serverSocket.port + } + + var client: TCPClient! + + override func setUp() { + super.setUp() + + serverSocket = TCPServer(address: "127.0.0.1", port: 0) + if case let .failure(error) = serverSocket.listen() { + Nimble.fail("Failed to setup TCP socket: [\(error)]") + } + client = TCPClient(address: "localhost", port: listenPort) + } + + override func tearDown() { + serverSocket.close() + client.close() + super.tearDown() + } + + func testTCPClient_input_streaming() { + if case let .failure(error) = client.connect(timeout: 1) { + Nimble.fail("Could not connect client socket: \(error)") + } + guard let server = serverSocket.accept() else { + Nimble.fail("Server could not accept") + return + } + let inputStream = client as InputStreaming + expect(inputStream.hasBytesAvailable).to(beFalse()) + + let message = Data([0x1, 0x2, 0x3, 0x4]) + _ = server.send(data: message) + + expect(inputStream.hasBytesAvailable).toEventually(beTrue()) + var receivedMessage = [UInt8](repeating: 0x0, count: 100) + let readBytes = inputStream.read(&receivedMessage, maxLength: receivedMessage.count) + + expect(readBytes).to(equal(4)) + expect(inputStream.hasBytesAvailable).to(beFalse()) + expect(Data(Array(receivedMessage[0 ..< readBytes]))).to(equal(message)) + } + + func testTCPClient_output_streaming() { + if case let .failure(error) = client.connect(timeout: 1) { + Nimble.fail("Could not connect client socket: \(error)") + } + let outputStream = client as OutputStreaming + + guard let server = serverSocket.accept(timeout: 1) else { + Nimble.fail("Server could not accept") + return + } + expect(outputStream.hasSpaceAvailable).to(beTrue()) + + let message = Data([0x8, 0x7, 0x6, 0x5, 0x4, 0x3, 0x2, 0x1]) + let bytesWritten = message.withUnsafeBytes { bytes in + outputStream.write(bytes, maxLength: message.count) + } + expect(bytesWritten).to(equal(message.count)) + let serverRead = Data(server.read(message.count, timeout: 1)!) // swiftlint:disable:this force_unwrapping + expect(serverRead).to(equal(message)) + expect(outputStream.hasSpaceAvailable).to(beTrue()) + + server.close() + } + + static var allTests = [ + ("testTCPClient_input_streaming", testTCPClient_input_streaming), + ("testTCPClient_output_streaming", testTCPClient_output_streaming), + ] +} diff --git a/CardSimulationTestKit/Tests/CardSimulationLoaderTests/Configuration.bundle/channelcontexts/ChannelContext_G2_eGK.xml b/CardSimulationTestKit/Tests/CardSimulationLoaderTests/Configuration.bundle/channelcontexts/ChannelContext_G2_eGK.xml new file mode 100755 index 0000000..e1f26d1 --- /dev/null +++ b/CardSimulationTestKit/Tests/CardSimulationLoaderTests/Configuration.bundle/channelcontexts/ChannelContext_G2_eGK.xml @@ -0,0 +1,632 @@ + + + + + MF + + + 1,1,1,1 + OPENED + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + + + + + + + + + + + false + + + + + + + + + + + true + -1 + + + + + + true + -1 + + + + + + true + -1 + + + + + + true + -1 + + + + + + false + -1 + + + + + + false + -1 + + + + + + false + -1 + + + + + + false + -1 + + + + + + + + + + + + + + + 1 + 3DES + + + + + false + false + + + + + + + + + + + MF + + + 1,1,1,1 + CLOSED + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + + + + + + + + + + + false + + + + + + + + + + + true + -1 + + + + + + true + -1 + + + + + + true + -1 + + + + + + true + -1 + + + + + + false + -1 + + + + + + false + -1 + + + + + + false + -1 + + + + + + false + -1 + + + + + + + + + + + + + + + 1 + 3DES + + + + + false + false + + + + + + + + + + + MF + + + 1,1,1,1 + CLOSED + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + + + + + + + + + + + false + + + + + + + + + + + true + -1 + + + + + + true + -1 + + + + + + true + -1 + + + + + + true + -1 + + + + + + false + -1 + + + + + + false + -1 + + + + + + false + -1 + + + + + + false + -1 + + + + + + + + + + + + + + + 1 + 3DES + + + + + false + false + + + + + + + + + + + MF + + + 1,1,1,1 + CLOSED + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + + + + + + + + + + + false + + + + + + + + + + + true + -1 + + + + + + true + -1 + + + + + + true + -1 + + + + + + true + -1 + + + + + + false + -1 + + + + + + false + -1 + + + + + + false + -1 + + + + + + false + -1 + + + + + + + + + + + + + + + 1 + 3DES + + + + + false + false + + + + + + + + + + diff --git a/CardSimulationTestKit/Tests/CardSimulationLoaderTests/Configuration.bundle/configuration_EGKG2_80276883110000017222_gema5_TCP.xml b/CardSimulationTestKit/Tests/CardSimulationLoaderTests/Configuration.bundle/configuration_EGKG2_80276883110000017222_gema5_TCP.xml new file mode 100755 index 0000000..fde0ff8 --- /dev/null +++ b/CardSimulationTestKit/Tests/CardSimulationLoaderTests/Configuration.bundle/configuration_EGKG2_80276883110000017222_gema5_TCP.xml @@ -0,0 +1,44 @@ + + + + ./images/EGKG2_80276883110000017222_gema5.xml + ./channelcontexts/ChannelContext_G2_eGK.xml + com.achelos.egk.g2sim.tcpipcardio.TcpIpCardIo + + + + + 4 + 4 + 0 + false + + + false + false + + + + + 3039 + + + + ../log/ + Logfile + yyyy-MM-dd HH-mm-ss + .log + false + + + ../log/ + Logfile + yyyy-MM-dd HH-mm-ss + .log + + + + 12350 + com.achelos.egk.g2sim.collis.tpdu.T1Layer + + diff --git a/CardSimulationTestKit/Tests/CardSimulationLoaderTests/Configuration.bundle/configuration_EGKG2_80276883110000017333_gema5_TCP.xml b/CardSimulationTestKit/Tests/CardSimulationLoaderTests/Configuration.bundle/configuration_EGKG2_80276883110000017333_gema5_TCP.xml new file mode 100755 index 0000000..92a6f2e --- /dev/null +++ b/CardSimulationTestKit/Tests/CardSimulationLoaderTests/Configuration.bundle/configuration_EGKG2_80276883110000017333_gema5_TCP.xml @@ -0,0 +1,44 @@ + + + + ./images/EGKG2_80276883110000017333_gema5.xml + ./channelcontexts/ChannelContext_G2_eGK.xml + com.achelos.egk.g2sim.tcpipcardio.TcpIpCardIo + + + + + 4 + 4 + 0 + false + + + false + false + + + + + 3039 + + + + ../log/ + Logfile + yyyy-MM-dd HH-mm-ss + .log + false + + + ../log/ + Logfile + yyyy-MM-dd HH-mm-ss + .log + + + + 12350 + com.achelos.egk.g2sim.collis.tpdu.T1Layer + + diff --git a/CardSimulationTestKit/Tests/CardSimulationLoaderTests/Configuration.bundle/images/EGKG2_80276883110000017222_gema5.xml b/CardSimulationTestKit/Tests/CardSimulationLoaderTests/Configuration.bundle/images/EGKG2_80276883110000017222_gema5.xml new file mode 100755 index 0000000..5f14a6e --- /dev/null +++ b/CardSimulationTestKit/Tests/CardSimulationLoaderTests/Configuration.bundle/images/EGKG2_80276883110000017222_gema5.xml @@ -0,0 +1,1807 @@ + + + + + + + ACTIVATED + CB{ +[ACTIVATED,1,{ +({80||fa||00||00},ALW), +({00||ea||00||00,10||ea||00||00},AND{OR{SMMAC(13),SMMAC(18),SMMAC(cvc_FlagList_CMS:00800000000000)},SMCMDENC}) +}]} + TRUE + {d2760001448000} + 3f00 + 1 + + + + + CB{ +[ACTIVATED,1,{ +({00||04||00||00,00||44||00||00},OR{SMMAC(13),SMMAC(18),SMMAC(cvc_FlagList_CMS:00800000000000)}), +({00||ea||00||00,10||ea||00||00},AND{OR{SMMAC(13),SMMAC(18),SMMAC(cvc_FlagList_CMS:00800000000000)},SMCMDENC}) +}], +[DEACTIVATED,??,{ +({00||44||00||00,00||04||00||00},OR{SMMAC(13),SMMAC(18),SMMAC(cvc_FlagList_CMS:00800000000000)}) +}]} + {d27600000102} + ACTIVATED + TRUE + 1026 + + + + + CB{ +[ACTIVATED,1,{ +({00||04||00||00,00||44||00||00},AND{PWD(83),AUTCHAT(cvc_FlagList_TI:00020000000000)}), +({00||ea||00||00,10||ea||00||00},AND{OR{SMMAC(13),SMMAC(18),SMMAC(cvc_FlagList_CMS:00800000000000)},SMCMDENC}) +}], +[DEACTIVATED,??,{ +({00||44||00||00,00||04||00||00},AND{PWD(83),AUTCHAT(cvc_FlagList_TI:00020000000000)}) +}]} + {d27600014407} + ACTIVATED + TRUE + 1037 + + + + + 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + d010 + 10 + ACTIVATED + TRUE + CB{ +[ACTIVATED,1,{ +({00||e4||00||00},OR{SMMAC(13),SMMAC(18),SMMAC(cvc_FlagList_CMS:00800000000000)}), +({00||b0||??||??},OR{AUTCHAT(cvc_FlagList_TI:00002000000000),AND{PWD(87),AUTCHAT(cvc_FlagList_TI:00004000000000)}}), +({00||0e||??||??,80||0e||90||00,00||d6||??||??,00||d0||??||??},AND{PWD(83),AUTCHAT(cvc_FlagList_TI:00010000000000)}) +}]} + FALSE + FALSE + 2f2b + 2f2b + 1038 + + + + + 00000000000000000000000000000000000000000000000000 + d00e + 0e + ACTIVATED + TRUE + CB{ +[ACTIVATED,1,{ +({00||e4||00||00},OR{SMMAC(13),SMMAC(18),SMMAC(cvc_FlagList_CMS:00800000000000)}), +({00||b0||??||??},OR{AUTCHAT(cvc_FlagList_TI:00002000000000),AND{PWD(87),AUTCHAT(cvc_FlagList_TI:00004000000000)}}), +({00||0e||??||??,80||0e||8e||00,00||d6||??||??,00||d0||??||??},AND{PWD(83),AUTCHAT(cvc_FlagList_TI:00010000000000)}) +}]} + TRUE + TRUE + 19 + 19 + 1039 + + + + + ACTIVATED + CB{ +[ACTIVATED,1,{ +({00||26||00||83,00||28||00||83,00||24||00||83,80||20||00||83,00||2c||00||83,00||2c||01||83,00||20||00||83},ALW) +}], +[DEACTIVATED,??,{ +({00||26||00||83,00||28||00||83,00||24||00||83,80||20||00||83,00||2c||00||83,00||2c||01||83,00||20||00||83},ALW) +}]} + 01 + 03 + FALSE + {(1,INFINITY)} + 1041 + + + + + ACTIVATED + CB{ +[ACTIVATED,1,{ +({00||24||00||87,80||20||00||87,00||2c||00||87,00||2c||01||87,00||20||00||87},ALW) +}]} + 01 + 07 + TRUE + {(1,INFINITY)} + 1542 + + + + + + + CB{ +[ACTIVATED,1,{ +({00||44||00||00,00||04||00||00},OR{PWD(02),AND{PWD(84),AUTCHAT(cvc_FlagList_TI:00001000000000)}}), +({00||ea||00||00,10||ea||00||00},AND{OR{SMMAC(13),SMMAC(18),SMMAC(cvc_FlagList_CMS:00800000000000)},SMCMDENC}) +}], +[DEACTIVATED,??,{ +({00||44||00||00,00||04||00||00},OR{PWD(02),AND{PWD(84),AUTCHAT(cvc_FlagList_TI:00001000000000)}}) +}]} + {d27600014408} + ACTIVATED + TRUE + 1043 + + + + + 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + d01b + 1b + ACTIVATED + TRUE + CB{ +[ACTIVATED,1,{ +({00||e4||00||00},OR{SMMAC(13),SMMAC(18),SMMAC(cvc_FlagList_CMS:00800000000000)}), +({00||b0||??||??},OR{AND{PWD(88),AUTCHAT(cvc_FlagList_TI:00000200000000)},AUTCHAT(cvc_FlagList_TI:00000100000000),PWD(02)}), +({00||0e||??||??,80||0e||9b||00,00||d6||??||??,00||d0||??||??},AND{PWD(84),AUTCHAT(cvc_FlagList_TI:00000800000000)}) +}]} + FALSE + TRUE + 06bd + 06bd + 1044 + + + + + 00000000000000000000000000000000000000000000000000 + d018 + 18 + ACTIVATED + TRUE + CB{ +[ACTIVATED,1,{ +({00||e4||00||00},OR{SMMAC(13),SMMAC(18),SMMAC(cvc_FlagList_CMS:00800000000000)}), +({00||b0||??||??},OR{AND{PWD(88),AUTCHAT(cvc_FlagList_TI:00000200000000)},AUTCHAT(cvc_FlagList_TI:00000100000000),PWD(02)}), +({00||0e||??||??,80||0e||98||00,00||d6||??||??,00||d0||??||??},AND{PWD(84),AUTCHAT(cvc_FlagList_TI:00000800000000)}) +}]} + TRUE + TRUE + 19 + 19 + 1045 + + + + + ACTIVATED + CB{ +[ACTIVATED,1,{ +({00||26||00||84,00||28||00||84,00||24||00||84,80||20||00||84,00||2c||00||84,00||2c||01||84,00||20||00||84},ALW) +}], +[DEACTIVATED,??,{ +({00||26||00||84,00||28||00||84,00||24||00||84,80||20||00||84,00||2c||00||84,00||2c||01||84,00||20||00||84},ALW) +}]} + 01 + 04 + FALSE + {(1,INFINITY)} + 1047 + + + + + ACTIVATED + CB{ +[ACTIVATED,1,{ +({00||24||00||88,80||20||00||88,00||2c||00||88,00||2c||01||88,00||20||00||88},ALW) +}]} + 01 + 08 + TRUE + {(1,INFINITY)} + 1131 + + + + + + + CB{ +[ACTIVATED,1,{ +({00||44||00||00,00||04||00||00},OR{PWD(02),AND{PWD(85),AUTCHAT(cvc_FlagList_TI:00000000010000)}}), +({00||ea||00||00,10||ea||00||00},AND{OR{SMMAC(13),SMMAC(18),SMMAC(cvc_FlagList_CMS:00800000000000)},SMCMDENC}) +}], +[DEACTIVATED,??,{ +({00||44||00||00,00||04||00||00},OR{PWD(02),AND{PWD(85),AUTCHAT(cvc_FlagList_TI:00000000010000)}}) +}]} + {d2760001440a} + ACTIVATED + TRUE + 1048 + + + + + d013 + 13 + ACTIVATED + TRUE + CB{ +[ACTIVATED,1,{ +({00||e2||00||00,00||e2||00||98,00||0c||??||??,80||0c||??||??,00||b2||??||??,00||a2||??||??,00||dc||??||??},OR{PWD(02),AND{PWD(85),AUTCHAT(cvc_FlagList_TI:00000000008000)}}) +}]} + TRUE + TRUE + 14 + 3c + TRUE + 0258 + 1049 + + + + ACTIVATED + 000000e164f0467ffe5d379d0b8bb7cb23230263ada3508540508399db7c06aa873a3d + + + ACTIVATED + 000000e164f0467ffe5d379d0b8bb7cb23230263ada3508540508399db7c06aa873a3d + + + ACTIVATED + 000000e164f0467ffe5d379d0b8bb7cb23230263ada3508540508399db7c06aa873a3d + + + ACTIVATED + 000000e164f0467ffe5d379d0b8bb7cb23230263ada3508540508399db7c06aa873a3d + + + ACTIVATED + 000000e164f0467ffe5d379d0b8bb7cb23230263ada3508540508399db7c06aa873a3d + + + ACTIVATED + 000000e164f0467ffe5d379d0b8bb7cb23230263ada3508540508399db7c06aa873a3d + + + ACTIVATED + 000000e164f0467ffe5d379d0b8bb7cb23230263ada3508540508399db7c06aa873a3d + + + ACTIVATED + 000000e164f0467ffe5d379d0b8bb7cb23230263ada3508540508399db7c06aa873a3d + + + ACTIVATED + 000000e164f0467ffe5d379d0b8bb7cb23230263ada3508540508399db7c06aa873a3d + + + ACTIVATED + 000000e164f0467ffe5d379d0b8bb7cb23230263ada3508540508399db7c06aa873a3d + + + ACTIVATED + 000000e164f0467ffe5d379d0b8bb7cb23230263ada3508540508399db7c06aa873a3d + + + ACTIVATED + 000000e164f0467ffe5d379d0b8bb7cb23230263ada3508540508399db7c06aa873a3d + + + ACTIVATED + 000000e164f0467ffe5d379d0b8bb7cb23230263ada3508540508399db7c06aa873a3d + + + ACTIVATED + 000000e164f0467ffe5d379d0b8bb7cb23230263ada3508540508399db7c06aa873a3d + + + ACTIVATED + 000000e164f0467ffe5d379d0b8bb7cb23230263ada3508540508399db7c06aa873a3d + + + ACTIVATED + 000000e164f0467ffe5d379d0b8bb7cb23230263ada3508540508399db7c06aa873a3d + + + ACTIVATED + 000000e164f0467ffe5d379d0b8bb7cb23230263ada3508540508399db7c06aa873a3d + + + + + + d01a + 1a + ACTIVATED + TRUE + CB{ +[ACTIVATED,1,{ +({00||e2||00||00,00||e2||00||d0,00||0c||??||??,80||0c||??||??,00||b2||??||??,00||a2||??||??,00||dc||??||??},OR{PWD(02),AND{PWD(85),AUTCHAT(cvc_FlagList_TI:00000000008000)}}) +}]} + TRUE + TRUE + 14 + 3c + TRUE + 04b0 + 1050 + + + + ACTIVATED + 000000e164f0467ffe5d379d0b8bb7cb232302ecd446eee98852d785614ef5f0acdb23 + + + ACTIVATED + 000000e164f0467ffe5d379d0b8bb7cb232302ecd446eee98852d785614ef5f0acdb23 + + + ACTIVATED + 000000e164f0467ffe5d379d0b8bb7cb232302ecd446eee98852d785614ef5f0acdb23 + + + ACTIVATED + 000000e164f0467ffe5d379d0b8bb7cb232302ecd446eee98852d785614ef5f0acdb23 + + + ACTIVATED + 000000e164f0467ffe5d379d0b8bb7cb232302ecd446eee98852d785614ef5f0acdb23 + + + ACTIVATED + 000000e164f0467ffe5d379d0b8bb7cb232302ecd446eee98852d785614ef5f0acdb23 + + + ACTIVATED + 000000e164f0467ffe5d379d0b8bb7cb232302ecd446eee98852d785614ef5f0acdb23 + + + ACTIVATED + 000000e164f0467ffe5d379d0b8bb7cb232302ecd446eee98852d785614ef5f0acdb23 + + + ACTIVATED + 000000e164f0467ffe5d379d0b8bb7cb232302ecd446eee98852d785614ef5f0acdb23 + + + ACTIVATED + 000000e164f0467ffe5d379d0b8bb7cb232302ecd446eee98852d785614ef5f0acdb23 + + + ACTIVATED + 000000e164f0467ffe5d379d0b8bb7cb232302ecd446eee98852d785614ef5f0acdb23 + + + ACTIVATED + 000000e164f0467ffe5d379d0b8bb7cb232302ecd446eee98852d785614ef5f0acdb23 + + + ACTIVATED + 000000e164f0467ffe5d379d0b8bb7cb232302ecd446eee98852d785614ef5f0acdb23 + + + ACTIVATED + 000000e164f0467ffe5d379d0b8bb7cb232302ecd446eee98852d785614ef5f0acdb23 + + + ACTIVATED + 000000e164f0467ffe5d379d0b8bb7cb232302ecd446eee98852d785614ef5f0acdb23 + + + ACTIVATED + 000000e164f0467ffe5d379d0b8bb7cb232302ecd446eee98852d785614ef5f0acdb23 + + + ACTIVATED + 000000e164f0467ffe5d379d0b8bb7cb232302ecd446eee98852d785614ef5f0acdb23 + + + + + + ACTIVATED + CB{ +[ACTIVATED,1,{ +({00||26||00||85,00||28||00||85,00||24||00||85,80||20||00||85,00||2c||00||85,00||2c||01||85,00||20||00||85},ALW) +}], +[DEACTIVATED,??,{ +({00||26||00||85,00||28||00||85,00||24||00||85,80||20||00||85,00||2c||00||85,00||2c||01||85,00||20||00||85},ALW) +}]} + 01 + 05 + TRUE + {(1,INFINITY)} + 1101 + + + + + + + CB{ +[ACTIVATED,1,{ +({00||44||00||00,00||04||00||00},OR{PWD(02),AND{PWD(89),AUTCHAT(cvc_FlagList_TI:00000000000800)}}), +({00||ea||00||00,10||ea||00||00},AND{OR{SMMAC(13),SMMAC(18),SMMAC(cvc_FlagList_CMS:00800000000000)},SMCMDENC}) +}], +[DEACTIVATED,??,{ +({00||44||00||00,00||04||00||00},OR{PWD(02),AND{PWD(89),AUTCHAT(cvc_FlagList_TI:00000000000800)}}) +}]} + {d2760001440b} + ACTIVATED + TRUE + 3048 + + + + + 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + e001 + 01 + ACTIVATED + TRUE + CB{ +[ACTIVATED,1,{ +({00||e4||00||00},OR{SMMAC(13),SMMAC(18),SMMAC(cvc_FlagList_CMS:00800000000000)}), +({00||b0||??||??},OR{AUTCHAT(cvc_FlagList_TI:00000000002000),AND{PWD(89),AUTCHAT(cvc_FlagList_TI:00000000004000)},PWD(02)}), +({00||0e||??||??,80||0e||81||00,00||d6||??||??,00||d0||??||??},AND{PWD(89),AUTCHAT(cvc_FlagList_TI:00000000001000)}) +}]} + FALSE + TRUE + 1b58 + 1b58 + 3045 + + + + + 00000000000000000000000000000000000000000000000000 + e002 + 02 + ACTIVATED + TRUE + CB{ +[ACTIVATED,1,{ +({00||e4||00||00},OR{SMMAC(13),SMMAC(18),SMMAC(cvc_FlagList_CMS:00800000000000)}), +({00||b0||??||??},OR{AUTCHAT(cvc_FlagList_TI:00000000002000),AND{PWD(89),AUTCHAT(cvc_FlagList_TI:00000000004000)},PWD(02)}), +({00||0e||??||??,80||0e||82||00,00||d6||??||??,00||d0||??||??},AND{PWD(89),AUTCHAT(cvc_FlagList_TI:00000000001000)}) +}]} + TRUE + TRUE + 19 + 19 + 3145 + + + + + ACTIVATED + CB{ +[ACTIVATED,1,{ +({00||24||00||89,80||20||00||89,00||2c||00||89,00||2c||01||89,00||20||00||89},ALW) +}], +[DEACTIVATED,??,{ +({00||24||00||89,80||20||00||89,00||2c||00||89,00||2c||01||89,00||20||00||89},ALW) +}]} + 01 + 09 + TRUE + {(1,INFINITY)} + 3484 + + + + + + + CB{ +[ACTIVATED,1,{ +({00||44||00||00,00||04||00||00},OR{PWD(02),AND{PWD(8c),AUTCHAT(cvc_FlagList_TI:00000000000400)}}), +({00||ea||00||00,10||ea||00||00},AND{OR{SMMAC(13),SMMAC(18),SMMAC(cvc_FlagList_CMS:00800000000000)},SMCMDENC}) +}], +[DEACTIVATED,??,{ +({00||44||00||00,00||04||00||00},OR{PWD(02),AND{PWD(8c),AUTCHAT(cvc_FlagList_TI:00000000000400)}}) +}]} + {d2760001440c} + ACTIVATED + TRUE + 1051 + + + + + e004 + 04 + ACTIVATED + TRUE + CB{ +[ACTIVATED,1,{ +({00||b2||??||??,00||a2||??||??},OR{PWD(02),AND{PWD(8c),AUTCHAT(cvc_FlagList_TI:00000000000200)},AND{PWD(8d),AUTCHAT(cvc_FlagList_TI:00000000000200)}}), +({00||e2||00||00,00||e2||00||20,00||0c||??||??,80||0c||??||??,00||dc||??||??},AND{PWD(8c),AUTCHAT(cvc_FlagList_TI:00000000000100)}) +}]} + TRUE + TRUE + 03 + 45 + TRUE + 00cf + 3485 + + + + ACTIVATED + 00 + + + ACTIVATED + 00 + + + ACTIVATED + 00 + + + + + + 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + e005 + 05 + ACTIVATED + TRUE + CB{ +[ACTIVATED,1,{ +({00||e4||00||00},OR{SMMAC(13),SMMAC(18),SMMAC(cvc_FlagList_CMS:00800000000000)}), +({00||b0||??||??},OR{AND{PWD(8c),AUTCHAT(cvc_FlagList_TI:00000000000200)},AND{PWD(8d),AUTCHAT(cvc_FlagList_TI:00000000000200)}}), +({00||0e||??||??,00||d6||??||??},OR{AND{PWD(8c),AUTCHAT(cvc_FlagList_TI:00000000000100)},AND{PWD(8d),AUTCHAT(cvc_FlagList_TI:00000000000100)}}) +}]} + FALSE + TRUE + 34f8 + 34f8 + 3145 + + + + + e006 + 06 + ACTIVATED + TRUE + CB{ +[ACTIVATED,1,{ +({00||b2||??||??,00||a2||??||??},OR{PWD(02),AND{PWD(8c),AUTCHAT(cvc_FlagList_TI:00000000000200)},AND{PWD(8d),AUTCHAT(cvc_FlagList_TI:00000000000200)}}), +({00||e2||00||00,00||e2||00||30,00||0c||??||??,80||0c||??||??,00||dc||??||??},AND{PWD(8c),AUTCHAT(cvc_FlagList_TI:00000000000100)}) +}]} + TRUE + TRUE + 05 + 78 + TRUE + 0258 + 3849 + + + + ACTIVATED + 00 + + + ACTIVATED + 00 + + + ACTIVATED + 00 + + + ACTIVATED + 00 + + + ACTIVATED + 00 + + + + + + 00000000000000000000000000000000000000000000000000 + e007 + 07 + ACTIVATED + TRUE + CB{ +[ACTIVATED,1,{ +({00||e4||00||00},OR{SMMAC(13),SMMAC(18),SMMAC(cvc_FlagList_CMS:00800000000000)}), +({00||b0||??||??},OR{AND{PWD(8c),AUTCHAT(cvc_FlagList_TI:00000000000200)},AND{PWD(8d),AUTCHAT(cvc_FlagList_TI:00000000000200)}}), +({00||d6||??||??},OR{AND{PWD(8c),AUTCHAT(cvc_FlagList_TI:00000000000100)},AND{PWD(8d),AUTCHAT(cvc_FlagList_TI:00000000000100)}}) +}]} + TRUE + TRUE + 19 + 19 + 3846 + + + + + ACTIVATED + CB{ +[ACTIVATED,1,{ +({00||24||00||8c,80||20||00||8c,00||2c||00||8c,00||2c||01||8c,00||20||00||8c},ALW) +}], +[DEACTIVATED,??,{ +({00||24||00||8c,80||20||00||8c,00||2c||00||8c,00||2c||01||8c,00||20||00||8c},ALW) +}]} + 01 + 0c + TRUE + {(1,INFINITY)} + 3847 + + + + + 0d + ACTIVATED + CB{ +[ACTIVATED,1,{ +({00||24||01||8d,00||2c||02||8d},PWD(8c)), +({80||20||00||8d,00||20||00||8d},ALW) +}]} + 06 + 08 + 03 + 03 + regularPassword + TRUE + {(1,INFINITY)} + 00 + 26123456FFFFFFFF + Wildcard + 3848 + + + + + 08 + ACTIVATED + CB{ +[ACTIVATED,1,{ +({00||2a||80||86,00||2a||86||b8},OR{AND{PWD(8c),AUTCHAT(cvc_FlagList_TI:00000000000200)},AND{PWD(8d),AUTCHAT(cvc_FlagList_TI:00000000000200)}}), +({00||46||81||88},AND{OR{PWD(8c),PWD(8d)},OR{AUTCHAT(cvc_FlagList_TI:00000000000200),AUTCHAT(cvc_FlagList_TI:00000000000100)}}), +({00||46||c0||88},AND{PWD(8c),AUTCHAT(cvc_FlagList_TI:00000000000100)}) +}]} + brainpoolP256r1 + {[1,(elcSharedSecretCalculation)]} + Wildcard + AttributeNotSet + 3849 + + + + + + + d005 + 05 + ACTIVATED + TRUE + CB{ +[ACTIVATED,1,{ +({00||08||??||??,00||06||??||??},OR{PWD(02),AND{PWD(01),AUTCHAT(cvc_FlagList_TI:00000080000000)}}), +({00||b2||??||??,00||a2||??||??},OR{PWD(02),AND{PWD(01),AUTCHAT(cvc_FlagList_TI:00000040000000)}}), +({00||dc||??||??},AND{PWD(01),AUTCHAT(cvc_FlagList_TI:00000010000000)}), +({00||0c||??||??,80||0c||??||??},AND{PWD(01),AUTCHAT(cvc_FlagList_TI:00000040000000)}) +}]} + TRUE + TRUE + 0a + 45 + TRUE + 1027 + + + + ACTIVATED + 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + + + ACTIVATED + 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + + + ACTIVATED + 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + + + ACTIVATED + 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + + + ACTIVATED + 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + + + ACTIVATED + 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + + + ACTIVATED + 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + + + ACTIVATED + 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + + + ACTIVATED + 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + + + ACTIVATED + 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + + + + + + 01001f8b080000000000000085505d4bc33014fd2b25ef6b36a15025e9d02932704e2c0ed9cb08cd35294bd392dc56edaff716059521bedccfc339e75eb17c6b5c32408875eb255ba4739680af5a5d7b23d9badccef23c3b9f2d329644545e2bd77a90ec1d225b16e26975b88558d91e7044d84d2c95858040400acf9bbb6475bd39ec6e1ecbf5f65eb22c3d9b0448d247c92c6277c1f96b4c0d340aeb63aa81bf283e44dd4c810f846785d8f7a3b2aef7269205ec6321cacf3c17fcab12fc147405b1f51a023c902f72ed4de8bb0e8a5cf0bf56a2040747ac077a08060586469710467474d724f7dd88bdb25efddcfd1e90b5532efeffc38a0f03b325bc92010000 + d003 + 03 + ACTIVATED + TRUE + CB{ +[ACTIVATED,1,{ +({00||e4||00||00},OR{SMMAC(13),SMMAC(18),SMMAC(cvc_FlagList_CMS:00800000000000)}), +({00||b0||??||??},OR{PWD(02),AND{PWD(01),AUTCHAT(cvc_FlagList_TI:00000004000000)},AUTCHAT(cvc_FlagList_TI:00000002000000),AND{OR{SMMAC(12),SMMAC(19),SMMAC(cvc_FlagList_CMS:00400000000000)},SMRSPENC}}), +({00||0e||??||??,80||0e||??||??},OR{SMMAC(12),SMMAC(19),SMMAC(cvc_FlagList_CMS:00400000000000)}), +({00||d6||??||??,00||d0||??||??},AND{OR{SMMAC(12),SMMAC(19),SMMAC(cvc_FlagList_CMS:00400000000000)},SMCMDENC}) +}]} + FALSE + TRUE + 0258 + 0102 + 1028 + + + + + d006 + 06 + ACTIVATED + TRUE + CB{ +[ACTIVATED,1,{ +({00||e2||00||00,00||e2||00||30},OR{AND{PWD(01),AUTCHAT(cvc_FlagList_TI:00000001000000)},AUTCHAT(cvc_FlagList_TI:00000000800000)}), +({00||b2||??||??,00||a2||??||??},OR{PWD(02),AND{PWD(01),AUTCHAT(cvc_FlagList_TI:00000000400000)}}) +}]} + TRUE + TRUE + 32 + 2e + FALSE + 1029 + + + + ACTIVATED + 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + + + ACTIVATED + 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + + + ACTIVATED + 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + + + ACTIVATED + 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + + + ACTIVATED + 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + + + ACTIVATED + 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + + + ACTIVATED + 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + + + ACTIVATED + 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + + + ACTIVATED + 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + + + ACTIVATED + 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + + + ACTIVATED + 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + + + ACTIVATED + 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + + + ACTIVATED + 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + + + ACTIVATED + 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + + + ACTIVATED + 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + + + ACTIVATED + 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + + + ACTIVATED + 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + + + ACTIVATED + 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + + + ACTIVATED + 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + + + ACTIVATED + 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + + + ACTIVATED + 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + + + ACTIVATED + 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + + + ACTIVATED + 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + + + ACTIVATED + 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + + + ACTIVATED + 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + + + ACTIVATED + 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + + + ACTIVATED + 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + + + ACTIVATED + 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + + + ACTIVATED + 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + + + ACTIVATED + 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + + + ACTIVATED + 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + + + ACTIVATED + 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + + + ACTIVATED + 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + + + ACTIVATED + 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + + + ACTIVATED + 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + + + ACTIVATED + 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + + + ACTIVATED + 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + + + ACTIVATED + 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + + + ACTIVATED + 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + + + ACTIVATED + 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + + + ACTIVATED + 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + + + ACTIVATED + 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + + + ACTIVATED + 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + + + ACTIVATED + 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + + + ACTIVATED + 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + + + ACTIVATED + 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + + + ACTIVATED + 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + + + ACTIVATED + 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + + + ACTIVATED + 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + + + ACTIVATED + 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + + + + + + 017c1f8b08000000000000008d52db4ec3300cfd952aefd42b53d18adc2060082601436c0cdea6d07aa45a9ba0241b973fe62f70d9058678e025c939b18f4fece0d16b53474b72beb2261749dc111199c2969579cac56034dcebf5d26c2f4945e48332a5aaada15cbc91174712ef4ea7379c6ac9d455a169d2caf0ee0271242f0f5797d169ff6a3a39bb1d0d86d7b948e3fdb602d7343e173a84e74380171f3f51a342358f4b829982a52f9b768125c70b893f74dd0e32d3415f3e2449a79b66bdac83f0fb0ebfec1989e7f4b870c1b3ab4523932ced75d2a48bb043e3c43aa31a92e3ca28d65a23bc5685fe3a5d5031d76ae13f0cc29664695fe89a0a1de47dabb84538ae02d5f2c6d9591cf55d8cb02270149cf29ecc71e9887776697da8a90aef4ad7b27bc00f42d8e170e8821cb130638416e0254f43e2bdd5c633592b6e39391e1cc93ec25f34c22a655d5d9e286db49df9d03adb9078c1ef338ba6e14e77b3e811e107b10dfb760e9b06c3ee90e01f5f437e02ff821ecb7d020000 + d001 + 01 + ACTIVATED + TRUE + CB{ +[ACTIVATED,1,{ +({00||e4||00||00},OR{SMMAC(13),SMMAC(18),SMMAC(cvc_FlagList_CMS:00800000000000)}), +({00||b0||??||??},ALW), +({00||0e||??||??,80||0e||??||??},OR{SMMAC(12),SMMAC(19),SMMAC(cvc_FlagList_CMS:00400000000000)}), +({00||d6||??||??,00||d0||??||??},AND{OR{SMMAC(12),SMMAC(19),SMMAC(cvc_FlagList_CMS:00400000000000)},SMCMDENC}) +}]} + FALSE + TRUE + 0352 + 017E + 1030 + + + + + + d01c + 1c + ACTIVATED + TRUE + CB{ +[ACTIVATED,1,{ +({00||e4||00||00},OR{SMMAC(13),SMMAC(18),SMMAC(cvc_FlagList_CMS:00800000000000)}), +({00||b0||??||??,00||0e||??||??,80||0e||??||??,00||d6||??||??,00||d0||??||??},ALW) +}]} + TRUE + TRUE + 012c + 00 + 1031 + + + + + + da0a + 0a + ACTIVATED + TRUE + CB{ +[ACTIVATED,1,{ +({00||e4||00||00},OR{SMMAC(13),SMMAC(18),SMMAC(cvc_FlagList_CMS:00800000000000)}), +({00||b0||??||??,00||0e||??||??,80||0e||??||??,00||d6||??||??,00||d0||??||??},ALW) +}]} + TRUE + TRUE + 0384 + 00 + 1032 + + + + + 30323031353038303330373531303500500200000030000004 + d00c + 0c + ACTIVATED + TRUE + CB{ +[ACTIVATED,1,{ +({00||e4||00||00},OR{SMMAC(13),SMMAC(18),SMMAC(cvc_FlagList_CMS:00800000000000)}), +({00||b0||??||??},ALW), +({00||0e||??||??,80||0e||??||??},OR{SMMAC(12),SMMAC(19),SMMAC(cvc_FlagList_CMS:00400000000000)}), +({00||d6||??||??,00||d0||??||??},AND{OR{SMMAC(12),SMMAC(19),SMMAC(cvc_FlagList_CMS:00400000000000)},SMCMDENC}) +}]} + TRUE + TRUE + 19 + 19 + 1033 + + + + + d00f + 0f + ACTIVATED + TRUE + CB{ +[ACTIVATED,1,{ +({00||e4||00||00},OR{SMMAC(13),SMMAC(18),SMMAC(cvc_FlagList_CMS:00800000000000)}), +({00||b2||??||??},OR{PWD(02),AND{PWD(01),AUTCHAT(cvc_FlagList_TI:00000000100000)},AUTCHAT(cvc_FlagList_TI:00000000080000),AND{OR{SMMAC(13),SMMAC(18),SMMAC(cvc_FlagList_CMS:00800000000000),SMMAC(12),SMMAC(19),SMMAC(cvc_FlagList_CMS:00400000000000)},SMRSPENC}}), +({00||dc||??||??},AND{OR{SMMAC(13),SMMAC(18),SMMAC(cvc_FlagList_CMS:00800000000000),SMMAC(12),SMMAC(19),SMMAC(cvc_FlagList_CMS:00400000000000)},SMCMDENC}) +}]} + TRUE + TRUE + 05 + 0f + TRUE + 1034 + + + + ACTIVATED + 000000000000000000000000000000 + + + ACTIVATED + 000000000000000000000000000000 + + + ACTIVATED + 000000000000000000000000000000 + + + ACTIVATED + 000000000000000000000000000000 + + + ACTIVATED + 000000000000000000000000000000 + + + + + + 000801ae01af02ae1f8b0800000000000000bd535d4fc23014fd2b4bdfa59b3864a6abc18f18a3889188861752d9755b1877a62da8fc7a6f11cd4626fae44b9b7b4fcfb9a7a7a9387e9b17de12b4c94b8c59d0f29907382d931cd3985d0e077bdd6e18ed0521f38c5598a8a24488d93b18762cc5fde9a4571429cc214718399169067a81a94994057cec5f7ba767fdc9e8fc6e7839b88959d8da770368249a9865d6be1c71fe6a5aa4a06c3e6b25c09f155f9a64ee16bea4f34c8a6f610bba52b931669a2dec4a8a13487344b9ef07a1dff5db826f1ae2aa3464c46a05a923d7ca192092888ca228ec1c76235ff046bcce2a1460029a220279b6c5a862e246cd416e6ee6f517744ccf9431105c5c8d045fa3a2f7a4619ae19af537ab61d03e083bd1ff5be53bbcf2edbaf191c60ba3ec2ac7e7d2d40a1a527b6454daca764564d3aa72261b37a43f59f33f1d10c32a6bd751f440af6ce1049c50a953d7a5376eec8bb1ca50fdc0f81113439a461f8740d027b410ee084d6d77438505c56ae11a72e34c02bad3cdc057a8d52b3d0c6ee5414770b793ad1d71f0ed7c792d7d5eff53fcf78f2c3f00a44417ce2a0400001f8b080000000000000085505d4bc33014fd2b25ef6b36a15025e9d02932704e2c0ed9cb08cd35294bd392dc56edaff716059521bedccfc339e75eb17c6b5c32408875eb255ba4739680af5a5d7b23d9badccef23c3b9f2d329644545e2bd77a90ec1d225b16e26975b88558d91e7044d84d2c95858040400acf9bbb6475bd39ec6e1ecbf5f65eb22c3d9b0448d247c92c6277c1f96b4c0d340aeb63aa81bf283e44dd4c810f846785d8f7a3b2aef7269205ec6321cacf3c17fcab12fc147405b1f51a023c902f72ed4de8bb0e8a5cf0bf56a2040747ac077a08060586469710467474d724f7dd88bdb25efddcfd1e90b5532efeffc38a0f03b325bc92010000 + d002 + 02 + ACTIVATED + TRUE + CB{ +[ACTIVATED,1,{ +({00||e4||00||00},OR{SMMAC(13),SMMAC(18),SMMAC(cvc_FlagList_CMS:00800000000000)}), +({00||b0||??||??},ALW), +({00||0e||??||??,80||0e||??||??},OR{SMMAC(12),SMMAC(19),SMMAC(cvc_FlagList_CMS:00400000000000)}), +({00||d6||??||??,00||d0||??||??},AND{OR{SMMAC(12),SMMAC(19),SMMAC(cvc_FlagList_CMS:00400000000000)},SMCMDENC}) +}]} + FALSE + TRUE + 04e2 + 02AF + 1035 + + + + + d009 + 09 + ACTIVATED + TRUE + CB{ +[ACTIVATED,1,{ +({00||08||??||??,00||06||??||??},OR{PWD(02),AND{PWD(01),AUTCHAT(cvc_FlagList_TI:00000080000000)}}), +({00||b2||??||??,00||a2||??||??,00||dc||??||??},OR{PWD(02),AND{PWD(01),AUTCHAT(cvc_FlagList_TI:00000008000000)}}) +}]} + TRUE + TRUE + 0a + 14 + TRUE + 1036 + + + + ACTIVATED + 0000000000000000000000000000000000000000 + + + ACTIVATED + 0000000000000000000000000000000000000000 + + + ACTIVATED + 0000000000000000000000000000000000000000 + + + ACTIVATED + 0000000000000000000000000000000000000000 + + + ACTIVATED + 0000000000000000000000000000000000000000 + + + ACTIVATED + 0000000000000000000000000000000000000000 + + + ACTIVATED + 0000000000000000000000000000000000000000 + + + ACTIVATED + 0000000000000000000000000000000000000000 + + + ACTIVATED + 0000000000000000000000000000000000000000 + + + ACTIVATED + 0000000000000000000000000000000000000000 + + + + + + + + CB{ +[ACTIVATED,1,{ +({00||ea||00||00,10||ea||00||00},AND{OR{SMMAC(13),SMMAC(18),SMMAC(cvc_FlagList_CMS:00800000000000)},SMCMDENC}) +}]} + {a000000167455349474e} + ACTIVATED + TRUE + 1051 + + + + + 308204D6308203BEA0030201020207034B80216D43AE300D06092A864886F70D01010B0500308183310B3009060355040613024445311F301D060355040A0C1667656D6174696B20476D6248204E4F542D56414C494431323030060355040B0C294B6F6D706F6E656E74656E2D4341206465722054656C656D6174696B696E667261737472756B747572311F301D06035504030C1647454D2E4B4F4D502D43413820544553542D4F4E4C59301E170D3135303830343131303130305A170D3137303830343131303130305A3081C8310B300906035504061302444531293027060355040A0C2067656D6174696B204D75737465726B6173736531474B564E4F542D56414C494431133011060355040B0C0A5831313033353938393031123010060355040B0C093939393536373839303116301406035504040C0D4865636B68617573C383C2A96E310D300B060355042A0C0454696E6131123010060355040C0C0950726F662E2044722E312A302806035504030C2150726F662E2044722E2054696E61204865636B686175736E544553542D4F4E4C5930820122300D06092A864886F70D01010105000382010F003082010A0282010100AB1E208F682FDD3985CD8352C7F5B2A347ACF9B32E5F833A8E7BC58081EAAB11ABF591677D6BCECA304495C5F07ECAD98A51E446E9246725AB130454C2EAD7C9B3B687E2F1647E80620C10D7CC617F37A5918693B4FB747172E6B63CE18423AC2EA8FA2511D31B0161198D1E930AB16309FE692EE863836E687BA8DCD26F5936CA409504725547FAF3A0C65FB7F801E6669F02F0B1ADE694E035628FF220B94DF798264F566ED97E74AD4F16D224D78BEF9CD1B53663CBE11A210F20DB5139420D45032F296BBA8A7101564FF100C281913491C0BEB9CDE4B61F884947DFD3A6F8F0669337372610D3E4A926BC151801E602DAA7C46EDDC3D0BE4B1CE18376410203010001A382010630820102303006052B240803030427302530233021301F301D30100C0E56657273696368657274652F2D72300906072A8214004C043130200603551D2004193017300A06082A8214004C048123300906072A8214004C0446300E0603551D0F0101FF040403020780304B06082B06010505070101043F303D303B06082B06010505073001862F687474703A2F2F6F6373702E706B692E74656C656D6174696B2D746573743A383038302F434D4F4353502F4F435350301D0603551D0E0416041489FE32F74D3CAE713B32E4E028D0D969E2E76D11301F0603551D2304183016801425306D18D53CB141690A977A4375E9951601A6D2300F0603551D130101FF04053003010100300D06092A864886F70D01010B0500038201010045C3FB31ADB9ED559B8B501EEDD922E5753BBD5628BBD4717D2E7583811BE8EA40C2F0837CD992409A70A3828CC123B84892F6DEF43854CAA45805593794D9AB0D5A07324479C576FD7899668F2AABC0B0E81F68A81274046E99AAAEDAC79A41FE6DD04296259387539E32747FD8C22D1351C022C72E86EE3E769787BAEC9C89934B2A5D3B389F8DA31527B7412277C9F9F68B59C012A96A4D33976EAD56ABE919AF062A28A17FEAC28AE75BC2A0CD974B61371B3FB437BB6428D99BE9FB27B956A7A4AF019B18AD8B47E63880E7E6190A88D2D81559BB27295ED9BFC9E0D667A3691DCFB6C11EA0BFA31F5EB10B9E5CCF607C664B01F629C80D313A308FDF90 + c500 + 01 + ACTIVATED + TRUE + CB{ +[ACTIVATED,1,{ +({00||e4||00||00,00||0e||??||??,80||0e||??||??},OR{SMMAC(13),SMMAC(18),SMMAC(cvc_FlagList_CMS:00800000000000)}), +({00||d6||??||??,00||d0||??||??},AND{OR{SMMAC(13),SMMAC(18),SMMAC(cvc_FlagList_CMS:00800000000000)},SMCMDENC}), +({00||b0||??||??},ALW) +}]} + TRUE + FALSE + 076c + 04DA + 1052 + + + + + 308204953082037DA00302010202061A44D785FAB3300D06092A864886F70D01010B0500308183310B3009060355040613024445311F301D060355040A0C1667656D6174696B20476D6248204E4F542D56414C494431323030060355040B0C294B6F6D706F6E656E74656E2D4341206465722054656C656D6174696B696E667261737472756B747572311F301D06035504030C1647454D2E4B4F4D502D43413820544553542D4F4E4C59301E170D3135303830343131303130305A170D3137303830343131303130305A3074310B300906035504061302444531293027060355040A0C2067656D6174696B204D75737465726B6173736531474B564E4F542D56414C494431123010060355040B0C093939393536373839303126302406035504030C1D4144383042453136434132393330313932433133544553542D4F4E4C5930820122300D06092A864886F70D01010105000382010F003082010A0282010100B0BA458E88217DE0F767BFBBB5E94606F604B89F7B72DDCC8AD21CB99302EC9C52F1DE53A097148C4C4F3B4115E3ADA8C512C6F973A2426A7F8741A08B9C67519985E1B707B69281578AAFDCC02B69DCA6EEE03CE704D4AF9FB0FA5DF19A08126A399E8543EB4420B65492892689331E93A3F2303BB5868B7EB402BDBCC3B6450F649E65ABED4F74A1B4E5CD649503F8360F45FFD8135D441560C0C76F4C02029E11B2B8534D7ED96BC68CADAC9D5D96950F163B1D22FB5536F7D925F8F18CE9A570567465077E5B9069297AA2DC7DF67D83E9EBA3A405AC168D76BE6FE8DAD7ADAA6C5540CA6CFF8B02330F71985BCD761BCF7E9DAF324E329EAA4C0AAD906D0203010001A382011B30820117303006052B240803030427302530233021301F301D30100C0E56657273696368657274652F2D72300906072A8214004C043130200603551D2004193017300A06082A8214004C048123300906072A8214004C0447300E0603551D0F0101FF04040302078030130603551D25040C300A06082B06010505070302304B06082B06010505070101043F303D303B06082B06010505073001862F687474703A2F2F6F6373702E706B692E74656C656D6174696B2D746573743A383038302F434D4F4353502F4F435350301D0603551D0E041604140B9EF2AB8019A34DA8E780A5FA90711F3704AE06301F0603551D2304183016801425306D18D53CB141690A977A4375E9951601A6D2300F0603551D130101FF04053003010100300D06092A864886F70D01010B0500038201010078678146A5BCCCC04CB7035DA56E5C5A560247B6BF64FDD4A5CB72BC8392F3E0728599438D8A672287927A8905459D6E9DD4DE89FC0A4ACEBAABB3B21E88B75E969D1EDC3754C04D780B6566D6C3170BB26384FC4E5DEC62269732E96D9E9B374B93095E27CBF2935113D2408CAECE671F37E21EC7E9A85766F339374925940AD73FC2D35A7902FF63FF331CEDB352962165AFB3AC73F8203AC68FC1D6DAF22536D29224F866E253F39C474E4A794258005CC28DC94DF678B1E713A84E5F0B4DC9585998F6687F5CF1827972F0A92F9F7D264C7F7010E8C7267DFD54B1637E23722F2A48448336C4E2E362754C33DF2BFA3F9F2FACE676AEBF4D7BDE40640F96 + c509 + 09 + ACTIVATED + TRUE + CB{ +[ACTIVATED,1,{ +({00||e4||00||00,00||0e||??||??,80||0e||??||??},OR{SMMAC(13),SMMAC(18),SMMAC(cvc_FlagList_CMS:00800000000000)}), +({00||d6||??||??,00||d0||??||??},AND{OR{SMMAC(13),SMMAC(18),SMMAC(cvc_FlagList_CMS:00800000000000)},SMCMDENC}), +({00||b0||??||??},OR{PWD(02),AND{PWD(01),AUTCHAT(cvc_FlagList_TI:00800000000000)},AUTCHAT(cvc_FlagList_TI:00400000000000),AND{OR{SMMAC(13),SMMAC(18),SMMAC(cvc_FlagList_CMS:00800000000000)},SMRSPENC}}) +}]} + TRUE + FALSE + 076c + 0499 + 1054 + + + + + 308204D2308203BAA003020102020703D0834295D9A8300D06092A864886F70D01010B0500308183310B3009060355040613024445311F301D060355040A0C1667656D6174696B20476D6248204E4F542D56414C494431323030060355040B0C294B6F6D706F6E656E74656E2D4341206465722054656C656D6174696B696E667261737472756B747572311F301D06035504030C1647454D2E4B4F4D502D43413820544553542D4F4E4C59301E170D3135303830343131303130305A170D3137303830343131303130305A3081C4310B300906035504061302444531293027060355040A0C2067656D6174696B204D75737465726B6173736531474B564E4F542D56414C494431133011060355040B0C0A5831313033353938393031123010060355040B0C093939393536373839303112301006035504040C094865636B686175736E310D300B060355042A0C0454696E6131123010060355040C0C0950726F662E2044722E312A302806035504030C2150726F662E2044722E2054696E61204865636B686175736E544553542D4F4E4C5930820122300D06092A864886F70D01010105000382010F003082010A028201010091C6FB52C46907E44208BA13191960AE2C51101EFE11E58A1A5DC90F01AA10BCA9C447E8028C558F7D5EF7C3FD69ABC03B631CEDD304A31293F05361C7326C6253483CF3CC2CDD201F7DBED927B327B061F19A21D375D2025700EACA7BFE359072FDAE3E3870D2D67D4C2D418ED114DB8122F77626D9C926C518144F40ABB772C34CFE123C4C11F16F4B2795FF3799DB0E16D0801309BD17A871353A0FC3A0D37F078A23AD124C57212554C29DEC52AF2FB15644C5707566A8FD92FE08D0E1074653B9A2B7E61AFD548C17A2DF065761EF49AB92310F0C988AA7BDF315AC6F35F878B0960500AE303142F1B3A98F46A6495EE460E2BD4F2B53EAB901D8DC74290203010001A382010630820102303006052B240803030427302530233021301F301D30100C0E56657273696368657274652F2D72300906072A8214004C043130200603551D2004193017300A06082A8214004C048123300906072A8214004C0444300E0603551D0F0101FF040403020430304B06082B06010505070101043F303D303B06082B06010505073001862F687474703A2F2F6F6373702E706B692E74656C656D6174696B2D746573743A383038302F434D4F4353502F4F435350301D0603551D0E0416041431C051C1F4DAB1F26941D00C5D612856DB2306B0301F0603551D2304183016801425306D18D53CB141690A977A4375E9951601A6D2300F0603551D130101FF04053003010100300D06092A864886F70D01010B050003820101009CAA6C67CB3C55E28C4CF956DF090EA211B27019301C9E24E4CF154AE8E65BCD79E60AB05FA1DBF4D2EF18F68CBCF6BE540273F7A02D4599F8E35C30531442B2D0191BC85915EE4BB35B483105382B7071DE47ADBA558B16AE4B245FB6E9D0C81A22BDE05D197D87AFE08EEB110023380569F1919D0D6597EC0B6E52BE66654F3A3BE6EFDF6B2869F593D5EB0D75B81769A0B06C4A20451BF5F71E0C6B3A8B8DC143C133273FC461791B45AA4F9BEB6421C255F30113F6C8A90F4C8BEC6440BF7F82E03CF352C5E8F85E2ED77FD904E13C4AD2DF2757A2AB55AB5F8C0206305D73BA1EB207B8E16B89A2BB8CB27800FF7E17F91BDF07AAC1FE6CCBA0B1D05F47 + c200 + 02 + ACTIVATED + TRUE + CB{ +[ACTIVATED,1,{ +({00||b0||??||??},ALW) +}]} + TRUE + FALSE + 076c + 04D6 + 1056 + + + + + 3082048030820368A003020102020607403BA616F5300D06092A864886F70D01010B0500308183310B3009060355040613024445311F301D060355040A0C1667656D6174696B20476D6248204E4F542D56414C494431323030060355040B0C294B6F6D706F6E656E74656E2D4341206465722054656C656D6174696B696E667261737472756B747572311F301D06035504030C1647454D2E4B4F4D502D43413820544553542D4F4E4C59301E170D3135303830343131303130305A170D3137303830343131303130305A3074310B300906035504061302444531293027060355040A0C2067656D6174696B204D75737465726B6173736531474B564E4F542D56414C494431123010060355040B0C093939393536373839303126302406035504030C1D4144383042453136434132393330313932433133544553542D4F4E4C5930820122300D06092A864886F70D01010105000382010F003082010A0282010100B4246AE540A1459B331B288F007949432CE98FC7B24FE356CAD4A4F21AE3815433BEFA53E8A9FF0E4367D856A94ADA90516F79B5F857663EFB9C159BFFD93CEAFE352FDAEDA92A5867D429AE33AE57F6BCE36289D8EDEF718AF7A7CC2BC948D445B8DB92F99C848CCA3BF38CAE4EB89996D5A336D9EE3520D7728AB160ACC28BE8BECD6B334944C285917AD10EDD7D3EA08335E86A71A5C7647B11F15A6FDE6B124DAD1567C481CBF3A3C6F74549780452A031805B28C432099431A718C34AD052B582C135B6262046E0951CDB18E2EF7D80B10EB16F2A69BAEE6E17EC557DEE78FD5CC8C09374578A314DDE39BD37869FBB6C0A23103CCF129B8A587EAFE3970203010001A382010630820102303006052B240803030427302530233021301F301D30100C0E56657273696368657274652F2D72300906072A8214004C043130200603551D2004193017300A06082A8214004C048123300906072A8214004C0445300E0603551D0F0101FF040403020430304B06082B06010505070101043F303D303B06082B06010505073001862F687474703A2F2F6F6373702E706B692E74656C656D6174696B2D746573743A383038302F434D4F4353502F4F435350301D0603551D0E041604143350D5F03D6E6AE59E62364FB73C427C332A0247301F0603551D2304183016801425306D18D53CB141690A977A4375E9951601A6D2300F0603551D130101FF04053003010100300D06092A864886F70D01010B05000382010100A989EC8A8013F7567185FD24800942968B5FABE731440C96498CB250DB5B300ADA6EB8A0C27F346A30557DC624E44FB61546D6CF479C0AB93F8909933406453FFDAE63145E816320BE89B69642CB1FB6958826BF76593F6731833B70462F8D994193230901E26D1DB0AE904487CD4A34AAC8AF3C1B4EC8A96294EC42931556DC103404378A31133B4E30482C8BCB72F7F8A7EC95FFC78CFD61DBD7F6CB3B4654BD84BE6ED0D38F3E0ABCD92FCB24D70968C472586B77404077DEADBFD1E5A3335016AEDC1E4BB814838F8DB275EBF1A6CD64356B972FB359B26E7D9EF3C383F16723A43609E8329342A1A4750206121E4E9CFDB5CBD9606DBC91DFA9A8DEAA8D + c50a + 0a + ACTIVATED + TRUE + CB{ +[ACTIVATED,1,{ +({00||e4||00||00,00||0e||??||??,80||0e||??||??},OR{SMMAC(13),SMMAC(18),SMMAC(cvc_FlagList_CMS:00800000000000)}), +({00||d6||??||??,00||d0||??||??},AND{OR{SMMAC(13),SMMAC(18),SMMAC(cvc_FlagList_CMS:00800000000000)},SMCMDENC}), +({00||b0||??||??},OR{PWD(02),AND{PWD(01),AUTCHAT(cvc_FlagList_TI:00200000000000)},AUTCHAT(cvc_FlagList_TI:00100000000000),AND{OR{SMMAC(13),SMMAC(18),SMMAC(cvc_FlagList_CMS:00800000000000)},SMRSPENC}}) +}]} + TRUE + FALSE + 076c + 0484 + 1059 + + + + + 02 + ACTIVATED + CB{ +[ACTIVATED,1,{ +({00||88||00||00,00||2a||9e||9a,00||2a||9e||ac},OR{PWD(02),AND{PWD(01),AUTCHAT(cvc_FlagList_TI:00080000000000)}}), +({00||46||81||00,00||46||81||82},ALW), +({00||e4||20||82},OR{SMMAC(13),SMMAC(18),SMMAC(cvc_FlagList_CMS:00800000000000)}) +}]} + 0800 + AB1E208F682FDD3985CD8352C7F5B2A347ACF9B32E5F833A8E7BC58081EAAB11ABF591677D6BCECA304495C5F07ECAD98A51E446E9246725AB130454C2EAD7C9B3B687E2F1647E80620C10D7CC617F37A5918693B4FB747172E6B63CE18423AC2EA8FA2511D31B0161198D1E930AB16309FE692EE863836E687BA8DCD26F5936CA409504725547FAF3A0C65FB7F801E6669F02F0B1ADE694E035628FF220B94DF798264F566ED97E74AD4F16D224D78BEF9CD1B53663CBE11A210F20DB5139420D45032F296BBA8A7101564FF100C281913491C0BEB9CDE4B61F884947DFD3A6F8F0669337372610D3E4A926BC151801E602DAA7C46EDDC3D0BE4B1CE1837641 + 010001 + 89FE92BD7384DDFFCC82AE7BEC9B9C8306835D1EFDAFB2D15F243B62E5E24C30C51F15328337949D030DDC46B32A5D05D001387962FCA35E023724D0021C8706B731E525C40B89E498AD284C0F1B350FB82AC27F8D7D172B8240C20818C98A47099DE5944D6A9425A99B846D7AA12DEA339E024EFCC37BB366F90A7582129FBB38D4B8D8AB8757EC45F5BDBC30AE642E347B354BEB55234F6D27D75DEEB8FA571608F1F5A5813E52F3B50B3048CED03499BB4E2F5F7713FA1F651D195ADFA612340AA88D9CA8015E72AC02ACDBE6E774C869D6B37205BC46D369352C4711370F55F6786C8B975C0B1474DC6A173D9596E4F3966A675CD97F33C88FFC74AF4001 + C9CBC84BD565DA3490555A51DFEF94E9B5C143146D9CF9596978EA681280736FD26699C56E80B6180C2FF3CCCC127DAE8E4905507B8BAF4682D49A9E2C383BE35D5B359C74443D47F9B0FF89734E2D18DF25F808926FEB975797BE96E14831F959ADC3BB51F08FC7D95CBAF8072C41E9390D06ECBC5135ADA64FD0F15D17D701 + D914CACBD753C912A7775DD7BA1374ABDAAF85704B5D8EB3E227EFB4F2EF14D2EB9D7595FBF3411140FF86532505EBF8A92A917E8DCB6B37C68B432A138C6742D335F594E4241A7554A777B93B0FFFE1D6FA7599089446127D4D8EC28B432B63C9B1670337F207CEA6968DF229285822BF84F6F0B4FD74A526118419862CDF41 + B5BB8575EE081D1C4B83E2A46BA52B19D2EAEACB61F0058BA57614BC87351140FA5E164BFCB983C4626D6905DE1F24FAE7FF10FF2B546014834C8EB6B6222AA5177545F1D1AF86F4E404A80D943F2A5404DAFFE65062E4EBD621BDADC9D327D665121D7CFC4D465F77FC901140FC759B611ABF4AC249ECAAA765A849464A6B01 + C69E428ACD4268D7FB87B8C2180B9315666A7001F5C2ED3D62F03D5F67631EBF793AC18A7052FA36CA2CC17F3381BE8CEE62F76A3E5C5F8651CFBBAD34E3A2DB3E9AC14EF08AA3F6B474E193061A367A31134A23B1F8D0403C8B88D2314F4CD4E986BA84F45C2B8E85577D1A9353C988498963D38B15D7F2FEE8C9DFFCA6F3C1 + 1E5E8B589AE8C6A257729F5DE99F041BC6A0335878EB134B70A2F97374AB95EB71E9ADE9F3CDC90EEE2F1AFBF4208A8C6805257201B3F03E1A577CE1CCF2CD06794B90774843EE67CA149151FC05D191FFE79578F31ADD24B302C554BA2515D566D187BD78614DC6D3AB9369416900FC01638E5FE59461EF71390591EC2C9AB4 + {[1,(rsaClientAuthentication,sign9796_2_DS2,signPKCS1_V1_5,signPSS)]} + TRUE + 1061 + + + + + 06 + ACTIVATED + CB{ +[ACTIVATED,1,{ +({00||88||00||00,00||2a||9e||9a,00||2a||9e||ac},OR{PWD(02),AND{PWD(01),AUTCHAT(cvc_FlagList_TI:00800000000000)},AUTCHAT(cvc_FlagList_TI:00400000000000)}), +({00||46||81||00,00||46||81||86},ALW), +({00||e4||20||86},OR{SMMAC(13),SMMAC(18),SMMAC(cvc_FlagList_CMS:00800000000000)}) +}]} + 0800 + B0BA458E88217DE0F767BFBBB5E94606F604B89F7B72DDCC8AD21CB99302EC9C52F1DE53A097148C4C4F3B4115E3ADA8C512C6F973A2426A7F8741A08B9C67519985E1B707B69281578AAFDCC02B69DCA6EEE03CE704D4AF9FB0FA5DF19A08126A399E8543EB4420B65492892689331E93A3F2303BB5868B7EB402BDBCC3B6450F649E65ABED4F74A1B4E5CD649503F8360F45FFD8135D441560C0C76F4C02029E11B2B8534D7ED96BC68CADAC9D5D96950F163B1D22FB5536F7D925F8F18CE9A570567465077E5B9069297AA2DC7DF67D83E9EBA3A405AC168D76BE6FE8DAD7ADAA6C5540CA6CFF8B02330F71985BCD761BCF7E9DAF324E329EAA4C0AAD906D + 010001 + 7A4DFF133BFCC9ABE62C63D1997C3E1D5527414A05DA21CB8B8B0B9C1634A0E132B9F69E33763B1F3934601293FE84515749BE70266975C3544C9BCB6AB32C0199D8C0B3B55FD19637AA6038CAB980C2D6B85C716983BB596B8FC4453D8DD6E63FA36EA455B3BCEB52A3C6E1A9CCAB970EA0185CEF059A7E718A4C9758CAAD1989469E44C3EBDC9D5D38B96FAC092A9E85A15FA5B31934F79CE5CC2C50715476ED2884B4B730F3A2B250CEC38DDF0139082D4633E3EF7057131F66AB4994EC0BBCEDA01AD6D84EECBADCE8471E677067EB1CEE47A59AC94968F25D387D20532C8E7BC20FAF6BDC62E16AA87E85F4676E6AB4EB553C4A625DAA093FFDB247B641 + C921B780313C0C55675791F932CFC38173BFEC98400C91D1EC776531D266ABEBAD7921C992C2DF72AE1897184AA7FE7874ECE761E89744F26E8ABDB8B05E6B0AEAA22405AF77DEB293B6AFAAA8208D9B13D51E28F958A777410B9BAA2520AD8C3CA5B9EE09B0886E359DD5AA67A8F169D946248A2420BA0C890B4CA352862CD1 + E0F043F27A2715D03C6F7FA35FA8FB2CEC7953250805C17AA08A9DE35AD614819ED164F350370666D088D48B87978894B8FB2950E8FB9ACDFBD0BF8B4999CFCAAA05D0FC4F41932292CF9DEB540202523151ADBEFF3D56339A2B5AE1356CBB1F08988C401D30C0EB5CBB7989545B458114C0BA1BF592284F3AAB8A5E4C02E0DD + 220E747CDF5954994D73558345A84A696C090E6DC5429B9A5918EA68A240C25198C10F088BB23595BC86EB66B0957B9037F43945A9D59B561583A696543ED88F33A59AC5DFAD4367277DE286DA0B110F362F7AF8E327B0CB8F970097B1CBB3B73039BB9EE3C32186CFCB56F790AFD998DBB275D372449C5C2D045DC8B5DB8451 + 309D3CD226FC538691C93738C3EFED7924128499B846262EAE8BC6DBE041EC64A7427222F3EF307F000AD284E56526AB9DDF0A6AE62F9AA1720F0796BEED732F45D7C3F703DA1446A09C267139D2C555A63B14E5F69BF70968047EBBB5A42E3CE2CAB56515E9F787E69ECE01942DB5B3D41C631CAFD24ACBF4CE263583100C31 + 30870F6C879F426EB7D980B4EDCB82BBD705EEE3C01377410955E6A6F0FE4E543DBBC70B11EE243988B56A3CF6C047710788C441E0064A2FCCD12C18B2138F29EE12AB83F8E403449BEDE3AC2AA7820817B220246FE63E7A679875968238FFF2D38CEA8391FBE9A6E1CC136AF77A09A7398D1ACD538D3CA2519C9C36F7BED6C4 + {[1,(rsaClientAuthentication,sign9796_2_DS2,signPSS)]} + TRUE + 1064 + + + + + 03 + ACTIVATED + CB{ +[ACTIVATED,1,{ +({00||2a||80||86,00||2a||86||b8},OR{PWD(02),AND{PWD(01),AUTCHAT(cvc_FlagList_TI:00040000000000)}}), +({00||46||81||83},ALW) +}]} + 0800 + 91C6FB52C46907E44208BA13191960AE2C51101EFE11E58A1A5DC90F01AA10BCA9C447E8028C558F7D5EF7C3FD69ABC03B631CEDD304A31293F05361C7326C6253483CF3CC2CDD201F7DBED927B327B061F19A21D375D2025700EACA7BFE359072FDAE3E3870D2D67D4C2D418ED114DB8122F77626D9C926C518144F40ABB772C34CFE123C4C11F16F4B2795FF3799DB0E16D0801309BD17A871353A0FC3A0D37F078A23AD124C57212554C29DEC52AF2FB15644C5707566A8FD92FE08D0E1074653B9A2B7E61AFD548C17A2DF065761EF49AB92310F0C988AA7BDF315AC6F35F878B0960500AE303142F1B3A98F46A6495EE460E2BD4F2B53EAB901D8DC7429 + 010001 + 6359C2854918EFE8EFDC34BCB959635BB1165A2F5526EB5270DFC41C771CE9A53AEA6BBB42A953D2A4362A1427CC71E264570B2B46AA9D5D16F82E4BB04FBC3052E423AE60539F2CBA699FBD2DE25AC54A2B37C99FED678072BD4C474DB415DB69935CC24903139E5CECA2D750374CC8C0BD0CFC38442B6441E5444A332014B899C9CF091C02631B22B6B659C2F854ACFEBFF8D31BAD0D24D0A36369A461B5A5887BBDC3277D26A9AAB094D3FC9BDF7D9CB4444CD8B7542727322F4CFA814CDAE6E73ABF62493D0F1450B1339B89F85479B28F068CC75410114E9BA320D79D3F75662071578B7A19A5F1EA0B53755E975051EA6E29AC035495255926D15DBDB5 + BA987BB5FDABC4CB016CE8B7F5945A0E0573E2E65469772548888DE6D245C85102C3122675C95FFE4884296CA09A3CF2A87FCA26838B65B4F238F9D6C08648BAD8C7AB14A86CE5B14C138196D6325BD261011E92EE6068EC5325E5A2081D68E5C529FE189A34C7FB4313925941066F25DC2F659EE121CFF2C81CA987FF03D617 + C7FFCCCA71ED2F0E7309F43D5FE1415740E7402FA518C7BE9007A06C979114A7C052885494A4FA162E31CED1CFC45C31128D23396CC583FC17217545E0E8E19A9FFBEA7A1BD3BF642D91260B80C07922FA1DE183977F9B6AC12CE2ED5F699BC940C012F5F69E6D56C6662A8D7C2F1EA6388D2385BFF50793B2B494FC654AAFBF + 64471614D3E2BFBBA964721C8AA9D34BBDBA6DB202A33B189A46689C275CC12E6821955B7DE95EE134EF71A3A31BC0AD57C875470562A0A2019A8509D8255268B79F765D7FB6262A860BE594BE400A00A1890C79420A25D8FB465E86197E54A546B42E8DE231835790D0AFD1AF94599F2B197DAF48A5F72F2E43D907F1108AB9 + 9F7A8FAFC2C6D226207F887DC44DD78F9F1687AD36661B290EAAB636C16993E1EC4F239CE666E370FA670737710870474536BC26D7606CCD811851EE65D8EDC521DB7C6EE06FAA0754FA902ECDFD2CDB423CBF8DF2297421DD665091DDEA55AA567292EC053AF18F276762792DD459094CC0E6D98966F722C47690F2EE466EFB + 378DB3564184782AE4042A4B6F7D0CF24D0C5CC3BC46018AE89E6892D8B1F6E255486630BF4D740793EF9720AC6912A4FFB651F7499EFEFF2FFC4787E31F0DE9883E5D9389EC69BFA30154109AB0E7221417E3506B75A18D62702C13C8FFAB1A35D38A534DA82D4DE7E12CE4FD9045CB5C4AE6C5293063CC0B5C50BB2A7868F7 + {[1,(rsaDecipherPKCS1_V1_5,rsaDecipherOaep)]} + TRUE + 1067 + + + + + 07 + ACTIVATED + CB{ +[ACTIVATED,1,{ +({00||2a||80||86,00||2a||86||b8},OR{PWD(02),AND{PWD(01),AUTCHAT(cvc_FlagList_TI:00200000000000)},AUTCHAT(cvc_FlagList_TI:00100000000000)}), +({00||46||81||87},ALW), +({00||e4||20||87},OR{SMMAC(13),SMMAC(18),SMMAC(cvc_FlagList_CMS:00800000000000)}) +}]} + 0800 + B4246AE540A1459B331B288F007949432CE98FC7B24FE356CAD4A4F21AE3815433BEFA53E8A9FF0E4367D856A94ADA90516F79B5F857663EFB9C159BFFD93CEAFE352FDAEDA92A5867D429AE33AE57F6BCE36289D8EDEF718AF7A7CC2BC948D445B8DB92F99C848CCA3BF38CAE4EB89996D5A336D9EE3520D7728AB160ACC28BE8BECD6B334944C285917AD10EDD7D3EA08335E86A71A5C7647B11F15A6FDE6B124DAD1567C481CBF3A3C6F74549780452A031805B28C432099431A718C34AD052B582C135B6262046E0951CDB18E2EF7D80B10EB16F2A69BAEE6E17EC557DEE78FD5CC8C09374578A314DDE39BD37869FBB6C0A23103CCF129B8A587EAFE397 + 010001 + 6D2D111805F677C01AD61FDBA336DE9EF6CE4AD4858E03432BC47A7F3CAA9B4C13DC6FCC80DADE789F83854AE869345378F76DB54A6075D8401795C528E7591336A3B77020CF809979BBCCD3060168D062241129682EB40A856598ED95AFF512A97AE2A08DE53D3432B0E8E75F10D8B245070F5703F7697D90F59B76EB176903EBB6A3EB0DFB304C646DAC5C7DA9AAD72E91A836C73028477E6358C65E045DBF1F5E7391FFE3A743A09D8901818F28F1089DB80EE021100FB0B9422AF82BBF55987C7554F058766309AFA17ACB3C70CEB3E74FF636D03ACBBB89B8554FC093FD6A8D982AAD19AB74DE1F3297EA72D5E28A78516A79E8888426C5452C7C8473D1 + CE679D6CCA2AB45854FC457CB60562A5AA1048ACB8A5C75DDEFDCBFB173F4112504FF4E32D1FDCD85D8EDA8E3506752A6293CF664F4FC2CA431B9E82D5405A1D5672834417EE243C11872E88CC1127609B1EFC691A19541015EEA463CD0531DAC92778CE19A2800399F64D6F5EB178682662714476F91D634AD7FA1855BF1729 + DF6D579F0F50D5E27C7818AA90BC91013314A8D1F853D43482DC57102932A3D57E14771D861CF6BBDC74E8B4402065928886A205AD91094A1F37634F4D97FE63002ACDB8E1082DA52C50A8EAB7A177137DC6F7E16E397615703DDCFB31A01AB176B94D149CAA4C34AE7808AB5B71A1A124AEED97C79E382F9112B148C4303CBF + B22C5583BCBCC27361E1672671861292C94C473FFA20F909BA5DC1C09D5FB80F540EC1697DE17C65B5D5842AAFF14420F3797ED6656E87CACBC542BED3D13A390B0FCCEA71F1DB8B92E1EBB4A0DBC9EF25D8C8B0FD9B91AA55146D09CDC8473202E4B4EECCC82ED36D0B65EAD68642573D934B0D7BDA2D9931D96085B3374289 + A40BCD74ED32E607E869E97A7AD0E90ADF6D80D2C22912BB07862EAAA0051D83E891B02FCE43BFE9896191669F5AEA192002F23D8705E1B3399E5A5D64D47FA443002A925F2FB90BF8B0B485BA1464B0BBFDF60CDFF872BA24F257295C737885EA6CFDAA6FA91E50E3F5203068F0D2C2D58356D1C57067428D9B12EE21966553 + 6E265263008998B56B53DC201C22C065567520C22F754197CD3876542717B5185AC0CD2A9E4E682D5B337142C088BD9FBCFEF0D9D940A71D440D09DE52A05F1CC36E3A12DCD805F0852FEE88CDB332FF85FB69A5102FD9B2423039A612B2C6A103D9902B1C1BD316333DFD7BD41327181A5418E490038F80EDE2E40B72396F5A + {[1,(rsaDecipherPKCS1_V1_5,rsaDecipherOaep)]} + TRUE + 1074 + + + + + + + + {e828bd080fa000000167455349474e} + ACTIVATED + TRUE + 1077 + + + + + 3015020101030100a60d0c0b44494e2056203636323931 + 5032 + 12 + ACTIVATED + TRUE + CB{ +[ACTIVATED,1,{ +({00||b0||??||??},ALW) +}]} + FALSE + TRUE + 17 + 17 + 1078 + + + + + + + e01102020409020300800202020409020204095f520c806605444573696d739621f0d003040300d210444567656d5f4e4f4e455f2020000001d310444567656d434f535f53494d20000100d41045474b47322020202020202020010304d610444567656d5f4e4f4e455f2020010000cf15000000000000000000000000000000000000000000 + 2f01 + 1d + ACTIVATED + TRUE + CB{ +[ACTIVATED,1,{ +({00||b0||??||??,00||d0||??||??},ALW) +}]} + TRUE + TRUE + 86 + 86 + 3 + + + + + 7F2181D87F4E81915F290170420844454758588302147F494D06082A8648CE3D04030286410433057328A45B238364F03A5AE7CAD3C52917741C3489008EF1972555E9924AEE66AC1DF71F93A256A3F08074DC069DA7547E2C57A42D8E3F027CBBAC0C29FFCA5F200844454745581602147F4C1306082A8214004C0481185307800000000000005F25060104010102055F24060202010102045F37407C4093884F52203E2AB02C7567D2750D6D04915489CA61D95584898FAD554A611024972EED6E730D5E9BE8EF4E8C39209F300B40E205327FD48EB64DB4DFE8C4 + 2f07 + 07 + ACTIVATED + TRUE + CB{ +[ACTIVATED,1,{ +({00||d6||??||??},AND{OR{SMMAC(13),SMMAC(18),SMMAC(cvc_FlagList_CMS:00800000000000)},SMCMDENC}), +({00||b0||??||??},ALW) +}]} + TRUE + FALSE + 00dc + DC + 1001 + + + + + 7F2181DA7F4E81935F290170420844454745581602147F494B06062B24030503018641045AF7DAA917CDC2BBBC24509489803B1801FBF1D07B6210585C04DEECDE3E1A34A9142BE9A800CA591468CF284D485280B3F3BE52CB846B25B7827174243E28935F200C0009802768831100000172227F4C1306082A8214004C0481185307000000000000005F25060105000800045F24060107000800045F3740105707EA1FB7BE023EC5BBD2E21DCD7D35EB8253E67CF86F01A3183FA7D066AF9028E939474F2C293C20AD10CB6D42C91952753FDF1DC44C0D4DAB16FE3F3B90 + 2f06 + 06 + ACTIVATED + TRUE + CB{ +[ACTIVATED,1,{ +({00||d6||??||??},AND{OR{SMMAC(13),SMMAC(18),SMMAC(cvc_FlagList_CMS:00800000000000)},SMCMDENC}), +({00||b0||??||??},ALW) +}]} + TRUE + FALSE + 00de + DE + 1003 + + + + + 2f00 + 1e + ACTIVATED + TRUE + CB{ +[ACTIVATED,1,{ +({00||e2||00||00,00||e2||00||f0,00||dc||??||??},AND{OR{SMMAC(13),SMMAC(18),SMMAC(cvc_FlagList_CMS:00800000000000)},SMCMDENC}), +({80||0c||??||??},OR{SMMAC(13),SMMAC(18),SMMAC(cvc_FlagList_CMS:00800000000000)}), +({00||b2||??||??,00||a2||??||??},ALW) +}]} + TRUE + TRUE + 14 + 20 + FALSE + 00c8 + 7 + + + + ACTIVATED + 61094f07d2760001448000 + + + ACTIVATED + 61084f06d27600000102 + + + ACTIVATED + 610c4f0aa000000167455349474e + + + ACTIVATED + 61114f0fe828bd080fa000000167455349474e + + + ACTIVATED + 61084f06d27600014407 + + + ACTIVATED + 61084f06d27600014408 + + + ACTIVATED + 61084f06d2760001440a + + + ACTIVATED + 61084f06d2760001440c + + + + + + 5a0a80276883110000017222 + 2f02 + 02 + ACTIVATED + TRUE + CB{ +[ACTIVATED,1,{ +({00||b0||??||??},ALW) +}]} + FALSE + TRUE + 0c + 0C + 5 + + + + + 2f10 + 10 + ACTIVATED + TRUE + CB{ +[ACTIVATED,1,{ +({00||b2||??||??,00||a2||??||??},ALW), +({00||dc||??||??},AND{OR{SMMAC(13),SMMAC(18),SMMAC(cvc_FlagList_CMS:00800000000000)},SMCMDENC}) +}]} + TRUE + TRUE + 04 + 05 + FALSE + 1005 + + + + ACTIVATED + 0040000000 + + + ACTIVATED + 0040000000 + + + ACTIVATED + 0040000000 + + + ACTIVATED + 0000000000 + + + + + + ef2bc003020000c103040302c21045474b47322020202020202020010304c403010000c503020000c703010000 + 2f11 + 11 + ACTIVATED + TRUE + CB{ +[ACTIVATED,1,{ +({00||b0||??||??},ALW), +({00||d6||??||??},AND{OR{SMMAC(13),SMMAC(18),SMMAC(cvc_FlagList_CMS:00800000000000)},SMCMDENC}), +({80||0e||??||??},OR{SMMAC(13),SMMAC(18),SMMAC(cvc_FlagList_CMS:00800000000000)}) +}]} + TRUE + TRUE + 3c + 2d + 1111 + + + + + 01 + ACTIVATED + CB{ +[ACTIVATED,1,{ +({00||24||00||01,80||20||00||01,00||2c||00||01,00||2c||01||01,00||20||00||01},ALW) +}]} + 06 + 08 + 03 + 03 + regularPassword + TRUE + {(1,INFINITY)} + 0a + 26123456FFFFFFFF + 2812345678FFFFFF + 1006 + + + + + ACTIVATED + CB{ +[ACTIVATED,1,{ +({00||24||00||02,80||20||00||02,00||2c||00||02,00||2c||01||02,00||20||00||02},ALW) +}]} + 01 + 02 + TRUE + {(1,INFINITY)} + 1007 + + + + + 13 + ACTIVATED + CB{ +[ACTIVATED,1,{ +({00||82||00||00,00||86||00||00},ALW), +({00||e4||20||13},OR{SMMAC(13),SMMAC(18),SMMAC(cvc_FlagList_CMS:00800000000000)}) +}]} + AES_128 + 00 + aesSessionkey4SM + 110f49ba0810f100617b4bedb130a3da + 4995ae87d31c04572607d04a92f4b4dc + 1019 + + + + + 18 + ACTIVATED + CB{ +[ACTIVATED,1,{ +({00||82||00||00,00||86||00||00},ALW), +({00||e4||20||18},OR{SMMAC(13),SMMAC(18),SMMAC(cvc_FlagList_CMS:00800000000000)}) +}]} + AES_256 + 00 + aesSessionkey4SM + c967b562a5fb68b72e61e2832017264c47efa273b15dea7ffaf3353ddb33c01f + be8050bcf3eee2437a01d91cd6eeaad3d57551dc4fb0350212e6fa79a740dc17 + 2419 + + + + + 12 + ACTIVATED + CB{ +[ACTIVATED,1,{ +({00||82||00||00,00||86||00||00},ALW), +({00||e4||20||12},OR{SMMAC(13),SMMAC(18),SMMAC(cvc_FlagList_CMS:00800000000000)}) +}]} + AES_128 + 00 + aesSessionkey4SM + 953be21975d681ea57913ecfac79485d + f440bb7b89e2e9f03eb00b748250f498 + 1021 + + + + + 19 + ACTIVATED + CB{ +[ACTIVATED,1,{ +({00||82||00||00,00||86||00||00},ALW), +({00||e4||20||19},OR{SMMAC(13),SMMAC(18),SMMAC(cvc_FlagList_CMS:00800000000000)}) +}]} + AES_256 + 00 + aesSessionkey4SM + ea3464714d276171393411de09d4c06bfa727911813ce36bb99a62b762d69bb2 + 6b72804324254e8eebddc7e04ab7ca9a6853c983ef1675da799d724069d84e32 + 1419 + + + + + 09 + ACTIVATED + CB{ +[ACTIVATED,1,{ +({00||86||00||00,00||88||00||00,00||46||81||09},ALW), +({00||e4||20||09},OR{SMMAC(13),SMMAC(18),SMMAC(cvc_FlagList_CMS:00800000000000)}) +}]} + brainpoolP256r1 + {[1,(elcAsynchronAdmin,elcRoleAuthentication,elcSessionkey4SM)]} + TRUE + 00 + 18E095AEB4D451798CCF8D58C5EF88EB54B2D4FCA327097061A9754C7D29E6D1 + 1008 + + + + + 4445475858830214 + ACTIVATED + brainpoolP256r1 + 040E33B79383171D098F140E3F9336CE25D450AFACDCDA30C97EBC74A2C60680D28D89AAD9B4418C62FAB1481D7485DF045E09E03E87368D1A283145BF46B8F6BB + ecdsa-with-SHA256 + CB{ +[ACTIVATED,1,{ +({00||2a||00||be},ALW), +({00||e4||21||00},AND{OR{SMMAC(13),SMMAC(18),SMMAC(cvc_FlagList_CMS:00800000000000)},SMCMDENC}) +}]} + CB{ +[ACTIVATED,1,{ +({00||e4||21||00},AND{OR{SMMAC(13),SMMAC(18),SMMAC(cvc_FlagList_CMS:00800000000000)},SMCMDENC}), +({00||2a||00||be},ALW) +}]} + CB{ +[ACTIVATED,1,{ +({00||e4||21||00,00||86||00||00,00||82||00||00},ALW) +}]} + cvc_FlagList_TI:ffffffffffffc3 + 020400090202 + 1010 + + + + + 0000000000000013 + ACTIVATED + brainpoolP256r1 + 040E33B79383171D098F140E3F9336CE25D450AFACDCDA30C97EBC74A2C60680D28D89AAD9B4418C62FAB1481D7485DF045E09E03E87368D1A283145BF46B8F6BB + ecdsa-with-SHA256 + CB{ +[ACTIVATED,1,{ +({00||2a||00||be},ALW), +({00||e4||21||00},AND{OR{SMMAC(13),SMMAC(18),SMMAC(cvc_FlagList_CMS:00800000000000)},SMCMDENC}) +}]} + CB{ +[ACTIVATED,1,{ +({00||e4||21||00},AND{OR{SMMAC(13),SMMAC(18),SMMAC(cvc_FlagList_CMS:00800000000000)},SMCMDENC}), +({00||2a||00||be},ALW) +}]} + CB{ +[ACTIVATED,1,{ +({00||e4||21||00,00||86||00||00},ALW) +}]} + cvc_FlagList_CMS:ffbfffffffffff + 010501020301 + AttributeNotSet + 1020 + + + + + + 3b901881b1fe451f031f + 3b909581b1fe451f0392 + 6883110000017222 + 010500080004 + ACTIVATED + + 05 + + + V3.8.1 + FALSE + FALSE + ..\d3\TLK_eGK_G2_sample.d3 + E02_init;Image_V1.3.4;gemSpec_eGK_ObjSys_V3.8.1;gemSpec_COS_Wrapper_V1.6.0;gemSpec_COS_V3.7.0;Produkttypversion_V4.3.2;Release_V1.4.7 + EGKG2 + FALSE + + diff --git a/CardSimulationTestKit/Tests/CardSimulationLoaderTests/Configuration.bundle/images/EGKG2_80276883110000017333_gema5.xml b/CardSimulationTestKit/Tests/CardSimulationLoaderTests/Configuration.bundle/images/EGKG2_80276883110000017333_gema5.xml new file mode 100755 index 0000000..a6b2651 --- /dev/null +++ b/CardSimulationTestKit/Tests/CardSimulationLoaderTests/Configuration.bundle/images/EGKG2_80276883110000017333_gema5.xml @@ -0,0 +1,1614 @@ + + + + + + + ACTIVATED + CB{ +[ACTIVATED,1,{ +({80||fa||00||00},ALW), +({00||ea||00||00,10||ea||00||00},AND{OR{SMMAC(13),SMMAC(18),SMMAC(cvc_FlagList_CMS:00800000000000)},SMCMDENC}) +}]} + TRUE + {d2760001448000} + 3f00 + 1 + + + + + CB{ +[ACTIVATED,1,{ +({00||04||00||00,00||44||00||00},OR{SMMAC(13),SMMAC(18),SMMAC(cvc_FlagList_CMS:00800000000000)}), +({00||ea||00||00,10||ea||00||00},AND{OR{SMMAC(13),SMMAC(18),SMMAC(cvc_FlagList_CMS:00800000000000)},SMCMDENC}) +}], +[DEACTIVATED,??,{ +({00||44||00||00,00||04||00||00},OR{SMMAC(13),SMMAC(18),SMMAC(cvc_FlagList_CMS:00800000000000)}) +}]} + {d27600000102} + ACTIVATED + TRUE + 1026 + + + + + CB{ +[ACTIVATED,1,{ +({00||04||00||00,00||44||00||00},AND{PWD(83),AUTCHAT(cvc_FlagList_TI:00020000000000)}), +({00||ea||00||00,10||ea||00||00},AND{OR{SMMAC(13),SMMAC(18),SMMAC(cvc_FlagList_CMS:00800000000000)},SMCMDENC}) +}], +[DEACTIVATED,??,{ +({00||44||00||00,00||04||00||00},AND{PWD(83),AUTCHAT(cvc_FlagList_TI:00020000000000)}) +}]} + {d27600014407} + ACTIVATED + TRUE + 1037 + + + + + 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + d010 + 10 + ACTIVATED + TRUE + CB{ +[ACTIVATED,1,{ +({00||e4||00||00},OR{SMMAC(13),SMMAC(18),SMMAC(cvc_FlagList_CMS:00800000000000)}), +({00||b0||??||??},OR{AUTCHAT(cvc_FlagList_TI:00002000000000),AND{PWD(87),AUTCHAT(cvc_FlagList_TI:00004000000000)}}), +({00||0e||??||??,80||0e||90||00,00||d6||??||??,00||d0||??||??},AND{PWD(83),AUTCHAT(cvc_FlagList_TI:00010000000000)}) +}]} + FALSE + FALSE + 2f2b + 2f2b + 1038 + + + + + 00000000000000000000000000000000000000000000000000 + d00e + 0e + ACTIVATED + TRUE + CB{ +[ACTIVATED,1,{ +({00||e4||00||00},OR{SMMAC(13),SMMAC(18),SMMAC(cvc_FlagList_CMS:00800000000000)}), +({00||b0||??||??},OR{AUTCHAT(cvc_FlagList_TI:00002000000000),AND{PWD(87),AUTCHAT(cvc_FlagList_TI:00004000000000)}}), +({00||0e||??||??,80||0e||8e||00,00||d6||??||??,00||d0||??||??},AND{PWD(83),AUTCHAT(cvc_FlagList_TI:00010000000000)}) +}]} + TRUE + TRUE + 19 + 19 + 1039 + + + + + ACTIVATED + CB{ +[ACTIVATED,1,{ +({00||26||00||83,00||28||00||83,00||24||00||83,80||20||00||83,00||2c||00||83,00||2c||01||83,00||20||00||83},ALW) +}], +[DEACTIVATED,??,{ +({00||26||00||83,00||28||00||83,00||24||00||83,80||20||00||83,00||2c||00||83,00||2c||01||83,00||20||00||83},ALW) +}]} + 01 + 03 + FALSE + {(1,INFINITY)} + 1041 + + + + + ACTIVATED + CB{ +[ACTIVATED,1,{ +({00||24||00||87,80||20||00||87,00||2c||00||87,00||2c||01||87,00||20||00||87},ALW) +}]} + 01 + 07 + TRUE + {(1,INFINITY)} + 1542 + + + + + + + CB{ +[ACTIVATED,1,{ +({00||44||00||00,00||04||00||00},OR{PWD(02),AND{PWD(84),AUTCHAT(cvc_FlagList_TI:00001000000000)}}), +({00||ea||00||00,10||ea||00||00},AND{OR{SMMAC(13),SMMAC(18),SMMAC(cvc_FlagList_CMS:00800000000000)},SMCMDENC}) +}], +[DEACTIVATED,??,{ +({00||44||00||00,00||04||00||00},OR{PWD(02),AND{PWD(84),AUTCHAT(cvc_FlagList_TI:00001000000000)}}) +}]} + {d27600014408} + ACTIVATED + TRUE + 1043 + + + + + 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + d01b + 1b + ACTIVATED + TRUE + CB{ +[ACTIVATED,1,{ +({00||e4||00||00},OR{SMMAC(13),SMMAC(18),SMMAC(cvc_FlagList_CMS:00800000000000)}), +({00||b0||??||??},OR{AND{PWD(88),AUTCHAT(cvc_FlagList_TI:00000200000000)},AUTCHAT(cvc_FlagList_TI:00000100000000),PWD(02)}), +({00||0e||??||??,80||0e||9b||00,00||d6||??||??,00||d0||??||??},AND{PWD(84),AUTCHAT(cvc_FlagList_TI:00000800000000)}) +}]} + FALSE + TRUE + 06bd + 06bd + 1044 + + + + + 00000000000000000000000000000000000000000000000000 + d018 + 18 + ACTIVATED + TRUE + CB{ +[ACTIVATED,1,{ +({00||e4||00||00},OR{SMMAC(13),SMMAC(18),SMMAC(cvc_FlagList_CMS:00800000000000)}), +({00||b0||??||??},OR{AND{PWD(88),AUTCHAT(cvc_FlagList_TI:00000200000000)},AUTCHAT(cvc_FlagList_TI:00000100000000),PWD(02)}), +({00||0e||??||??,80||0e||98||00,00||d6||??||??,00||d0||??||??},AND{PWD(84),AUTCHAT(cvc_FlagList_TI:00000800000000)}) +}]} + TRUE + TRUE + 19 + 19 + 1045 + + + + + ACTIVATED + CB{ +[ACTIVATED,1,{ +({00||26||00||84,00||28||00||84,00||24||00||84,80||20||00||84,00||2c||00||84,00||2c||01||84,00||20||00||84},ALW) +}], +[DEACTIVATED,??,{ +({00||26||00||84,00||28||00||84,00||24||00||84,80||20||00||84,00||2c||00||84,00||2c||01||84,00||20||00||84},ALW) +}]} + 01 + 04 + FALSE + {(1,INFINITY)} + 1047 + + + + + ACTIVATED + CB{ +[ACTIVATED,1,{ +({00||24||00||88,80||20||00||88,00||2c||00||88,00||2c||01||88,00||20||00||88},ALW) +}]} + 01 + 08 + TRUE + {(1,INFINITY)} + 1131 + + + + + + + CB{ +[ACTIVATED,1,{ +({00||44||00||00,00||04||00||00},OR{PWD(02),AND{PWD(85),AUTCHAT(cvc_FlagList_TI:00000000010000)}}), +({00||ea||00||00,10||ea||00||00},AND{OR{SMMAC(13),SMMAC(18),SMMAC(cvc_FlagList_CMS:00800000000000)},SMCMDENC}) +}], +[DEACTIVATED,??,{ +({00||44||00||00,00||04||00||00},OR{PWD(02),AND{PWD(85),AUTCHAT(cvc_FlagList_TI:00000000010000)}}) +}]} + {d2760001440a} + ACTIVATED + TRUE + 1048 + + + + + d013 + 13 + ACTIVATED + TRUE + CB{ +[ACTIVATED,1,{ +({00||e2||00||00,00||e2||00||98,00||0c||??||??,80||0c||??||??,00||b2||??||??,00||a2||??||??,00||dc||??||??},OR{PWD(02),AND{PWD(85),AUTCHAT(cvc_FlagList_TI:00000000008000)}}) +}]} + TRUE + TRUE + 14 + 3c + TRUE + 0258 + 1049 + + + + ACTIVATED + 000000e164f0467ffe5d379d0b8bb7cb23230263ada3508540508399db7c06aa873a3d + + + ACTIVATED + 000000e164f0467ffe5d379d0b8bb7cb23230263ada3508540508399db7c06aa873a3d + + + ACTIVATED + 000000e164f0467ffe5d379d0b8bb7cb23230263ada3508540508399db7c06aa873a3d + + + ACTIVATED + 000000e164f0467ffe5d379d0b8bb7cb23230263ada3508540508399db7c06aa873a3d + + + ACTIVATED + 000000e164f0467ffe5d379d0b8bb7cb23230263ada3508540508399db7c06aa873a3d + + + ACTIVATED + 000000e164f0467ffe5d379d0b8bb7cb23230263ada3508540508399db7c06aa873a3d + + + ACTIVATED + 000000e164f0467ffe5d379d0b8bb7cb23230263ada3508540508399db7c06aa873a3d + + + ACTIVATED + 000000e164f0467ffe5d379d0b8bb7cb23230263ada3508540508399db7c06aa873a3d + + + ACTIVATED + 000000e164f0467ffe5d379d0b8bb7cb23230263ada3508540508399db7c06aa873a3d + + + ACTIVATED + 000000e164f0467ffe5d379d0b8bb7cb23230263ada3508540508399db7c06aa873a3d + + + ACTIVATED + 000000e164f0467ffe5d379d0b8bb7cb23230263ada3508540508399db7c06aa873a3d + + + ACTIVATED + 000000e164f0467ffe5d379d0b8bb7cb23230263ada3508540508399db7c06aa873a3d + + + ACTIVATED + 000000e164f0467ffe5d379d0b8bb7cb23230263ada3508540508399db7c06aa873a3d + + + ACTIVATED + 000000e164f0467ffe5d379d0b8bb7cb23230263ada3508540508399db7c06aa873a3d + + + ACTIVATED + 000000e164f0467ffe5d379d0b8bb7cb23230263ada3508540508399db7c06aa873a3d + + + ACTIVATED + 000000e164f0467ffe5d379d0b8bb7cb23230263ada3508540508399db7c06aa873a3d + + + ACTIVATED + 000000e164f0467ffe5d379d0b8bb7cb23230263ada3508540508399db7c06aa873a3d + + + + + + d01a + 1a + ACTIVATED + TRUE + CB{ +[ACTIVATED,1,{ +({00||e2||00||00,00||e2||00||d0,00||0c||??||??,80||0c||??||??,00||b2||??||??,00||a2||??||??,00||dc||??||??},OR{PWD(02),AND{PWD(85),AUTCHAT(cvc_FlagList_TI:00000000008000)}}) +}]} + TRUE + TRUE + 14 + 3c + TRUE + 04b0 + 1050 + + + + ACTIVATED + 000000e164f0467ffe5d379d0b8bb7cb232302ecd446eee98852d785614ef5f0acdb23 + + + ACTIVATED + 000000e164f0467ffe5d379d0b8bb7cb232302ecd446eee98852d785614ef5f0acdb23 + + + ACTIVATED + 000000e164f0467ffe5d379d0b8bb7cb232302ecd446eee98852d785614ef5f0acdb23 + + + ACTIVATED + 000000e164f0467ffe5d379d0b8bb7cb232302ecd446eee98852d785614ef5f0acdb23 + + + ACTIVATED + 000000e164f0467ffe5d379d0b8bb7cb232302ecd446eee98852d785614ef5f0acdb23 + + + ACTIVATED + 000000e164f0467ffe5d379d0b8bb7cb232302ecd446eee98852d785614ef5f0acdb23 + + + ACTIVATED + 000000e164f0467ffe5d379d0b8bb7cb232302ecd446eee98852d785614ef5f0acdb23 + + + ACTIVATED + 000000e164f0467ffe5d379d0b8bb7cb232302ecd446eee98852d785614ef5f0acdb23 + + + ACTIVATED + 000000e164f0467ffe5d379d0b8bb7cb232302ecd446eee98852d785614ef5f0acdb23 + + + ACTIVATED + 000000e164f0467ffe5d379d0b8bb7cb232302ecd446eee98852d785614ef5f0acdb23 + + + ACTIVATED + 000000e164f0467ffe5d379d0b8bb7cb232302ecd446eee98852d785614ef5f0acdb23 + + + ACTIVATED + 000000e164f0467ffe5d379d0b8bb7cb232302ecd446eee98852d785614ef5f0acdb23 + + + ACTIVATED + 000000e164f0467ffe5d379d0b8bb7cb232302ecd446eee98852d785614ef5f0acdb23 + + + ACTIVATED + 000000e164f0467ffe5d379d0b8bb7cb232302ecd446eee98852d785614ef5f0acdb23 + + + ACTIVATED + 000000e164f0467ffe5d379d0b8bb7cb232302ecd446eee98852d785614ef5f0acdb23 + + + ACTIVATED + 000000e164f0467ffe5d379d0b8bb7cb232302ecd446eee98852d785614ef5f0acdb23 + + + ACTIVATED + 000000e164f0467ffe5d379d0b8bb7cb232302ecd446eee98852d785614ef5f0acdb23 + + + + + + ACTIVATED + CB{ +[ACTIVATED,1,{ +({00||26||00||85,00||28||00||85,00||24||00||85,80||20||00||85,00||2c||00||85,00||2c||01||85,00||20||00||85},ALW) +}], +[DEACTIVATED,??,{ +({00||26||00||85,00||28||00||85,00||24||00||85,80||20||00||85,00||2c||00||85,00||2c||01||85,00||20||00||85},ALW) +}]} + 01 + 05 + TRUE + {(1,INFINITY)} + 1101 + + + + + + + CB{ +[ACTIVATED,1,{ +({00||44||00||00,00||04||00||00},OR{PWD(02),AND{PWD(89),AUTCHAT(cvc_FlagList_TI:00000000000800)}}), +({00||ea||00||00,10||ea||00||00},AND{OR{SMMAC(13),SMMAC(18),SMMAC(cvc_FlagList_CMS:00800000000000)},SMCMDENC}) +}], +[DEACTIVATED,??,{ +({00||44||00||00,00||04||00||00},OR{PWD(02),AND{PWD(89),AUTCHAT(cvc_FlagList_TI:00000000000800)}}) +}]} + {d2760001440b} + ACTIVATED + TRUE + 3048 + + + + + 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + e001 + 01 + ACTIVATED + TRUE + CB{ +[ACTIVATED,1,{ +({00||e4||00||00},OR{SMMAC(13),SMMAC(18),SMMAC(cvc_FlagList_CMS:00800000000000)}), +({00||b0||??||??},OR{AUTCHAT(cvc_FlagList_TI:00000000002000),AND{PWD(89),AUTCHAT(cvc_FlagList_TI:00000000004000)},PWD(02)}), +({00||0e||??||??,80||0e||81||00,00||d6||??||??,00||d0||??||??},AND{PWD(89),AUTCHAT(cvc_FlagList_TI:00000000001000)}) +}]} + FALSE + TRUE + 1b58 + 1b58 + 3045 + + + + + 00000000000000000000000000000000000000000000000000 + e002 + 02 + ACTIVATED + TRUE + CB{ +[ACTIVATED,1,{ +({00||e4||00||00},OR{SMMAC(13),SMMAC(18),SMMAC(cvc_FlagList_CMS:00800000000000)}), +({00||b0||??||??},OR{AUTCHAT(cvc_FlagList_TI:00000000002000),AND{PWD(89),AUTCHAT(cvc_FlagList_TI:00000000004000)},PWD(02)}), +({00||0e||??||??,80||0e||82||00,00||d6||??||??,00||d0||??||??},AND{PWD(89),AUTCHAT(cvc_FlagList_TI:00000000001000)}) +}]} + TRUE + TRUE + 19 + 19 + 3145 + + + + + ACTIVATED + CB{ +[ACTIVATED,1,{ +({00||24||00||89,80||20||00||89,00||2c||00||89,00||2c||01||89,00||20||00||89},ALW) +}], +[DEACTIVATED,??,{ +({00||24||00||89,80||20||00||89,00||2c||00||89,00||2c||01||89,00||20||00||89},ALW) +}]} + 01 + 09 + TRUE + {(1,INFINITY)} + 3484 + + + + + + + d005 + 05 + ACTIVATED + TRUE + CB{ +[ACTIVATED,1,{ +({00||08||??||??,00||06||??||??},OR{PWD(02),AND{PWD(01),AUTCHAT(cvc_FlagList_TI:00000080000000)}}), +({00||b2||??||??,00||a2||??||??},OR{PWD(02),AND{PWD(01),AUTCHAT(cvc_FlagList_TI:00000040000000)}}), +({00||dc||??||??},AND{PWD(01),AUTCHAT(cvc_FlagList_TI:00000010000000)}), +({00||0c||??||??,80||0c||??||??},AND{PWD(01),AUTCHAT(cvc_FlagList_TI:00000040000000)}) +}]} + TRUE + TRUE + 0a + 45 + TRUE + 1027 + + + + ACTIVATED + 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + + + ACTIVATED + 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + + + ACTIVATED + 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + + + ACTIVATED + 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + + + ACTIVATED + 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + + + ACTIVATED + 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + + + ACTIVATED + 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + + + ACTIVATED + 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + + + ACTIVATED + 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + + + ACTIVATED + 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + + + + + + 00ec1f8b0800000000000000854f5d6bc24010fc2b61dfcd692160cbdd49b1a508b54283527c9123d9e682974bc96ea2cdaff782829516fa32fb35bbb32367c7ca451d3654d65ec1241e43843eabf3d2170a16e96a349d26f7a3490211b1f1b971b54705df4830d3723ddfbd2065b645ee1937c395cc62c31888013e96afd1fc69b9db3cbfa78bd59b8224be1b0482a4270596f9eb418803c5055686cb7d9ca3f834a2a3bc1a4074810f5a6edbde58d7fa82c20bdc9296e9398ea5b86452fc4142877b2ebb608e1b83056af9884dcf2efc38ac5e0bb935d69b9fb3db4690f97d4bfc6f5e9f00348b38355e010000 + d003 + 03 + ACTIVATED + TRUE + CB{ +[ACTIVATED,1,{ +({00||e4||00||00},OR{SMMAC(13),SMMAC(18),SMMAC(cvc_FlagList_CMS:00800000000000)}), +({00||b0||??||??},OR{PWD(02),AND{PWD(01),AUTCHAT(cvc_FlagList_TI:00000004000000)},AUTCHAT(cvc_FlagList_TI:00000002000000),AND{OR{SMMAC(12),SMMAC(19),SMMAC(cvc_FlagList_CMS:00400000000000)},SMRSPENC}}), +({00||0e||??||??,80||0e||??||??},OR{SMMAC(12),SMMAC(19),SMMAC(cvc_FlagList_CMS:00400000000000)}), +({00||d6||??||??,00||d0||??||??},AND{OR{SMMAC(12),SMMAC(19),SMMAC(cvc_FlagList_CMS:00400000000000)},SMCMDENC}) +}]} + FALSE + TRUE + 0258 + EE + 1028 + + + + + d006 + 06 + ACTIVATED + TRUE + CB{ +[ACTIVATED,1,{ +({00||e2||00||00,00||e2||00||30},OR{AND{PWD(01),AUTCHAT(cvc_FlagList_TI:00000001000000)},AUTCHAT(cvc_FlagList_TI:00000000800000)}), +({00||b2||??||??,00||a2||??||??},OR{PWD(02),AND{PWD(01),AUTCHAT(cvc_FlagList_TI:00000000400000)}}) +}]} + TRUE + TRUE + 32 + 2e + FALSE + 1029 + + + + ACTIVATED + 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + + + ACTIVATED + 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + + + ACTIVATED + 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + + + ACTIVATED + 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + + + ACTIVATED + 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + + + ACTIVATED + 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + + + ACTIVATED + 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + + + ACTIVATED + 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + + + ACTIVATED + 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + + + ACTIVATED + 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + + + ACTIVATED + 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + + + ACTIVATED + 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + + + ACTIVATED + 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + + + ACTIVATED + 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + + + ACTIVATED + 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + + + ACTIVATED + 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + + + ACTIVATED + 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + + + ACTIVATED + 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + + + ACTIVATED + 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + + + ACTIVATED + 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + + + ACTIVATED + 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + + + ACTIVATED + 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + + + ACTIVATED + 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + + + ACTIVATED + 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + + + ACTIVATED + 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + + + ACTIVATED + 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + + + ACTIVATED + 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + + + ACTIVATED + 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + + + ACTIVATED + 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + + + ACTIVATED + 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + + + ACTIVATED + 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + + + ACTIVATED + 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + + + ACTIVATED + 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + + + ACTIVATED + 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + + + ACTIVATED + 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + + + ACTIVATED + 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + + + ACTIVATED + 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + + + ACTIVATED + 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + + + ACTIVATED + 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + + + ACTIVATED + 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + + + ACTIVATED + 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + + + ACTIVATED + 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + + + ACTIVATED + 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + + + ACTIVATED + 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + + + ACTIVATED + 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + + + ACTIVATED + 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + + + ACTIVATED + 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + + + ACTIVATED + 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + + + ACTIVATED + 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + + + ACTIVATED + 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + + + + + + 01871f8b08000000000000008d52db4ec3300cfd952aefd4edc6d886dc20b47299b80c31d8789b426bd68a3445493a2edfce032e97c1100fbc38f6c9b17d6207f79e2a1dacc8bab2368988c3480464b23a2fcd3211e3e9646b30e80db7e29e089c572657ba3694886772624fe2f56871c1a935195d6605cdda327c5a4fcc647373761a8cd2b3c5ece0723a9e9c27a21776da0edcd3b84414de3fec023cba704995f2e57d9813dc2958b9bc6a0dac982f24fea86b3722b318a7f2268ea36ebf33dce920fcbec3777946e211dd36d63b56d554321e76fb51b7d347d88071565ba32a9287c4cf29bd72c148ab2627ef894b7f5ee2b9ca8a772f555a57ea992cc21ae3462e2b34658597f3b6fe3ac2abd29396a90d113e5c9c7aab9c23b39f5be293d5d6ce6b2afd8b2ab4dc8eb67706081b184eac97e92b93755edb3b8436c6535e8cc4795d18c73cad78fa6479872c11e12f18e123e553803c29c91594dd930de6b444f8c2f15835ce3455c5738fa308e147bc667dcb87af69c3e6c6e01fff44be01fe575ab68a020000 + d001 + 01 + ACTIVATED + TRUE + CB{ +[ACTIVATED,1,{ +({00||e4||00||00},OR{SMMAC(13),SMMAC(18),SMMAC(cvc_FlagList_CMS:00800000000000)}), +({00||b0||??||??},ALW), +({00||0e||??||??,80||0e||??||??},OR{SMMAC(12),SMMAC(19),SMMAC(cvc_FlagList_CMS:00400000000000)}), +({00||d6||??||??,00||d0||??||??},AND{OR{SMMAC(12),SMMAC(19),SMMAC(cvc_FlagList_CMS:00400000000000)},SMCMDENC}) +}]} + FALSE + TRUE + 0352 + 0189 + 1030 + + + + + + d01c + 1c + ACTIVATED + TRUE + CB{ +[ACTIVATED,1,{ +({00||e4||00||00},OR{SMMAC(13),SMMAC(18),SMMAC(cvc_FlagList_CMS:00800000000000)}), +({00||b0||??||??,00||0e||??||??,80||0e||??||??,00||d6||??||??,00||d0||??||??},ALW) +}]} + TRUE + TRUE + 012c + 00 + 1031 + + + + + + da0a + 0a + ACTIVATED + TRUE + CB{ +[ACTIVATED,1,{ +({00||e4||00||00},OR{SMMAC(13),SMMAC(18),SMMAC(cvc_FlagList_CMS:00800000000000)}), +({00||b0||??||??,00||0e||??||??,80||0e||??||??,00||d6||??||??,00||d0||??||??},ALW) +}]} + TRUE + TRUE + 0384 + 00 + 1032 + + + + + 30323031353038303330373531303500500200000030000004 + d00c + 0c + ACTIVATED + TRUE + CB{ +[ACTIVATED,1,{ +({00||e4||00||00},OR{SMMAC(13),SMMAC(18),SMMAC(cvc_FlagList_CMS:00800000000000)}), +({00||b0||??||??},ALW), +({00||0e||??||??,80||0e||??||??},OR{SMMAC(12),SMMAC(19),SMMAC(cvc_FlagList_CMS:00400000000000)}), +({00||d6||??||??,00||d0||??||??},AND{OR{SMMAC(12),SMMAC(19),SMMAC(cvc_FlagList_CMS:00400000000000)},SMCMDENC}) +}]} + TRUE + TRUE + 19 + 19 + 1033 + + + + + d00f + 0f + ACTIVATED + TRUE + CB{ +[ACTIVATED,1,{ +({00||e4||00||00},OR{SMMAC(13),SMMAC(18),SMMAC(cvc_FlagList_CMS:00800000000000)}), +({00||b2||??||??},OR{PWD(02),AND{PWD(01),AUTCHAT(cvc_FlagList_TI:00000000100000)},AUTCHAT(cvc_FlagList_TI:00000000080000),AND{OR{SMMAC(13),SMMAC(18),SMMAC(cvc_FlagList_CMS:00800000000000),SMMAC(12),SMMAC(19),SMMAC(cvc_FlagList_CMS:00400000000000)},SMRSPENC}}), +({00||dc||??||??},AND{OR{SMMAC(13),SMMAC(18),SMMAC(cvc_FlagList_CMS:00800000000000),SMMAC(12),SMMAC(19),SMMAC(cvc_FlagList_CMS:00400000000000)},SMCMDENC}) +}]} + TRUE + TRUE + 05 + 0f + TRUE + 1034 + + + + ACTIVATED + 000000000000000000000000000000 + + + ACTIVATED + 000000000000000000000000000000 + + + ACTIVATED + 000000000000000000000000000000 + + + ACTIVATED + 000000000000000000000000000000 + + + ACTIVATED + 000000000000000000000000000000 + + + + + + 000801ae01af029a1f8b0800000000000000bd535d4fc23014fd2b4bdfa5039c6ea62bc18f18a3889188861752d9755b1877a62da8fc7a6f11cd46e6c7932f6dee3d3de79e9ea6a2f7ba28bc1568939718b376cb671ee0ac4c724c6376311aee856110edb503e619ab3051458910b33730ac27c5ddc9b45f14292c2047183b9159067a89a94994057c185c7927a783e9f8ec767431bc8e59d0eab80134124dcc326b9f8f387f312d5250369fb712e04f8aaf4cb2700b5fd17926c597b0055da9dc1833cb96762dc531a439a2ecf8edc00ffdaee0db86b82c0d19b15a41eac8b5720e882422a3280a0e0ec3c817bc11afb30a059880a688409eee30aa98b8560b90db9b7983251dd373650cb4cf2fc7826f50d17fd430cb70c3fa9bd57dbfbb1f1c04ff6f95ffe095efd68d8f34591a65d7393e95a656d090da23a3d256762b22db569533ddba21fde986ffe180185659bb89a20f7a6d0b27e0844a9dba2ebd71635f4c5486ea1bc6b79818d134fa3804823ea6857047686abb1b2a2c28560b57901b6712d09d6e063e43ad5ee97e7823bba1e06e275b3fc4c177f3e5b5f479fd4ff1df3fb27c07bbc3c89b2a0400001f8b0800000000000000854f5d6bc24010fc2b61dfcd692160cbdd49b1a508b54283527c9123d9e682974bc96ea2cdaff782829516fa32fb35bbb32367c7ca451d3654d65ec1241e43843eabf3d2170a16e96a349d26f7a3490211b1f1b971b54705df4830d3723ddfbd2065b645ee1937c395cc62c31888013e96afd1fc69b9db3cbfa78bd59b8224be1b0482a4270596f9eb418803c5055686cb7d9ca3f834a2a3bc1a4074810f5a6edbde58d7fa82c20bdc9296e9398ea5b86452fc4142877b2ebb608e1b83056af9884dcf2efc38ac5e0bb935d69b9fb3db4690f97d4bfc6f5e9f00348b38355e010000 + d002 + 02 + ACTIVATED + TRUE + CB{ +[ACTIVATED,1,{ +({00||e4||00||00},OR{SMMAC(13),SMMAC(18),SMMAC(cvc_FlagList_CMS:00800000000000)}), +({00||b0||??||??},ALW), +({00||0e||??||??,80||0e||??||??},OR{SMMAC(12),SMMAC(19),SMMAC(cvc_FlagList_CMS:00400000000000)}), +({00||d6||??||??,00||d0||??||??},AND{OR{SMMAC(12),SMMAC(19),SMMAC(cvc_FlagList_CMS:00400000000000)},SMCMDENC}) +}]} + FALSE + TRUE + 04e2 + 029B + 1035 + + + + + d009 + 09 + ACTIVATED + TRUE + CB{ +[ACTIVATED,1,{ +({00||08||??||??,00||06||??||??},OR{PWD(02),AND{PWD(01),AUTCHAT(cvc_FlagList_TI:00000080000000)}}), +({00||b2||??||??,00||a2||??||??,00||dc||??||??},OR{PWD(02),AND{PWD(01),AUTCHAT(cvc_FlagList_TI:00000008000000)}}) +}]} + TRUE + TRUE + 0a + 14 + TRUE + 1036 + + + + ACTIVATED + 0000000000000000000000000000000000000000 + + + ACTIVATED + 0000000000000000000000000000000000000000 + + + ACTIVATED + 0000000000000000000000000000000000000000 + + + ACTIVATED + 0000000000000000000000000000000000000000 + + + ACTIVATED + 0000000000000000000000000000000000000000 + + + ACTIVATED + 0000000000000000000000000000000000000000 + + + ACTIVATED + 0000000000000000000000000000000000000000 + + + ACTIVATED + 0000000000000000000000000000000000000000 + + + ACTIVATED + 0000000000000000000000000000000000000000 + + + ACTIVATED + 0000000000000000000000000000000000000000 + + + + + + + + CB{ +[ACTIVATED,1,{ +({00||ea||00||00,10||ea||00||00},AND{OR{SMMAC(13),SMMAC(18),SMMAC(cvc_FlagList_CMS:00800000000000)},SMCMDENC}) +}]} + {a000000167455349474e} + ACTIVATED + TRUE + 1051 + + + + + 308204E4308203CCA003020102020703922BAC3138FE300D06092A864886F70D01010B0500308183310B3009060355040613024445311F301D060355040A0C1667656D6174696B20476D6248204E4F542D56414C494431323030060355040B0C294B6F6D706F6E656E74656E2D4341206465722054656C656D6174696B696E667261737472756B747572311F301D06035504030C1647454D2E4B4F4D502D43413820544553542D4F4E4C59301E170D3135303830343131303130305A170D3137303830343131303130305A3081D6310B300906035504061302444531293027060355040A0C2067656D6174696B204D75737465726B6173736531474B564E4F542D56414C494431133011060355040B0C0A5831313033373239363231123010060355040B0C093939393536373839303112301006035504040C0944616C6C6D61796572311C301A060355042A0C1346656C69636974617320436C61756465747465310C300A060355040C0C0344722E3133303106035504030C2A44722E2046656C69636974617320436C617564657474652044616C6C6D61796572544553542D4F4E4C5930820122300D06092A864886F70D01010105000382010F003082010A02820101008D5440DF21B945CCA91F7A4988D1D80C9B7FE6C0503D8E098B5B56DD8CDEA3513652B3674C043F7680643603C46A91153BC80791E4A70FF42D969CCC0DAA516945F82430FC8011F3E8A19A29038DC8AEFF1A9A251BDC1C312508F1BF1378DEDBC6E3470939C141E70158FFE4A98708C1E074C028F448F66EB5903FA4BD09618CEF18D529CCCB28CFE8FF58B0CFD0FB1827D7CB310A8E2F88AE365996837A903CDD9E66EF74747465D43A33C4076692CE114B2C37C66D7373842C8566B1729557F2B067F578F9A172CEA11CC1D690B988058BE8B3663B1C90FB7D74C05BBD3941671662F23ACB68036DA0DEB39B23BCF4DD5CC136359CAFAF2F383E4B913CD5E70203010001A382010630820102303006052B240803030427302530233021301F301D30100C0E56657273696368657274652F2D72300906072A8214004C043130200603551D2004193017300A06082A8214004C048123300906072A8214004C0446300E0603551D0F0101FF040403020780304B06082B06010505070101043F303D303B06082B06010505073001862F687474703A2F2F6F6373702E706B692E74656C656D6174696B2D746573743A383038302F434D4F4353502F4F435350301D0603551D0E041604143BA4687F78DF0CB0B0DF77CA191A788890F517EE301F0603551D2304183016801425306D18D53CB141690A977A4375E9951601A6D2300F0603551D130101FF04053003010100300D06092A864886F70D01010B0500038201010053AE709C9F1509431C37417D0A0BADA500EB84C5D8ADAA98BD17A74A0858EC2A16DDB2584712980642CF39D562E43D8E05F1D79074A631B157FEE88DC01267E219C412F6AB42BB8AA06AF3212BC286E7D764A4C3706C0A274E881191CD9B3624A0EADBD4986E71866CF0A52A68567748C8614A17C1E473E7BC3AAB22C8BDF38930BE2269854F7A7BF1928B199B4E4D4664628B5AF86515C87ADB809F91B954A7F93B6C2B50AA30E6406C52EBF3C03559B265AB5961BAF151B810D8C575CE4CDEF59977BAD3752897B26CEDE101F24161B5098153341F3F12DB07069656539119CA271D0496A884242E84A379D37F212CA9923D889ACCCEB7711235A71A480760 + c500 + 01 + ACTIVATED + TRUE + CB{ +[ACTIVATED,1,{ +({00||e4||00||00,00||0e||??||??,80||0e||??||??},OR{SMMAC(13),SMMAC(18),SMMAC(cvc_FlagList_CMS:00800000000000)}), +({00||d6||??||??,00||d0||??||??},AND{OR{SMMAC(13),SMMAC(18),SMMAC(cvc_FlagList_CMS:00800000000000)},SMCMDENC}), +({00||b0||??||??},ALW) +}]} + TRUE + FALSE + 076c + 04E8 + 1052 + + + + + 308204953082037DA00302010202064383FC9118CC300D06092A864886F70D01010B0500308183310B3009060355040613024445311F301D060355040A0C1667656D6174696B20476D6248204E4F542D56414C494431323030060355040B0C294B6F6D706F6E656E74656E2D4341206465722054656C656D6174696B696E667261737472756B747572311F301D06035504030C1647454D2E4B4F4D502D43413820544553542D4F4E4C59301E170D3135303830343131303130305A170D3137303830343131303130305A3074310B300906035504061302444531293027060355040A0C2067656D6174696B204D75737465726B6173736531474B564E4F542D56414C494431123010060355040B0C093939393536373839303126302406035504030C1D3038384637313938393937383530303741354533544553542D4F4E4C5930820122300D06092A864886F70D01010105000382010F003082010A0282010100CBC5BFFBE07F4A97FED1FBFE6DA19FBCF517663DB7C9E8C0C63A470ACD4259BADA41767C81F00E009C8ABC4F077E47E91E56523BED0FEEBC6849945F5100CDB3319E298C122414D21A5B848B638DB35F1956320A3A5D85002BAB5EE9BF2301A4FC6268E42936CF83F1A5E5F8DC1E4B1A9002F13846CBC78FF9CD95A22C9C59F7F4BF30444773109A1326BC1CEAE5ACAA2A3553FFAE3CE7FCE146553B446BAD68C328646A99904E53E7ECC5DDECE67743076B525A5DD42DC99708241E1438A5BC5477D056FC9112CA6FA34CC80C90F5D692DF62E7D234EA417DEB878864D486E78E64BC2C6F969D2A587611821871590B99B3DE292E3A0B3C548F312D7ED781E10203010001A382011B30820117303006052B240803030427302530233021301F301D30100C0E56657273696368657274652F2D72300906072A8214004C043130200603551D2004193017300A06082A8214004C048123300906072A8214004C0447300E0603551D0F0101FF04040302078030130603551D25040C300A06082B06010505070302304B06082B06010505070101043F303D303B06082B06010505073001862F687474703A2F2F6F6373702E706B692E74656C656D6174696B2D746573743A383038302F434D4F4353502F4F435350301D0603551D0E041604140CF1F6A2AF44EE4F1664732B1A85C5CCC67657EF301F0603551D2304183016801425306D18D53CB141690A977A4375E9951601A6D2300F0603551D130101FF04053003010100300D06092A864886F70D01010B050003820101004306A007A52BD40C3ED32608185A9B20D8147167709C3EC6A0C913D96FD32AED4C16766DD4FD29946C7E41AD0E54B809284EC1D13CC3123FEAECE17A57DA252A89F95F9E09366DD0DEC99285A5BF4EF2FD4F364F9A2C9B0500161BFDDF00C7678446F19D7EB5E79AF8CB752A202D20F3720FD85C05EECF8217D803FFFE93CAE16DF2334B77D7D14205797A2968F609CD6EEB42233F20D2A63AB15041D34EDC1102D1FC71FBCB8A680D845436B14D31F4FC2162329667C90AE515229B7CC606048EA0747FA28FFB136A4F57E9CBC65A11823E54F764FF0DB2C54402F30972F8F4E2A9BACC6C1FCD2319AFA7247E2A2B5549ABD1C415D13123B49C3B77212EF668 + c509 + 09 + ACTIVATED + TRUE + CB{ +[ACTIVATED,1,{ +({00||e4||00||00,00||0e||??||??,80||0e||??||??},OR{SMMAC(13),SMMAC(18),SMMAC(cvc_FlagList_CMS:00800000000000)}), +({00||d6||??||??,00||d0||??||??},AND{OR{SMMAC(13),SMMAC(18),SMMAC(cvc_FlagList_CMS:00800000000000)},SMCMDENC}), +({00||b0||??||??},OR{PWD(02),AND{PWD(01),AUTCHAT(cvc_FlagList_TI:00800000000000)},AUTCHAT(cvc_FlagList_TI:00400000000000),AND{OR{SMMAC(13),SMMAC(18),SMMAC(cvc_FlagList_CMS:00800000000000)},SMRSPENC}}) +}]} + TRUE + FALSE + 076c + 0499 + 1054 + + + + + 308204E4308203CCA0030201020207010FFBA746E3A0300D06092A864886F70D01010B0500308183310B3009060355040613024445311F301D060355040A0C1667656D6174696B20476D6248204E4F542D56414C494431323030060355040B0C294B6F6D706F6E656E74656E2D4341206465722054656C656D6174696B696E667261737472756B747572311F301D06035504030C1647454D2E4B4F4D502D43413820544553542D4F4E4C59301E170D3135303830343131303130305A170D3137303830343131303130305A3081D6310B300906035504061302444531293027060355040A0C2067656D6174696B204D75737465726B6173736531474B564E4F542D56414C494431133011060355040B0C0A5831313033373239363231123010060355040B0C093939393536373839303112301006035504040C0944616C6C6D61796572311C301A060355042A0C1346656C69636974617320436C61756465747465310C300A060355040C0C0344722E3133303106035504030C2A44722E2046656C69636974617320436C617564657474652044616C6C6D61796572544553542D4F4E4C5930820122300D06092A864886F70D01010105000382010F003082010A0282010100B30F9CD63F557AFE66E1FF2D31830F94CE433C950D9F30D06D90E548E107A9816307B678542E3E21DD27A4DA7033B80F6BBE99B05EB9F6D3919E04364ABCEB9205B3E5AC80FE18B40411DF8E615FCB4EFC81355812168462979AAB6332BF31FDA0156754B6614A7069DD291CFEBC6D13AF94B30CBBFE8602B767C2AF913C3A61C65E6916CBC7CFA2069527D9A4077CC5F8D425A2129A0A768CC73BAAAFF66608D2412EF538F554C37417428FB40656E2A5D716E3E7328DBD63704266CDDC3AB3EC373D01B7B25F61376105371294D4D37E44C705AD7974A856CD66F891E6E12D706D736EB7762EA76507375F050C03A3B806C16E35F3599E4AB2D34DCB3EC7630203010001A382010630820102303006052B240803030427302530233021301F301D30100C0E56657273696368657274652F2D72300906072A8214004C043130200603551D2004193017300A06082A8214004C048123300906072A8214004C0444300E0603551D0F0101FF040403020430304B06082B06010505070101043F303D303B06082B06010505073001862F687474703A2F2F6F6373702E706B692E74656C656D6174696B2D746573743A383038302F434D4F4353502F4F435350301D0603551D0E04160414E19A0E7FB7A505802951776A6625E2E50777FD75301F0603551D2304183016801425306D18D53CB141690A977A4375E9951601A6D2300F0603551D130101FF04053003010100300D06092A864886F70D01010B05000382010100198AA5AFA5BBA1F18AA8829D45BBB07B2D03E02250DC4658E84432A53AEBD0C62BA0E11F0494136659980208227FAD5E686D4C14F7148C5ACB17229B20F1B47D1A71251AE49C34E727C89128B71B9D31E52A8D785C563DD53C90A6CAEC1AB052D7F263967B41026E031689BFC5798C15A226086001517B5DB8FB49BDCFF7F0E62450CA4F783BBE624284C06EDA176978D1AA1E2DA9588893B658EE91D026DB315197F42F2B877389988A54A701EA27F578197611A1EEF0A338F81CB36163337636623183ECA6996B2D7BDFF16B0F262EF121DE1B363CB1F2D08DBC7385C64D25EDE88C1E7AF551214411986DBC2883F98DDE7DC4B565EA288553BD4798AC1673 + c200 + 02 + ACTIVATED + TRUE + CB{ +[ACTIVATED,1,{ +({00||b0||??||??},ALW) +}]} + TRUE + FALSE + 076c + 04E8 + 1056 + + + + + 3082048130820369A003020102020700BD187102B07C300D06092A864886F70D01010B0500308183310B3009060355040613024445311F301D060355040A0C1667656D6174696B20476D6248204E4F542D56414C494431323030060355040B0C294B6F6D706F6E656E74656E2D4341206465722054656C656D6174696B696E667261737472756B747572311F301D06035504030C1647454D2E4B4F4D502D43413820544553542D4F4E4C59301E170D3135303830343131303130305A170D3137303830343131303130305A3074310B300906035504061302444531293027060355040A0C2067656D6174696B204D75737465726B6173736531474B564E4F542D56414C494431123010060355040B0C093939393536373839303126302406035504030C1D3038384637313938393937383530303741354533544553542D4F4E4C5930820122300D06092A864886F70D01010105000382010F003082010A0282010100BA3C03B1C1DFC9CAE48471F5BF1178F783984DBACEB37EB73DAF5BFAC803990C6D04FCC0EC962D4CDE2A3EFF2CEE24F80FA3BA1F117E4480BFE293C6005477941B6F4F06EE2EB94F61EA80F8FA5E4C9B44FF2905415EB401AE9519FD8D9562385477077D99CEAF9073BB1209ED4D14895284F2F9BE621522001C45891F1C88C64029A772A5B6FB15845AA22314651DDEFBD980ABBDE75036BC763677133CB36F6E1389DB1E0F5061FCC5ACDDD0A7B2CA7C085B54D334E4862D043198BA9E3A98A80D3AF68249953A8D72255B5CBF13266DB8FFEDBD30CB559162A5622AC7CFB39C0A54A467CBBBBD7E4CD626A78A5EFF685116299051FB727CECF8C443D1CA650203010001A382010630820102303006052B240803030427302530233021301F301D30100C0E56657273696368657274652F2D72300906072A8214004C043130200603551D2004193017300A06082A8214004C048123300906072A8214004C0445300E0603551D0F0101FF040403020430304B06082B06010505070101043F303D303B06082B06010505073001862F687474703A2F2F6F6373702E706B692E74656C656D6174696B2D746573743A383038302F434D4F4353502F4F435350301D0603551D0E04160414254FD70D5B3EF1FC5C3FA21539C8CACE580C9064301F0603551D2304183016801425306D18D53CB141690A977A4375E9951601A6D2300F0603551D130101FF04053003010100300D06092A864886F70D01010B05000382010100C1117D858058CE1D11D6F786494F6835F06CB87782224EDD81D51D822F758B1314F0757E8A7695605E2A48621CC872A9F590F00DDA3734275390B4D5C10DF55F5763C9AEE153383584CE13018ED6138F584AD5D87EE7F446A5AE46213957713CFFEA19EB55A7C71816F63D64B0135FBEF318292D3B2DB9570A6A00BB9CF31780A3960B984A36AB1E19273674A3E3CBC19276B29834B973D98B1EA2023BB71E87291BD2D31DCCAB81DB062B90CCA68DEC3524ACB15B0CA9F809FBDBE33D61BF03FFDB95247CB8B5A008D72DB0CFA3CBD956BAC421C0883AE11AC5EB38E42246923F192169626464B869AC49B09F8AD7EDC38FC6BE3DC067880DB0ED0B3BE3D43F + c50a + 0a + ACTIVATED + TRUE + CB{ +[ACTIVATED,1,{ +({00||e4||00||00,00||0e||??||??,80||0e||??||??},OR{SMMAC(13),SMMAC(18),SMMAC(cvc_FlagList_CMS:00800000000000)}), +({00||d6||??||??,00||d0||??||??},AND{OR{SMMAC(13),SMMAC(18),SMMAC(cvc_FlagList_CMS:00800000000000)},SMCMDENC}), +({00||b0||??||??},OR{PWD(02),AND{PWD(01),AUTCHAT(cvc_FlagList_TI:00200000000000)},AUTCHAT(cvc_FlagList_TI:00100000000000),AND{OR{SMMAC(13),SMMAC(18),SMMAC(cvc_FlagList_CMS:00800000000000)},SMRSPENC}}) +}]} + TRUE + FALSE + 076c + 0485 + 1059 + + + + + 02 + ACTIVATED + CB{ +[ACTIVATED,1,{ +({00||88||00||00,00||2a||9e||9a,00||2a||9e||ac},OR{PWD(02),AND{PWD(01),AUTCHAT(cvc_FlagList_TI:00080000000000)}}), +({00||46||81||00,00||46||81||82},ALW), +({00||e4||20||82},OR{SMMAC(13),SMMAC(18),SMMAC(cvc_FlagList_CMS:00800000000000)}) +}]} + 0800 + 8D5440DF21B945CCA91F7A4988D1D80C9B7FE6C0503D8E098B5B56DD8CDEA3513652B3674C043F7680643603C46A91153BC80791E4A70FF42D969CCC0DAA516945F82430FC8011F3E8A19A29038DC8AEFF1A9A251BDC1C312508F1BF1378DEDBC6E3470939C141E70158FFE4A98708C1E074C028F448F66EB5903FA4BD09618CEF18D529CCCB28CFE8FF58B0CFD0FB1827D7CB310A8E2F88AE365996837A903CDD9E66EF74747465D43A33C4076692CE114B2C37C66D7373842C8566B1729557F2B067F578F9A172CEA11CC1D690B988058BE8B3663B1C90FB7D74C05BBD3941671662F23ACB68036DA0DEB39B23BCF4DD5CC136359CAFAF2F383E4B913CD5E7 + 010001 + 42F94758B631876B4A46197C59732010316C761C72AA08F26AF0D9045AAA72F89C66AA8FEC0D2349F3E40958D5AEAE9C425D338126BB28AB4D234FA0BF6513F97067FC369EA1CE6028C0D43E5569CE4D67A4E2A16D476CB0B95D38BA94EEB5A5AEE5AB972AA073AB960EE80D236D537014FF1EC509A6BDE98EEF11C9EEAF50637546B05B47DBE4B8FFE6466A7AF176AAB7BDDEAF23FC76A0A7903488D77A68FC6C7E4F31AD14B4B35AAB938DCBC51C70648E047A86C94B19EA38968ACBAF57A196F744F772961590C074EB9B0DE4D25997E192CD5300F57089F361F12ABA63F109B4CEB654465B5760782FF9B5A3DCE578EEEFCF40918BF1916C785F1B0ABB49 + AE9FB17BAB0ABC1691D3F5C0D12F37D780E6F3F791E5C26BBE35CEABBFA8C8A0563F797B0689DFACEB6461E725C00DF660D4CB78315FEC9577EB451C7139186841E60586D0E72F723CAB246F7E1D795B8650F28095B000FB01B846002D07BE2B61D051710BE4D476EACE5A72D8EDDBEEA14CD44FC50564ADCDBDCBD851DC3015 + CF309047E075492A3AF188FF3B9AEA83140E39223885EA95EAC6FB4ACFA9955F4E04D3B005F8593107C57D1D49F2E126950D261007E4FF53D838B4874354BC8A0483D36538DAB6B9863BDE8DF65C51204556C8BD5CEF2C4A45031CCB0A84984763E96C4206B1C24BEDED1037E8AF0329E94CCF43ED81740BBF50B4E87337F10B + 13E3FACA746427A2867FD7495C4A7D98DD84F11B2D1237C0200D6EFA1F3DB18499EE66FEFD72ACF8BC6355C7878445D2DF9ABD8676514FD882AD58D4F18CA85C0FCD8CA99B9809CE805C9A2CDCF7AC80215F8D0FDA7D0ECF88959DDB9D457982E5845E127B615856274ED3FCAAFB05073C764CE4BD336D116313106A1680F735 + 4D08C26C6711549DC602AE2C2FCE3EA973D881F7AE4A64594F4CA27C434FCB40FF321E3F11493068617A5535819C338873DCCAAD25324898B509085E4E73801254F16AB4F4F9A4FCBFE31CB16DCB0F42CF6520080038D11FE01EF322AF0B73CEFF5FF7A768F3C8C910729718228487C99A7BBB8887131DC18C65868DF2E0F6D7 + 400D66D571EA98860C7777F06C0E3EA17C6420E1ABD7F88A0B46497D94F1C2B06BA925834B3D4C412C5B9E62819023BF0D504637E513A43F081DDAC0531ECE777220FFC81A65BBA75C0D7B3608F6ABAA5DCCA9911DB1DD2C0FC835AF8BE566C2D3F4E22B5CDEBCD37F90587DD633747D90460106132E8EE1C3BB5EE678C4FAC1 + {[1,(rsaClientAuthentication,sign9796_2_DS2,signPKCS1_V1_5,signPSS)]} + TRUE + 1061 + + + + + 06 + ACTIVATED + CB{ +[ACTIVATED,1,{ +({00||88||00||00,00||2a||9e||9a,00||2a||9e||ac},OR{PWD(02),AND{PWD(01),AUTCHAT(cvc_FlagList_TI:00800000000000)},AUTCHAT(cvc_FlagList_TI:00400000000000)}), +({00||46||81||00,00||46||81||86},ALW), +({00||e4||20||86},OR{SMMAC(13),SMMAC(18),SMMAC(cvc_FlagList_CMS:00800000000000)}) +}]} + 0800 + CBC5BFFBE07F4A97FED1FBFE6DA19FBCF517663DB7C9E8C0C63A470ACD4259BADA41767C81F00E009C8ABC4F077E47E91E56523BED0FEEBC6849945F5100CDB3319E298C122414D21A5B848B638DB35F1956320A3A5D85002BAB5EE9BF2301A4FC6268E42936CF83F1A5E5F8DC1E4B1A9002F13846CBC78FF9CD95A22C9C59F7F4BF30444773109A1326BC1CEAE5ACAA2A3553FFAE3CE7FCE146553B446BAD68C328646A99904E53E7ECC5DDECE67743076B525A5DD42DC99708241E1438A5BC5477D056FC9112CA6FA34CC80C90F5D692DF62E7D234EA417DEB878864D486E78E64BC2C6F969D2A587611821871590B99B3DE292E3A0B3C548F312D7ED781E1 + 010001 + 82809F37BCCB49069717FC7F31CF34F25B35253199A721FD73F696D1002BE2339CDC17FA1D6D944A27F7622A6AEE2137D74A09587FB6987AE97F561AC551F26B34F7CA3BFED244D35A360A690AD5116F725695AD9F3B8D9652616A63E119965007A32EF210C31D9BAF03448960CFB5E1C92159436573D4D70C70F1C7EF32231B590D7171F840C6D81B2E5828EA9A5F875D3E2A95D3DC3F7EB3E610AB9B0529B1EFB19A1238708111006149F7CA21D5FE4E17F9D6A792064A0CD2BB16DE017FCFD41F99447D7DD34EA0B46F0D0F4DEAE1C72917C103BF498E69E1B7B25354A8756BEDE43F06B062390FF1475E352363D8B217D73F0CB6CE2333356F5708306511 + D7FB97662A88B058BBB3F4F776C9FD90C437FAD5A171E15214C8B5E7A76CA3B91C195499F93F3790FA6EFB80385141225B2E135EED4E7BA267AE589695F717A50C851E407774844F0AC55249C446031FD2491B68AC46B1613999ECB39DE077DC9D97B660E4D9952B7B92D349B3CCDFDE692E49E97632D0C0F8D4535478AB0463 + F18700ECE3268B87D013E07362C41BFF6F5F8C53442FBDDF4E2840C6F717298DED599BE1656DFD8CC80D545362802E261CE44510C10DA677624FD12DFF5D295F025EE38A63D1D2B1A1031051D737C86F737FAB70708F4F1DAD978AC0CD41088418479E19EFCB973F485E16557EF513640C0B703ED0FFEA9199B1EBF24D7109EB + 19296B5AF0AB99F7CC6E4BA4A4C7256E3F1DD2701EEDD8752A8CB37C7869D4AD1513F26239C25EA3DA3921BDAF51F007A39DBB8DFC917F1FCD7A6741ABD8EC7D42F7232E197C8E8972D4C82065E84E26DFE5BA76B8534808EE9FFB0E75DF17B7B0F862BBE90D5C2E83A7F84B86D1E066D5D419B2441DE96A01D3229E1DACB6C7 + B360A1B64D69961D32D3605231DB16341A622B14B84280D0B4FA3E49C6BF44146D5FACDEB47700E52ABA83933E47967EA5DC7ED2D79E2CB0E3AA05E01494FB21DDDFDD3C2DB06ABB93AA73D76470C082CD93D71EB5EA29471062C921320F87A49B67AD2AF4260F596784C12F940FADEC12E9F7DE1F58C1BC8B1A51F2EDC2F32B + 2CAA534363EB2A3F88AC6DE6F21B6255ADCC159F8B7FD7ACAF74DC6B8B957D523F9534AA9F385E14F6861C7D055FA3B024E46318176A204A3E27A5935583D549BF50E68D826CAEFC5A90F194F24F84F77CD90537E9A2507FC4E8CEDD13FCE3829B373305AD7F645ABA770B649710797C3A701A29EA5D5343234573AE10502297 + {[1,(rsaClientAuthentication,sign9796_2_DS2,signPSS)]} + TRUE + 1064 + + + + + 03 + ACTIVATED + CB{ +[ACTIVATED,1,{ +({00||2a||80||86,00||2a||86||b8},OR{PWD(02),AND{PWD(01),AUTCHAT(cvc_FlagList_TI:00040000000000)}}), +({00||46||81||83},ALW) +}]} + 0800 + B30F9CD63F557AFE66E1FF2D31830F94CE433C950D9F30D06D90E548E107A9816307B678542E3E21DD27A4DA7033B80F6BBE99B05EB9F6D3919E04364ABCEB9205B3E5AC80FE18B40411DF8E615FCB4EFC81355812168462979AAB6332BF31FDA0156754B6614A7069DD291CFEBC6D13AF94B30CBBFE8602B767C2AF913C3A61C65E6916CBC7CFA2069527D9A4077CC5F8D425A2129A0A768CC73BAAAFF66608D2412EF538F554C37417428FB40656E2A5D716E3E7328DBD63704266CDDC3AB3EC373D01B7B25F61376105371294D4D37E44C705AD7974A856CD66F891E6E12D706D736EB7762EA76507375F050C03A3B806C16E35F3599E4AB2D34DCB3EC763 + 010001 + 19A500C74666CDA8A5BF74365AC2F476515C1BCF1516597D6053C222BFE7C304FED3D9F43DCA29A7DBEE93939D422AF83A6C1FC2BCAE518557739412DA7D58179FAD7615509C1399A48392CAE7733AC0E334F618D8EE54A37226FAA8C859CDA50F4A4174467284A0B8E8ADBCB356F5203EA343496D9B34422B5636F1C21128231EE4672CB2614A6A755A205DDB04783677E3304F4A5DF3DDF99CD170F993901249568A583C1F5AFDF1BF4967CE33D652C9B4B44EA37B3CFA344EB8DE7C3F21C31D8D457B0F731D75D804891D9458E65B7E3B34885451B18565E43F636C49A1E5E154A738712E1C302280FEAD746313C002AB80E6C07390B0549CF077F5DDA5B1 + BD3C80DDC3110A6C2A6CAFDADE56017A6D5CEC87CF732C267C88018D1258B56900D6E3969DC79121053519F3A301E2D0FF489B972069DC8F96D4258ABBD0F273982030AF6D44A4816EED8CCEE2E320B87CE54E750E302E0693CEF91DBF453E98C2A0C241B7959E8C9C3F39E9EA3E8F1CEC611463E96C4CDBA53EDA15B67C5775 + F23C16C725AE1346FEABFEAD90A997CC7F259CA45CDD7E40DBBFB76BCFC964C012A237542CAC49CA57D47D676FE36FCC0B7C96CF89794F7113FD57938B435BD3E732F30063068D688D6B17E7F49AAA1CBC217B6A0858FD8F80F1BD1FBA3813BAB887FFDC4F65229019DD813C820CC880BAA41B0F2BE5FD377498C3CA6D85A077 + 2651D52A92F0A572A7D8A077AAA431E26FB8EC70C7F263935B8E52FA1527FF7C46DE3CF1E7FB5C891A3BD9887B8ECB36552B87CE3F931045C75E284802A65A224C40E07AF59E7BCD7600068E726559DFE1F2B14384DEFEC2F835663EBED7AFC851492A6D1256EAE740509152ABCB85416F206D7799F203524B11022A796C8E6D + 05B5E6EF90F2D69F80D77B2C8A5185339BF7BE069DEDD6D11E9D196CE03C2634E4FB90045AFD40CC155FFC08D9396A644C0D06DD23A78978E7F8BBFCCD76AC0E85CFCCACC0A8E1E28A1AF13855AAE3C1C3A9A2683084308E16831C6B480F945F7D842F42F958300567A6B22A44029B2375C2F2A45BEB9319A0950D60934E6827 + 6F65367B6DBE19A49721E3CD7B2FF6A83A2A78AB1D53711DAD361A0E4267FF4250279D4912B1D5385DB3CC944FC02A3EE0E34E71AF04501DA4C765AFADC9A448BB6FB4F23BEB6AA79E3687B0DDC790B430DEC5E20B0BD900FC0C57C4A32948F0C3C522E45E4ED2321EC82FA81B798CB4FBCB073EC9A36A2D32592DCD2E60C294 + {[1,(rsaDecipherPKCS1_V1_5,rsaDecipherOaep)]} + TRUE + 1067 + + + + + 07 + ACTIVATED + CB{ +[ACTIVATED,1,{ +({00||2a||80||86,00||2a||86||b8},OR{PWD(02),AND{PWD(01),AUTCHAT(cvc_FlagList_TI:00200000000000)},AUTCHAT(cvc_FlagList_TI:00100000000000)}), +({00||46||81||87},ALW), +({00||e4||20||87},OR{SMMAC(13),SMMAC(18),SMMAC(cvc_FlagList_CMS:00800000000000)}) +}]} + 0800 + BA3C03B1C1DFC9CAE48471F5BF1178F783984DBACEB37EB73DAF5BFAC803990C6D04FCC0EC962D4CDE2A3EFF2CEE24F80FA3BA1F117E4480BFE293C6005477941B6F4F06EE2EB94F61EA80F8FA5E4C9B44FF2905415EB401AE9519FD8D9562385477077D99CEAF9073BB1209ED4D14895284F2F9BE621522001C45891F1C88C64029A772A5B6FB15845AA22314651DDEFBD980ABBDE75036BC763677133CB36F6E1389DB1E0F5061FCC5ACDDD0A7B2CA7C085B54D334E4862D043198BA9E3A98A80D3AF68249953A8D72255B5CBF13266DB8FFEDBD30CB559162A5622AC7CFB39C0A54A467CBBBBD7E4CD626A78A5EFF685116299051FB727CECF8C443D1CA65 + 010001 + 8C919E0C3F1526A0516A330655A8DF909BB08B0334DFC10698B5D30C708A5EAC45619D521581A941BAF352479367515A379BD2717EE7BAD71F7EEB2169C057DDDFF35D4812E20B978285D9C19461371B7FB1C509A574D113EFEDB5077025D0544A54E9BF8127C3D699B41B02892E4410FECB4107070FCB79B571A17EC58FE91FC914DED876B5117715CA502A061F091B8C20738AE4DEE8B707E93436554B239BABB92392135727016D0785096CDB398A90503CDF134D1F27DE2CEC529D6F1EB853EE59408619AE56B55ACE740F59EC852BDC22CD403DF71CAC1121CE9778A1FF7D013EAC9ED3256DCBCFA53C33C33EBA97D7F0CBCDFB163E9CD78345B8C815C5 + D23D9FA212AD426C7DA5FBC35FAAA97AC9038A24C56BA6B39B19678ABB1D1ABC5BCE2BF10125AFEAA23F3B0EB6D613BE5A5166487D53EAADFC5DB9544614F33531449C146E8FC50FCA4E2FBECF25321DD22BBA4288BEB8BADF00C13BEB6098D5263A00F3EBC98D56E014D29496BFBCC0ED2A77AB69B1D1F082395004387E594F + E2C4C9A0D1FB14738F6A7EC2E99652091E9DCDC56037129824B851F4A726A5440AA7734574819D5115442528ED41DD0961173ED43467A1A63B80F12C0B932AF5824F796515A7B5490340C14A91B32D091F8854E46140467F604CD18E7411D7A3DDF084A306C186CDA8D8A7F4932D74CA99D63ADC9D46FA3156E2EB1044F7CC0B + B4A1936C996558E38394BF595DF1700979795C1039BA43109F1A5596A12AE154A1FFE24AFF7454CF5FB4B9D5EB8AC48DD0658D5E8CA733C36647543AAEB7C3399969DC3BC5BE2A4E65BF855008036A2AAAEF3CE97B3979D7BC4F96B61785F7E9721D75C21C7C1FBE5B6A287ED78246F6EF0D84A1B67EBBE44ACE590C37497F0B + 2A01A207F45DBA501DC4F06E52AED1CB76AC6CAD9F411464B288A245DBA0C10475A4C7299A875808E913927E9E54910967BED298A48C7DD939348D78473C9FBC92C2FE0DC7912577BCEE85DFB655A686061D4EFC6F3764D7BB92FF4E9019AE0460DC68F57A0EE755B96D48CF7963F63A817CB9B29C3FC5A0D6237ABFACC6EA39 + 219344262282022BDD95582E522ABE046324728118E5FF06109B6C51F5BB638E93FB558451ED3FC64245B04496593FB8E953D935FEDEC157E7EC6788A477E589AF273EF2EFA5BF4A3093AF128B91B9096D83FF460C04B98C448CCAD035F83C28416ADE50166EE410A7B31A19FFA7EAC84BD9065A18288204BC2EBEC02E16AD94 + {[1,(rsaDecipherPKCS1_V1_5,rsaDecipherOaep)]} + TRUE + 1074 + + + + + + + + {e828bd080fa000000167455349474e} + ACTIVATED + TRUE + 1077 + + + + + 3015020101030100a60d0c0b44494e2056203636323931 + 5032 + 12 + ACTIVATED + TRUE + CB{ +[ACTIVATED,1,{ +({00||b0||??||??},ALW) +}]} + FALSE + TRUE + 17 + 17 + 1078 + + + + + + + e01102020409020300800202020409020204095f520c806605444573696d739621f3d003040300d210444567656d5f4e4f4e455f2020000001d310444567656d434f535f53494d20000100d41045474b47322020202020202020010304d610444567656d5f4e4f4e455f2020010000cf15000000000000000000000000000000000000000000 + 2f01 + 1d + ACTIVATED + TRUE + CB{ +[ACTIVATED,1,{ +({00||b0||??||??,00||d0||??||??},ALW) +}]} + TRUE + TRUE + 86 + 86 + 3 + + + + + 7F2181D87F4E81915F290170420844454758588302147F494D06082A8648CE3D04030286410433057328A45B238364F03A5AE7CAD3C52917741C3489008EF1972555E9924AEE66AC1DF71F93A256A3F08074DC069DA7547E2C57A42D8E3F027CBBAC0C29FFCA5F200844454745581602147F4C1306082A8214004C0481185307800000000000005F25060104010102055F24060202010102045F37407C4093884F52203E2AB02C7567D2750D6D04915489CA61D95584898FAD554A611024972EED6E730D5E9BE8EF4E8C39209F300B40E205327FD48EB64DB4DFE8C4 + 2f07 + 07 + ACTIVATED + TRUE + CB{ +[ACTIVATED,1,{ +({00||d6||??||??},AND{OR{SMMAC(13),SMMAC(18),SMMAC(cvc_FlagList_CMS:00800000000000)},SMCMDENC}), +({00||b0||??||??},ALW) +}]} + TRUE + FALSE + 00dc + DC + 1001 + + + + + 7F2181DA7F4E81935F290170420844454745581602147F494B06062B2403050301864104703ED4C516CB05FE1931A04020FAD8B48FA92DCCB9CA3E137BE8589C988CF84859A8CC0FC41FAF7499E8B4996466C379948477E91E808ECDD444DB2C9B68178D5F200C0009802768831100000173337F4C1306082A8214004C0481185307000000000000005F25060105000800045F24060107000800045F37406F88EB976E9368AB990F0B092C3E63EDFB08025F35361160B238C61B88437BE721B4B6713837CA72CD93111102E098927A99D7C88EB0DFA493E82622A0DCBE32 + 2f06 + 06 + ACTIVATED + TRUE + CB{ +[ACTIVATED,1,{ +({00||d6||??||??},AND{OR{SMMAC(13),SMMAC(18),SMMAC(cvc_FlagList_CMS:00800000000000)},SMCMDENC}), +({00||b0||??||??},ALW) +}]} + TRUE + FALSE + 00de + DE + 1003 + + + + + 2f00 + 1e + ACTIVATED + TRUE + CB{ +[ACTIVATED,1,{ +({00||e2||00||00,00||e2||00||f0,00||dc||??||??},AND{OR{SMMAC(13),SMMAC(18),SMMAC(cvc_FlagList_CMS:00800000000000)},SMCMDENC}), +({80||0c||??||??},OR{SMMAC(13),SMMAC(18),SMMAC(cvc_FlagList_CMS:00800000000000)}), +({00||b2||??||??,00||a2||??||??},ALW) +}]} + TRUE + TRUE + 14 + 20 + FALSE + 00c8 + 7 + + + + ACTIVATED + 61094f07d2760001448000 + + + ACTIVATED + 61084f06d27600000102 + + + ACTIVATED + 610c4f0aa000000167455349474e + + + ACTIVATED + 61114f0fe828bd080fa000000167455349474e + + + ACTIVATED + 61084f06d27600014407 + + + ACTIVATED + 61084f06d27600014408 + + + ACTIVATED + 61084f06d2760001440a + + + + + + 5a0a80276883110000017333 + 2f02 + 02 + ACTIVATED + TRUE + CB{ +[ACTIVATED,1,{ +({00||b0||??||??},ALW) +}]} + FALSE + TRUE + 0c + 0C + 5 + + + + + 2f10 + 10 + ACTIVATED + TRUE + CB{ +[ACTIVATED,1,{ +({00||b2||??||??,00||a2||??||??},ALW), +({00||dc||??||??},AND{OR{SMMAC(13),SMMAC(18),SMMAC(cvc_FlagList_CMS:00800000000000)},SMCMDENC}) +}]} + TRUE + TRUE + 04 + 05 + FALSE + 1005 + + + + ACTIVATED + 0040000000 + + + ACTIVATED + 0040000000 + + + ACTIVATED + 0040000000 + + + ACTIVATED + 0000000000 + + + + + + ef2bc003020000c103040302c21045474b47322020202020202020010304c403010000c503020000c703010000 + 2f11 + 11 + ACTIVATED + TRUE + CB{ +[ACTIVATED,1,{ +({00||b0||??||??},ALW), +({00||d6||??||??},AND{OR{SMMAC(13),SMMAC(18),SMMAC(cvc_FlagList_CMS:00800000000000)},SMCMDENC}), +({80||0e||??||??},OR{SMMAC(13),SMMAC(18),SMMAC(cvc_FlagList_CMS:00800000000000)}) +}]} + TRUE + TRUE + 3c + 2d + 1111 + + + + + 01 + ACTIVATED + CB{ +[ACTIVATED,1,{ +({00||24||00||01,80||20||00||01,00||2c||00||01,00||2c||01||01,00||20||00||01},ALW) +}]} + 06 + 08 + 03 + 03 + regularPassword + TRUE + {(1,INFINITY)} + 0a + 26123456FFFFFFFF + 2812345678FFFFFF + 1006 + + + + + ACTIVATED + CB{ +[ACTIVATED,1,{ +({00||24||00||02,80||20||00||02,00||2c||00||02,00||2c||01||02,00||20||00||02},ALW) +}]} + 01 + 02 + TRUE + {(1,INFINITY)} + 1007 + + + + + 13 + ACTIVATED + CB{ +[ACTIVATED,1,{ +({00||82||00||00,00||86||00||00},ALW), +({00||e4||20||13},OR{SMMAC(13),SMMAC(18),SMMAC(cvc_FlagList_CMS:00800000000000)}) +}]} + AES_128 + 00 + aesSessionkey4SM + 182abfc5caf0faeffc5c1e5e6b98ec93 + 3352b6e48523d0e0d402338da98c85dc + 1019 + + + + + 18 + ACTIVATED + CB{ +[ACTIVATED,1,{ +({00||82||00||00,00||86||00||00},ALW), +({00||e4||20||18},OR{SMMAC(13),SMMAC(18),SMMAC(cvc_FlagList_CMS:00800000000000)}) +}]} + AES_256 + 00 + aesSessionkey4SM + dbfd49a096c51cf651277f12bc3e4e70490acdd20e54cc67a05e2c239eb14a48 + ebcd86a704f9516017c3dcea943ee80b3d2e138cd2fbb5f2e12d77befd1063ef + 2419 + + + + + 12 + ACTIVATED + CB{ +[ACTIVATED,1,{ +({00||82||00||00,00||86||00||00},ALW), +({00||e4||20||12},OR{SMMAC(13),SMMAC(18),SMMAC(cvc_FlagList_CMS:00800000000000)}) +}]} + AES_128 + 00 + aesSessionkey4SM + cc1b5a2b9c0eea035b0336eb0c7295cb + 153a57dfcb72db064d6f8cd2f04d700e + 1021 + + + + + 19 + ACTIVATED + CB{ +[ACTIVATED,1,{ +({00||82||00||00,00||86||00||00},ALW), +({00||e4||20||19},OR{SMMAC(13),SMMAC(18),SMMAC(cvc_FlagList_CMS:00800000000000)}) +}]} + AES_256 + 00 + aesSessionkey4SM + a1be7dbf32542a51a77e21bf070225c7404f7a6ed61eac5115b681cabb1142cb + e03ca73a49a09d88d4931d10d78b942d3aee40df5001a072881d91bd7e4a21e7 + 1419 + + + + + 09 + ACTIVATED + CB{ +[ACTIVATED,1,{ +({00||86||00||00,00||88||00||00,00||46||81||09},ALW), +({00||e4||20||09},OR{SMMAC(13),SMMAC(18),SMMAC(cvc_FlagList_CMS:00800000000000)}) +}]} + brainpoolP256r1 + {[1,(elcAsynchronAdmin,elcRoleAuthentication,elcSessionkey4SM)]} + TRUE + 00 + 43CB265B532C300ACE2B98D7C3BE0FDB899BA3FF02CCC036BA4771BBD33C9135 + 1008 + + + + + 4445475858830214 + ACTIVATED + brainpoolP256r1 + 040E33B79383171D098F140E3F9336CE25D450AFACDCDA30C97EBC74A2C60680D28D89AAD9B4418C62FAB1481D7485DF045E09E03E87368D1A283145BF46B8F6BB + ecdsa-with-SHA256 + CB{ +[ACTIVATED,1,{ +({00||2a||00||be},ALW), +({00||e4||21||00},AND{OR{SMMAC(13),SMMAC(18),SMMAC(cvc_FlagList_CMS:00800000000000)},SMCMDENC}) +}]} + CB{ +[ACTIVATED,1,{ +({00||e4||21||00},AND{OR{SMMAC(13),SMMAC(18),SMMAC(cvc_FlagList_CMS:00800000000000)},SMCMDENC}), +({00||2a||00||be},ALW) +}]} + CB{ +[ACTIVATED,1,{ +({00||e4||21||00,00||86||00||00,00||82||00||00},ALW) +}]} + cvc_FlagList_TI:ffffffffffffc3 + 020400090202 + 1010 + + + + + 0000000000000013 + ACTIVATED + brainpoolP256r1 + 040E33B79383171D098F140E3F9336CE25D450AFACDCDA30C97EBC74A2C60680D28D89AAD9B4418C62FAB1481D7485DF045E09E03E87368D1A283145BF46B8F6BB + ecdsa-with-SHA256 + CB{ +[ACTIVATED,1,{ +({00||2a||00||be},ALW), +({00||e4||21||00},AND{OR{SMMAC(13),SMMAC(18),SMMAC(cvc_FlagList_CMS:00800000000000)},SMCMDENC}) +}]} + CB{ +[ACTIVATED,1,{ +({00||e4||21||00},AND{OR{SMMAC(13),SMMAC(18),SMMAC(cvc_FlagList_CMS:00800000000000)},SMCMDENC}), +({00||2a||00||be},ALW) +}]} + CB{ +[ACTIVATED,1,{ +({00||e4||21||00,00||86||00||00},ALW) +}]} + cvc_FlagList_CMS:ffbfffffffffff + 010501020301 + AttributeNotSet + 1020 + + + + + + 3b901881b1fe451f031f + 3b909581b1fe451f0392 + 6883110000017333 + 010500080004 + ACTIVATED + + 05 + + + V3.8.1 + FALSE + 4 + FALSE + ..\d3\TLK_eGK_G2_sample.d3 + E02_init;Image_V1.3.4;gemSpec_eGK_ObjSys_V3.8.1;gemSpec_COS_Wrapper_V1.6.0;gemSpec_COS_V3.7.0;Produkttypversion_V4.3.2;Release_V1.4.7 + EGKG2 + FALSE + + diff --git a/CardSimulationTestKit/Tests/CardSimulationLoaderTests/KeepAliveRunLoopTest.swift b/CardSimulationTestKit/Tests/CardSimulationLoaderTests/KeepAliveRunLoopTest.swift new file mode 100644 index 0000000..0dca56c --- /dev/null +++ b/CardSimulationTestKit/Tests/CardSimulationLoaderTests/KeepAliveRunLoopTest.swift @@ -0,0 +1,47 @@ +// +// Copyright (c) 2023 gematik GmbH +// +// Licensed under the Apache License, Version 2.0 (the License); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an 'AS IS' BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +@testable import CardSimulationLoader +import Nimble +import XCTest + +final class KeepAliveRunLoopTest: XCTestCase { + func testRunloop() { + let keepAliveRunloop = KeepAliveRunLoop() + keepAliveRunloop.start() + let runloop = keepAliveRunloop.runloop + expect(runloop).toNot(beNil()) + } + + func testRunloopEnds() { + var threadEnded = false + let keepAliveRunloop = KeepAliveRunLoop() + keepAliveRunloop.start() + keepAliveRunloop.runloop.perform(inModes: [.default]) { [keepAliveRunloop] in + keepAliveRunloop.cancel() + threadEnded = true + } + + expect(keepAliveRunloop.isCancelled).toEventually(beTrue()) + expect(keepAliveRunloop.isFinished).toEventually(beTrue()) + expect(threadEnded).toEventually(beTrue()) + } + + static var allTests = [ + ("testRunloop", testRunloop), + ("testRunloopEnds", testRunloopEnds), + ] +} diff --git a/CardSimulationTestKit/Tests/CardSimulationLoaderTests/Resources.bundle/configuration.xml b/CardSimulationTestKit/Tests/CardSimulationLoaderTests/Resources.bundle/configuration.xml new file mode 100755 index 0000000..e9734ec --- /dev/null +++ b/CardSimulationTestKit/Tests/CardSimulationLoaderTests/Resources.bundle/configuration.xml @@ -0,0 +1,44 @@ + + + + ../images/HBAG2_80276883110000017289_gema5.xml + ../channelcontexts/ChannelContext_G2_HBA.xml + com.achelos.egk.g2sim.tcpipcardio.TcpIpCardIo + + + + + 4 + 4 + 0 + false + + + false + false + + + + + 3039 + + + + ../log/ + Logfile + yyyy-MM-dd HH-mm-ss + .log + false + + + ../log/ + Logfile + yyyy-MM-dd HH-mm-ss + .log + + + + 12350 + com.achelos.egk.g2sim.collis.tpdu.T1Layer + + diff --git a/CardSimulationTestKit/Tests/CardSimulationLoaderTests/Resources.bundle/pom.xml b/CardSimulationTestKit/Tests/CardSimulationLoaderTests/Resources.bundle/pom.xml new file mode 100644 index 0000000..c325dcd --- /dev/null +++ b/CardSimulationTestKit/Tests/CardSimulationLoaderTests/Resources.bundle/pom.xml @@ -0,0 +1,22 @@ + + 4.0.0 + + CardSimulation-test + cardsimulation.exec + de.gematik.ti + 1.0.0-test + + + + de.gematik + de.gematik.egk.g2sim.product + ${project.version} + + + + + ${project.artifactId} + ./${project.name}-${project.version} + + diff --git a/CardSimulationTestKit/Tests/CardSimulationLoaderTests/Resources.bundle/soapRequest.xml b/CardSimulationTestKit/Tests/CardSimulationLoaderTests/Resources.bundle/soapRequest.xml new file mode 100644 index 0000000..4e72fa5 --- /dev/null +++ b/CardSimulationTestKit/Tests/CardSimulationLoaderTests/Resources.bundle/soapRequest.xml @@ -0,0 +1,17 @@ + + + + 234 + + + + AAPL + + + GOOG + + + ATTR + + + \ No newline at end of file diff --git a/CardSimulationTestKit/Tests/CardSimulationLoaderTests/SimulationManagerTest.swift b/CardSimulationTestKit/Tests/CardSimulationLoaderTests/SimulationManagerTest.swift new file mode 100644 index 0000000..0e96f55 --- /dev/null +++ b/CardSimulationTestKit/Tests/CardSimulationLoaderTests/SimulationManagerTest.swift @@ -0,0 +1,196 @@ +// +// Copyright (c) 2023 gematik GmbH +// +// Licensed under the Apache License, Version 2.0 (the License); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an 'AS IS' BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +@testable import CardSimulationLoader +import GemCommonsKit +import Nimble +import XCTest + +final class SimulationManagerTest: XCTestCase { + private static let tempDir: URL = { + NSTemporaryDirectory().asURL + .appendingPathComponent(ProcessInfo.processInfo.globallyUniqueString, isDirectory: true) + }() + + private static let manager: SimulationManager = { + SimulationManager(tempDir: tempDir) + }() + + typealias SimulationDelegateCallback = (manager: SimulationManagerType, simulator: SimulationRunnerType) + + class TestSimulationManagerDelegate: SimulationManagerDelegate { + var startedSimulatorCalls = [SimulationDelegateCallback]() + var endedSimulatorCalls = [SimulationDelegateCallback]() + + func simulation(manager: SimulationManagerType, didStart simulator: SimulationRunnerType) { + startedSimulatorCalls.append((manager: manager, simulator: simulator)) + } + + func simulation(manager: SimulationManagerType, didEnd simulator: SimulationRunnerType) { + endedSimulatorCalls.append((manager: manager, simulator: simulator)) + } + + var didCallStarted: Bool { + startCallsCount > 0 + } + + var startCallsCount: Int { + startedSimulatorCalls.count + } + + var didCallEnded: Bool { + endCallsCount > 0 + } + + var endCallsCount: Int { + endedSimulatorCalls.count + } + } + + // swiftlint:disable:next function_body_length + func testSimulationManager() { + do { + let simulatorConfig = Bundle(for: SimulationRunnerTest.self) + .testResourceFilePath(in: "Configuration", + for: "configuration_EGKG2_80276883110000017222_gema5_TCP.xml") + .asURL + let manager = SimulationManagerTest.manager + let delegate = TestSimulationManagerDelegate() + var strongDelegate = TestSimulationManagerDelegate() + weak var weakDelegate = strongDelegate + let deregisteredDelegate = TestSimulationManagerDelegate() + manager.register(delegate: delegate) + // Check for double registration + manager.register(delegate: delegate) + manager.register(delegate: deregisteredDelegate) + manager.register(delegate: strongDelegate) + manager.deregister(delegate: deregisteredDelegate) + // Double de-registration should not be a problem + manager.deregister(delegate: deregisteredDelegate) + let runner = try manager.createSimulation( + configFile: simulatorConfig, + preprocessor: [XMLPathManipulatorHolder.tlvPortManipulator(port: "0"), + XMLPathManipulatorHolder.relativeToAbsolutePathManipulator( + with: XMLPathManipulatorHolder.CardConfigFileXMLPath, + absolutePath: simulatorConfig.deletingLastPathComponent() + ), + XMLPathManipulatorHolder.relativeToAbsolutePathManipulator( + with: XMLPathManipulatorHolder.ChannelConfigFileXMLPath, + absolutePath: simulatorConfig.deletingLastPathComponent() + )] + ) + expect(runner).toNot(beNil()) + expect(runner.mode.isNotRunning).to(beTrue()) + runner.start(waitUntilLaunched: true) + expect(runner.mode.isRunning).to(beTrue()) + expect(manager.runners).to(containElementSatisfying({ element in element === runner }, "")) + + // Verify delegate got notified of SimulationRunner start + expect(delegate.didCallStarted).to(beTrue()) + // Verify no double calls despite 'double' registration + expect(delegate.startCallsCount).to(equal(1)) + expect(weakDelegate?.didCallStarted ?? false).to(beTrue()) + expect(delegate.didCallEnded).to(beFalse()) + expect(deregisteredDelegate.didCallEnded).to(beFalse()) + expect(deregisteredDelegate.didCallStarted).to(beFalse()) + + strongDelegate = TestSimulationManagerDelegate() + + let lateDelegate = TestSimulationManagerDelegate() + manager.register(delegate: lateDelegate) + /// Late delegate should still get notified of already running simulators + expect(lateDelegate.startCallsCount).to(equal(1)) + + runner.stop(waitUntilTerminated: true) + + // We need to wait a bit to allow for the delegate callbacks to be executed on the callback thread + RunLoop.current.run(mode: RunLoop.Mode.default, before: Date(timeIntervalSinceNow: 0.25)) + + // + // Verify delegate got notified of SimulationRunner ended + expect(delegate.didCallEnded).to(beTrue()) + expect(deregisteredDelegate.didCallEnded).to(beFalse()) + expect(deregisteredDelegate.didCallStarted).to(beFalse()) + + expect(manager.runners).toNot(containElementSatisfying({ element in element === runner }, "")) + // Assert that delegates are weak referenced + expect(weakDelegate?.didCallEnded ?? false).to(beFalse()) + expect(weakDelegate).to(beNil()) + } catch { + ALog("Exception thrown in test-case [\(error)]") + #if os(macOS) || os(Linux) + Nimble.fail("Failed with error \(error)") + #else + ALog("Skip testSimulationManager on platform other than macOS | Linux") + #endif + } + } + + func testSimulationManager_fail_to_start() { + do { + let delegate = TestSimulationManagerDelegate() + let manager = SimulationManagerTest.manager + manager.register(delegate: delegate) + /// Starting with this config file will fail this time since we don't change the image and channelContext + /// paths and therefore the G2-Kartensimulation can't start. Although our SimulationManager should just + /// run fine and detect this behaviour + let simulatorConfig = Bundle(for: SimulationRunnerTest.self) + .testResourceFilePath(in: "Configuration", + for: "configuration_EGKG2_80276883110000017222_gema5_TCP.xml") + .asURL + let runner = try manager.createSimulation( + configFile: simulatorConfig, + preprocessor: [] + ) + expect(runner).toNot(beNil()) + expect(runner.mode.isNotRunning).to(beTrue()) + runner.start(waitUntilLaunched: true) + expect(runner.mode.isTerminated).to(beTrue()) + + expect(manager.runners).toNot(containElementSatisfying({ element in element === runner }, "")) + + // + // Verify delegate did not get notified of SimulationRunner start + expect(delegate.didCallStarted).to(beFalse()) + expect(delegate.didCallEnded).to(beTrue()) + + } catch { + ALog("Exception thrown in test-case [\(error)]") + #if os(macOS) || os(Linux) + Nimble.fail("Failed with error \(error)") + #else + ALog("Skip testSimulationManager_fail_to_start on platform other than macOS | Linux") + #endif + } + } + + func testSimulationManagerClean() { + #if os(macOS) || os(Linux) + expect(FileManager.default.fileExists(atPath: SimulationManagerTest.tempDir.path)).to(beTrue()) + let manager = SimulationManagerTest.manager + manager.clean() + expect(FileManager.default.fileExists(atPath: SimulationManagerTest.tempDir.path)).toEventually(beFalse()) + #else + ALog("Skip testSimulationManagerClean on platform other than macOS | Linux") + #endif + } + + static var allTests = [ + ("testSimulationManager", testSimulationManager), + ("testSimulationManager_fail_to_start", testSimulationManager_fail_to_start), + ("testSimulationManagerClean", testSimulationManagerClean), + ] +} diff --git a/CardSimulationTestKit/Tests/CardSimulationLoaderTests/SimulationProcessModeTest.swift b/CardSimulationTestKit/Tests/CardSimulationLoaderTests/SimulationProcessModeTest.swift new file mode 100644 index 0000000..a56c3d1 --- /dev/null +++ b/CardSimulationTestKit/Tests/CardSimulationLoaderTests/SimulationProcessModeTest.swift @@ -0,0 +1,98 @@ +// +// Copyright (c) 2023 gematik GmbH +// +// Licensed under the Apache License, Version 2.0 (the License); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an 'AS IS' BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +@testable import CardSimulationLoader +import Nimble +import XCTest + +final class SimulationProcessModeTest: XCTestCase { + func testMode_notStarted() { + let mode = SimulationProcessMode.notStarted + + expect(mode.isNotRunning).to(beTrue()) + expect(mode.isTerminated).to(beFalse()) + expect(mode.isInitializing).to(beFalse()) + expect(mode.isRunning).to(beFalse()) + + expect(mode.tlvPort).to(beNil()) + expect(mode.terminationStatus).to(beNil()) + + expect(mode).toNot(equal(SimulationProcessMode.initializing)) + expect(mode).to(equal(SimulationProcessMode.notStarted)) + expect(mode).toNot(equal(SimulationProcessMode.running(onTCPPort: 500))) + expect(mode).toNot(equal(SimulationProcessMode.terminated(terminationStatus: -1))) + } + + func testMode_initializing() { + let mode = SimulationProcessMode.initializing + + expect(mode.isNotRunning).to(beFalse()) + expect(mode.isTerminated).to(beFalse()) + expect(mode.isInitializing).to(beTrue()) + expect(mode.isRunning).to(beFalse()) + + expect(mode.tlvPort).to(beNil()) + expect(mode.terminationStatus).to(beNil()) + + expect(mode).to(equal(SimulationProcessMode.initializing)) + expect(mode).toNot(equal(SimulationProcessMode.notStarted)) + expect(mode).toNot(equal(SimulationProcessMode.running(onTCPPort: 500))) + expect(mode).toNot(equal(SimulationProcessMode.terminated(terminationStatus: -1))) + } + + func testMode_running() { + let mode = SimulationProcessMode.running(onTCPPort: 9) + + expect(mode.isNotRunning).to(beFalse()) + expect(mode.isTerminated).to(beFalse()) + expect(mode.isInitializing).to(beFalse()) + expect(mode.isRunning).to(beTrue()) + + expect(mode.tlvPort).to(equal(9)) + expect(mode.terminationStatus).to(beNil()) + + expect(mode).toNot(equal(SimulationProcessMode.initializing)) + expect(mode).toNot(equal(SimulationProcessMode.notStarted)) + expect(mode).toNot(equal(SimulationProcessMode.running(onTCPPort: 500))) + expect(mode).to(equal(SimulationProcessMode.running(onTCPPort: 9))) + expect(mode).toNot(equal(SimulationProcessMode.terminated(terminationStatus: -1))) + } + + func testMode_terminated() { + let mode = SimulationProcessMode.terminated(terminationStatus: -1) + + expect(mode.isNotRunning).to(beFalse()) + expect(mode.isTerminated).to(beTrue()) + expect(mode.isInitializing).to(beFalse()) + expect(mode.isRunning).to(beFalse()) + + expect(mode.tlvPort).to(beNil()) + expect(mode.terminationStatus).to(equal(-1)) + + expect(mode).toNot(equal(SimulationProcessMode.initializing)) + expect(mode).toNot(equal(SimulationProcessMode.notStarted)) + expect(mode).toNot(equal(SimulationProcessMode.running(onTCPPort: 500))) + expect(mode).to(equal(SimulationProcessMode.terminated(terminationStatus: -1))) + expect(mode).toNot(equal(SimulationProcessMode.terminated(terminationStatus: 10))) + } + + static var allTests = [ + ("testMode_notStarted", testMode_notStarted), + ("testMode_initializing", testMode_initializing), + ("testMode_running", testMode_running), + ("testMode_terminated", testMode_terminated), + ] +} diff --git a/CardSimulationTestKit/Tests/CardSimulationLoaderTests/SimulationRunnerTest.swift b/CardSimulationTestKit/Tests/CardSimulationLoaderTests/SimulationRunnerTest.swift new file mode 100644 index 0000000..713a0f1 --- /dev/null +++ b/CardSimulationTestKit/Tests/CardSimulationLoaderTests/SimulationRunnerTest.swift @@ -0,0 +1,116 @@ +// +// Copyright (c) 2023 gematik GmbH +// +// Licensed under the Apache License, Version 2.0 (the License); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an 'AS IS' BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +@testable import CardSimulationLoader +import GemCommonsKit +import Nimble +import XCTest + +final class SimulationRunnerTest: XCTestCase { + private static let simTempPath: URL = { + NSTemporaryDirectory().asURL + .appendingPathComponent(ProcessInfo.processInfo.globallyUniqueString, isDirectory: true) + }() + + private static var simTempDependencyInfo: SimulationManager.DependencyInfo? + + override class func setUp() { + super.setUp() + DLog("Start simulator test at path: \(simTempPath)") + + do { + let pomXml = try Data(contentsOf: Bundle(for: Self.self) + .testResourceFilePath(in: "Resources", for: "pom.xml").asURL) + + simTempDependencyInfo = try SimulationManager.loadCardSimulatorDependencies( + version: SimulationManager.defaultVersion, + outputDirectory: simTempPath, + pom: pomXml + ) + .get() + } catch { + ALog("Error while loading dependencies: \(error)") + } + } + + override class func tearDown() { + // delete temp directory + do { + try FileManager.default.removeItem(at: simTempPath) + } catch { + ALog("Error while cleaning up test-case. \(String(describing: error))") + } + super.tearDown() + } + + func testSimulationRunner() { + guard let dependencyInfo = SimulationRunnerTest.simTempDependencyInfo, + let classPath = dependencyInfo.simulatorClassPath + else { + #if os(macOS) || os(Linux) + Nimble.fail("Could not run test while SimulationRunnerTest.simTempDependencyInfo is nil") + #else + ALog("Skip testSimulationRunner on platform other than macOS | Linux") + #endif + return + } + var delegate = SimulationRunnerTestDelegate() + let processedConfigFile = Bundle(for: SimulationRunnerTest.self) + .testResourceFilePath(in: "Configuration", + for: "configuration_EGKG2_80276883110000017222_gema5_TCP.xml") + .asURL + let runner = SimulationRunner( + simulator: processedConfigFile, + classPath: classPath, + workingDirectory: processedConfigFile.deletingLastPathComponent() + ) + runner.delegate = delegate + runner.start(waitUntilLaunched: true) + expect(runner.mode.isRunning).to(beTrue()) + + guard delegate.callbackStates.count > 1 else { + Nimble.fail("Not enough callbacks") + return + } + expect(delegate.callbackStates[0].isInitializing).to(beTrue()) + expect(delegate.callbackStates[1].isRunning).to(beTrue()) + + runner.stop(waitUntilTerminated: true) + // Allow for the callback to be scheduled on main + RunLoop.current.run(mode: .default, before: Date(timeIntervalSinceNow: 0.25)) + + guard delegate.callbackStates.count > 2 else { + Nimble.fail("Not enough callbacks") + return + } + expect(delegate.callbackStates[2].isTerminated).to(beTrue()) + // test whether delegate is weakly retained + delegate = SimulationRunnerTestDelegate() + expect(runner.delegate).to(beNil()) + } + + static var allTests = [ + ("testSimulationRunner", testSimulationRunner), + ] +} + +class SimulationRunnerTestDelegate: SimulationRunnerDelegate { + var callbackStates: [SimulationProcessMode] = [] + + func simulation(runner _: SimulationRunnerType, changed mode: SimulationProcessMode) { + callbackStates.append(mode) + } +} diff --git a/CardSimulationTestKit/Tests/CardSimulationLoaderTests/XCTestManifests.swift b/CardSimulationTestKit/Tests/CardSimulationLoaderTests/XCTestManifests.swift new file mode 100644 index 0000000..744449d --- /dev/null +++ b/CardSimulationTestKit/Tests/CardSimulationLoaderTests/XCTestManifests.swift @@ -0,0 +1,35 @@ +// +// Copyright (c) 2023 gematik GmbH +// +// Licensed under the Apache License, Version 2.0 (the License); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an 'AS IS' BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import XCTest + +#if !os(macOS) && !os(iOS) +/// Runs all tests in CardSimulation-Loader +public func allTests() -> [XCTestCaseEntry] { + [ + testCase(JavaProcessTest.allTests), + testCase(KeepAliveRunLoopTest.allTests), + testCase(SimulationManagerTest.allTests), + testCase(SimulationRunnerTest.allTests), + testCase(URLExtConfigurationFileProcessorTest.allTests), + testCase(XMLPathTest.allTests), + testCase(XMLElementManipulatorTest.allTests), + testCase(AEXMLDocumentExtXMLManipulationTest.allTests), + testCase(SimulationManagerExtInternalTest.allTests), + testCase(SimulationProcessModeTest.allTests), + ] +} +#endif diff --git a/CardSimulationTestKit/Tests/CardSimulationLoaderTests/internal/JavaProcessTest.swift b/CardSimulationTestKit/Tests/CardSimulationLoaderTests/internal/JavaProcessTest.swift new file mode 100644 index 0000000..a752bf6 --- /dev/null +++ b/CardSimulationTestKit/Tests/CardSimulationLoaderTests/internal/JavaProcessTest.swift @@ -0,0 +1,52 @@ +// +// Copyright (c) 2023 gematik GmbH +// +// Licensed under the Apache License, Version 2.0 (the License); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an 'AS IS' BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +@testable import CardSimulationLoader +import Nimble +import XCTest + +final class JavaProcessTest: XCTestCase { + class Delegate: JavaProcessUpdateDelegate { + var launchedCalls = [(process: JavaProcess, pid: Int32)]() + + func processDidLaunch(_ process: JavaProcess, pid: Int32) { + launchedCalls.append((process: process, pid: pid)) + } + + var terminateCalls = [(process: JavaProcess, status: Int32)]() + + func processDidTerminate(_ process: JavaProcess, with status: Int32) { + terminateCalls.append((process: process, status: status)) + } + } + + func testJavaProcessRun() { + let pipe = Pipe() + let config = JavaProcess.Config.build(workingDirectory: FileManager.default.currentDirectoryPath, + classPath: "./*") + let process = JavaProcess(config: config, stdout: pipe, stderr: pipe, stdin: pipe) + let delegate = Delegate() + process.run(delegate: delegate) + + RunLoop.current.run(mode: RunLoop.Mode.default, before: Date(timeIntervalSinceNow: 0.5)) + expect(delegate.launchedCalls.count).to(equal(1)) + expect(delegate.terminateCalls.count).to(equal(1)) + } + + static var allTests = [ + ("testJavaProcessRun", testJavaProcessRun), + ] +} diff --git a/CardSimulationTestKit/Tests/CardSimulationLoaderTests/internal/SimulationManagerExtInternalTest.swift b/CardSimulationTestKit/Tests/CardSimulationLoaderTests/internal/SimulationManagerExtInternalTest.swift new file mode 100644 index 0000000..9dfcd3b --- /dev/null +++ b/CardSimulationTestKit/Tests/CardSimulationLoaderTests/internal/SimulationManagerExtInternalTest.swift @@ -0,0 +1,103 @@ +// +// Copyright (c) 2023 gematik GmbH +// +// Licensed under the Apache License, Version 2.0 (the License); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an 'AS IS' BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import AEXML +@testable import CardSimulationLoader +import Foundation +import GemCommonsKit +import Nimble +import XCTest + +final class SimulationManagerExtInternalTest: XCTestCase { + func testSimulationManager_DependencyInfo() { + do { + let pomXmlData = try Data(contentsOf: Bundle(for: SimulationManagerExtInternalTest.self) + .testResourceFilePath(in: "Resources", for: "pom.xml").asURL) + let pomXml = try AEXMLDocument(xml: pomXmlData) + let outputPath = NSTemporaryDirectory() + .asURL.appendingPathComponent(ProcessInfo.processInfo.globallyUniqueString, isDirectory: true) + let dependencyInfo = SimulationManager.DependencyInfo(xml: pomXml, output: outputPath) + + let expectedProject = "CardSimulation-test" + let expectedVersion = "1.0.0-test" + let expectedName = "\(expectedProject)-\(expectedVersion)" + let simulatorName = try dependencyInfo.simulatorName() + expect(expectedName).to(equal(simulatorName)) + let expectedSimulatorPath = outputPath.appendingPathComponent(expectedVersion, isDirectory: true) + let expectedPomPath = expectedSimulatorPath.appendingPathComponent("pom.xml") + expect(expectedPomPath).to(equal(dependencyInfo.pom)) + let expectedScriptPath = expectedSimulatorPath.appendingPathComponent("runMaven.sh") + expect(expectedScriptPath).to(equal(dependencyInfo.script)) + + let expectedClassPath = expectedSimulatorPath.appendingPathComponent(expectedName, isDirectory: true) + .appendingPathComponent("dependency", isDirectory: true) + expect(expectedClassPath).to(equal(dependencyInfo.simulatorClassPath)) + + expect(dependencyInfo.simulatorExists).to(beFalse()) + let simPath = expectedScriptPath.deletingLastPathComponent() + try FileManager.default.createDirectory(at: simPath, withIntermediateDirectories: true) + expect(dependencyInfo.simulatorExists).to(beTrue()) + try FileManager.default.removeItem(at: simPath) + } catch { + ALog("Test-case failed with exception: [\(error)]") + Nimble.fail("Failed with error \(error)") + } + } + + func testSimulationManager_loadCardSimulatorDependencies() { + do { + let pomXmlData = try Data(contentsOf: Bundle(for: SimulationManagerExtInternalTest.self) + .testResourceFilePath(in: "Resources", for: "pom.xml").asURL) + let script = """ + #!/bin/bash + DIR="$(dirname $1)" + cd "${DIR}" && echo -n $1 > output.txt + exit 0 + """ + let outputPath = NSTemporaryDirectory().asURL + .appendingPathComponent(ProcessInfo.processInfo.globallyUniqueString, isDirectory: true) + let expectedVersion = "0.0.T-tests" + let dependencyInfo = try SimulationManager.loadCardSimulatorDependencies( + version: expectedVersion, + outputDirectory: outputPath, + pom: pomXmlData, + script: script + ) + .get() + + let scriptOutputFileData = try Data(contentsOf: dependencyInfo.pom.deletingLastPathComponent() + .appendingPathComponent("output.txt")) + guard let output = String(data: scriptOutputFileData, encoding: .utf8) else { + Nimble.fail("Failed converting scriptOutputFileData to String.") + return + } + expect(output).to(equal(dependencyInfo.pom.path)) + let pomFileData = try Data(contentsOf: dependencyInfo.pom) + let pomXml = try AEXMLDocument(xml: pomFileData) + expect(expectedVersion).to(equal(pomXml["project"]["version"].value)) + // cleanup + try FileManager.default.removeItem(at: outputPath) + } catch { + ALog("Test-case failed with exception: [\(error)]") + Nimble.fail("Failed with error \(error)") + } + } + + static var allTests = [ + ("testSimulationManager_DependencyInfo", testSimulationManager_DependencyInfo), + ("testSimulationManager_loadCardSimulatorDependencies", testSimulationManager_loadCardSimulatorDependencies), + ] +} diff --git a/CardSimulationTestKit/Tests/CardSimulationLoaderTests/xml/AEXMLDocumentExtXMLManipulationTest.swift b/CardSimulationTestKit/Tests/CardSimulationLoaderTests/xml/AEXMLDocumentExtXMLManipulationTest.swift new file mode 100644 index 0000000..d2c1a31 --- /dev/null +++ b/CardSimulationTestKit/Tests/CardSimulationLoaderTests/xml/AEXMLDocumentExtXMLManipulationTest.swift @@ -0,0 +1,54 @@ +// +// Copyright (c) 2023 gematik GmbH +// +// Licensed under the Apache License, Version 2.0 (the License); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an 'AS IS' BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import AEXML +@testable import CardSimulationLoader +import GemCommonsKit +import Nimble +import XCTest + +final class AEXMLDocumentExtXMLManipulationTest: XCTestCase { + func testXMLManipulation() { + do { + let configData = try Data(contentsOf: Bundle(for: AEXMLDocumentExtXMLManipulationTest.self) + .testResourceFilePath(in: "Resources", for: "configuration.xml") + .asURL) + let xmlDoc = try AEXMLDocument(xml: configData) + + let manipulators: [XMLPathManipulator] = [ + XMLPathManipulatorHolder(path: "configuration.general.attribute{id:cardImageFile}") { _, element in + element.value = "changed_" + (element.value ?? "no-value") + return element + }, + XMLPathManipulatorHolder(path: "configuration.ioConfiguration.port") { _, element in + element.value = "0" + return element + }, + ] + let xmlResult = try xmlDoc.manipulateXMLDocument(with: manipulators) + let configElement = xmlResult.root["general"]["attribute"].all(withAttributes: ["id": "cardImageFile"])?[0] + expect(configElement?.value).to(equal("changed_../images/HBAG2_80276883110000017289_gema5.xml")) + expect(xmlResult.root["ioConfiguration"]["port"].value).to(equal("0")) + } catch { + ALog("Test-case failed: [\(error)]") + Nimble.fail("Failed with error \(error)") + } + } + + static var allTests = [ + ("testXMLManipulation", testXMLManipulation), + ] +} diff --git a/CardSimulationTestKit/Tests/CardSimulationLoaderTests/xml/URLExtConfigurationFileProcessorTest.swift b/CardSimulationTestKit/Tests/CardSimulationLoaderTests/xml/URLExtConfigurationFileProcessorTest.swift new file mode 100644 index 0000000..cab22a0 --- /dev/null +++ b/CardSimulationTestKit/Tests/CardSimulationLoaderTests/xml/URLExtConfigurationFileProcessorTest.swift @@ -0,0 +1,60 @@ +// +// Copyright (c) 2023 gematik GmbH +// +// Licensed under the Apache License, Version 2.0 (the License); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an 'AS IS' BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import AEXML +@testable import CardSimulationLoader +import GemCommonsKit +import Nimble +import XCTest + +final class URLExtConfigurationFileProcessorTest: XCTestCase { + func testProcessConfigFile() { + let configFile = Bundle(for: URLExtConfigurationFileProcessorTest.self) + .testResourceFilePath(in: "Resources", for: "configuration.xml") + .asURL + + let manipulators: [XMLPathManipulator] = [ + XMLPathManipulatorHolder(path: "configuration.general.attribute{id:cardImageFile}") { _, element in + element.value = "changed_" + (element.value ?? "no-value") + return element + }, + XMLPathManipulatorHolder(path: "configuration.ioConfiguration.port") { _, element in + element.value = "0" + return element + }, + ] + let xmlResult = configFile.prepareXMLConfigFile(with: manipulators) + expect { + try xmlResult.get() + }.to(satisfyAllOf( + Predicate { expr in + let configElement = try? expr.evaluate()? + .root["general"]["attribute"] + .all(withAttributes: ["id": "cardImageFile"])?[0] + let condition = configElement?.value == "changed_../images/HBAG2_80276883110000017289_gema5.xml" + return PredicateResult(bool: condition, message: .expectedTo("Have changed the cardImageFile")) + }, + Predicate { expr in + PredicateResult(bool: try expr.evaluate()?.root["ioConfiguration"]["port"].value == "0", + message: .expectedTo("Have 0 as ioConfiguration/port")) + } + )) + } + + static var allTests = [ + ("testProcessConfigFile", testProcessConfigFile), + ] +} diff --git a/CardSimulationTestKit/Tests/CardSimulationLoaderTests/xml/XMLElementManipulatorTest.swift b/CardSimulationTestKit/Tests/CardSimulationLoaderTests/xml/XMLElementManipulatorTest.swift new file mode 100644 index 0000000..6c9bb9d --- /dev/null +++ b/CardSimulationTestKit/Tests/CardSimulationLoaderTests/xml/XMLElementManipulatorTest.swift @@ -0,0 +1,51 @@ +// +// Copyright (c) 2023 gematik GmbH +// +// Licensed under the Apache License, Version 2.0 (the License); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an 'AS IS' BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import AEXML +@testable import CardSimulationLoader +import Foundation +import Nimble +import XCTest + +final class XMLElementManipulatorTest: XCTestCase { + func testTLVPortManipulator() { + let manipulator = XMLPathManipulatorHolder.tlvPortManipulator(port: "0") + expect(manipulator.path).to(equal("configuration.ioConfiguration.port" as XMLPath)) + let element = AEXML.AEXMLElement(name: "port", value: "12345") + let manipulatedElement = manipulator.manipulate(path: "configuration.ioConfiguration.port", with: element) + expect(manipulatedElement.value).to(equal("0")) + expect(manipulatedElement.name).to(equal(element.name)) + } + + func testRelativePathManipulator() { + let absoluteDirectoryPath = "/My/Awesome-Path/With space/ïn path".asURL + let manipulator = XMLPathManipulatorHolder + .relativeToAbsolutePathManipulator(with: XMLPathManipulatorHolder.CardConfigFileXMLPath, + absolutePath: absoluteDirectoryPath) + let element = AEXML.AEXMLElement(name: "attribute", + value: "../Some/Path/To/File.xml", + attributes: ["id": "channelContextFile"]) + let manipulatedElement = manipulator.manipulate(path: "configuration.general.attribute{id:channelContextFile}", + with: element) + expect(manipulatedElement.value).to(equal("/My/Awesome-Path/With space/ïn path/../Some/Path/To/File.xml")) + expect(manipulatedElement.name).to(equal(element.name)) + } + + static var allTests = [ + ("testTLVPortManipulator", testTLVPortManipulator), + ("testRelativePathManipulator", testRelativePathManipulator), + ] +} diff --git a/CardSimulationTestKit/Tests/CardSimulationLoaderTests/xml/XMLPathTest.swift b/CardSimulationTestKit/Tests/CardSimulationLoaderTests/xml/XMLPathTest.swift new file mode 100644 index 0000000..4f77a4d --- /dev/null +++ b/CardSimulationTestKit/Tests/CardSimulationLoaderTests/xml/XMLPathTest.swift @@ -0,0 +1,123 @@ +// +// Copyright (c) 2023 gematik GmbH +// +// Licensed under the Apache License, Version 2.0 (the License); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an 'AS IS' BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import AEXML +@testable import CardSimulationLoader +import GemCommonsKit +import Nimble +import XCTest + +final class XMLPathTest: XCTestCase { + static var soapRequest: AEXMLDocument! + + var soapRequest: AEXMLDocument! { + XMLPathTest.soapRequest + } + + override class func setUp() { + super.setUp() + + do { + let xmlData = try Bundle(for: XMLPathTest.self) + .testResourceFilePath(in: "Resources", for: "soapRequest.xml") + .readFileContents() + soapRequest = try AEXMLDocument(xml: xmlData) + } catch { + Nimble.fail("Error in setup XMLPathTest") + } + } + + func testXMLPath() { + let path: XMLPath = "configuration.node.element" + expect(path.components).to(equal(["configuration", "node", "element"])) + } + + func testAEXMLDocument_resolve_path() { + let path: XMLPath = "soap:Envelope.soap:Header.m:Trans" + expect(self.soapRequest.resolve(path: path)?.value).to(equal("234")) + expect(self.soapRequest.resolve(path: "soap:Header.m:Trans")).to(beNil()) + expect(self.soapRequest.resolve(path: "configuration.non.existing")).to(beNil()) + } + + func testAEXMLDocument_resolve_path_element_at_index() { + /// Test fetching child elements by index + let bodyPath: XMLPath = "soap:Envelope.soap:Body.m:GetStockPrice.m:StockName" + expect(self.soapRequest.resolve(path: bodyPath)?.value).to(equal("AAPL")) + let bodyPathIndex1: XMLPath = "soap:Envelope.soap:Body.m:GetStockPrice[1].m:StockName" + let googelement = soapRequest.resolve(path: bodyPathIndex1) + expect(googelement?.value).to(equal("GOOG")) + } + + func testAEXMLDocument_resolve_path_element_with_attribute() { + let bodyPathAttribute: XMLPath = "soap:Envelope.soap:Body.m:GetStockPrice{attribute:attr_value}.m:StockName" + let element = soapRequest.resolve(path: bodyPathAttribute) + expect(element?.value).to(equal("ATTR")) + } + + func testAEXMLDocument_replace_path() { + /// Load document per test-case since the test will modify its contents + do { + let xmlData = try Bundle(for: XMLPathTest.self) + .testResourceFilePath(in: "Resources", for: "soapRequest.xml") + .readFileContents() + + let xmlDoc = try AEXMLDocument(xml: xmlData) + let xmlPath: XMLPath = "soap:Envelope.soap:Header.m:Trans" + let elementBefore = xmlDoc.resolve(path: xmlPath) + expect(elementBefore).toNot(beNil()) + let element = AEXMLElement(name: "ReplacedElement", value: "WithValue", attributes: [:]) + expect(xmlDoc.replace(path: xmlPath, with: element)).to(beTrue()) + expect(xmlDoc.resolve(path: xmlPath)).to(beNil()) + let elementAfter = xmlDoc.resolve(path: "soap:Envelope.soap:Header.ReplacedElement") + expect(elementAfter?.xml).to(equal(element.xml)) + expect(elementAfter?.xml).toNot(equal(elementBefore?.xml)) + } catch { + ALog("Test-case failed with exception: [\(error)]") + Nimble.fail("Failed with error \(error)") + } + } + + func testAEXMLDocument_replace_path_when_not_found() { + let xmlPath: XMLPath = "soap:Envelope.soap:NoHeader.m:NoTrans" + let elementBefore = soapRequest.resolve(path: xmlPath) + expect(elementBefore).to(beNil()) + let element = AEXMLElement(name: "ReplacedElement", value: "WithValue", attributes: [:]) + expect(self.soapRequest.replace(path: xmlPath, with: element)).to(beFalse()) + let elementAfter = soapRequest.resolve(path: xmlPath) + expect(elementAfter).to(beNil()) + } + + func testAEXMLDocument_replace_path_root_should_fail() { + let xmlPath: XMLPath = "soap:Envelope" + let elementBefore = soapRequest.resolve(path: xmlPath) + expect(elementBefore).toNot(beNil()) + let element = AEXMLElement(name: "ReplacedElement", value: "WithValue", attributes: [:]) + expect(self.soapRequest.replace(path: xmlPath, with: element)).to(beFalse()) + let elementAfter = soapRequest.resolve(path: xmlPath) + expect(elementBefore?.xml).to(equal(elementAfter?.xml)) + } + + static var allTests = [ + ("testXMLPath", testXMLPath), + ("testAEXMLDocument_resolve_path", testAEXMLDocument_resolve_path), + ("testAEXMLDocument_resolve_path_element_with_attribute", + testAEXMLDocument_resolve_path_element_with_attribute), + ("testAEXMLDocument_resolve_path_element_at_index", testAEXMLDocument_resolve_path_element_at_index), + ("testAEXMLDocument_replace_path_root_should_fail", testAEXMLDocument_replace_path_root_should_fail), + ("testAEXMLDocument_replace_path_when_not_found", testAEXMLDocument_replace_path_when_not_found), + ("testAEXMLDocument_replace_path", testAEXMLDocument_replace_path), + ] +} diff --git a/Package.resolved b/Package.resolved index f03ac95..e3dfe02 100644 --- a/Package.resolved +++ b/Package.resolved @@ -71,6 +71,24 @@ "revision" : "e19c2961ad48cf8897b679bde109988cf96fbb59", "version" : "1.3.0" } + }, + { + "identity" : "swift-docc-plugin", + "kind" : "remoteSourceControl", + "location" : "https://github.com/apple/swift-docc-plugin", + "state" : { + "revision" : "26ac5758409154cc448d7ab82389c520fa8a8247", + "version" : "1.3.0" + } + }, + { + "identity" : "swift-docc-symbolkit", + "kind" : "remoteSourceControl", + "location" : "https://github.com/apple/swift-docc-symbolkit", + "state" : { + "revision" : "b45d1f2ed151d057b54504d653e0da5552844e34", + "version" : "1.0.0" + } } ], "version" : 2 diff --git a/Package.swift b/Package.swift index e15657c..25d36f9 100644 --- a/Package.swift +++ b/Package.swift @@ -30,6 +30,7 @@ let package = Package( .package(url: "https://github.com/gematik/ASN1Kit.git", from: "1.2.0"), .package(url: "https://github.com/gematik/OpenSSL-Swift", from: "4.2.0"), .package(url: "https://github.com/gematik/ref-GemCommonsKit", from: "1.3.0"), + .package(url: "https://github.com/apple/swift-docc-plugin", from: "1.3.0"), ], targets: [ .target( @@ -37,9 +38,9 @@ let package = Package( dependencies: [ "HealthCardControl", "HealthCardAccess", - "Helper", - .product(name: "GemCommonsKit", package: "ref-GemCommonsKit"), - "DataKit" + "Helper", + .product(name: "GemCommonsKit", package: "ref-GemCommonsKit"), + "DataKit" ] ), .target( diff --git a/README.adoc b/README.adoc index 4ea7e02..318bf41 100644 --- a/README.adoc +++ b/README.adoc @@ -15,13 +15,19 @@ Execute `make readme` after editing /README.adoc Controlling/Use-case framework for accessing smart cards of the telematic infrastructure. include::doc/userguide/OHCKIT_Introduction.adoc[] + include::doc/userguide/OHCKIT_API.adoc[] + include::doc/userguide/OHCKIT_GettingStarted.adoc[] include::doc/userguide/OHCKIT_Overview.adoc[] + include::doc/userguide/OHCKIT_CardReaderProviderApi.adoc[] + include::doc/userguide/OHCKIT_HealthCardAccess.adoc[] + include::doc/userguide/OHCKIT_HealthCardControl.adoc[] + include::doc/userguide/OHCKIT_NFCCardReaderProvider.adoc[] include::doc/userguide/OHCKIT_NFCDemo.adoc[] diff --git a/ReleaseNotes.md b/ReleaseNotes.md index 8458ce2..261f7b1 100644 --- a/ReleaseNotes.md +++ b/ReleaseNotes.md @@ -1,3 +1,8 @@ +# 5.9.0 + + - Publish CardSimulator loading/running code for running IntegrationTests (CardSimulation itself cannot be public though) + - Refresh some documentation + # Release 5.8.0 ## Changed diff --git a/Sources/NFCCardReaderProvider/Reader/CoreNFCError.swift b/Sources/NFCCardReaderProvider/Reader/CoreNFCError.swift index 3691f49..5a27bb5 100644 --- a/Sources/NFCCardReaderProvider/Reader/CoreNFCError.swift +++ b/Sources/NFCCardReaderProvider/Reader/CoreNFCError.swift @@ -71,3 +71,8 @@ extension Swift.Error { } #endif + +// This is a dummy implementation for non-iOS platforms so that `swift build` is able to compile the code. +#if !os(iOS) +public enum CoreNFCError: Swift.Error {} +#endif diff --git a/devops/Jenkinsfile b/devops/Jenkinsfile new file mode 100644 index 0000000..94572ce --- /dev/null +++ b/devops/Jenkinsfile @@ -0,0 +1,93 @@ +import org.jenkinsci.plugins.pipeline.modeldefinition.Utils + +pipeline { + agent { label 'IOSDEV2' } + + triggers { + gitlab( + triggerOnNoteRequest: true, + noteRegex: "[jJ]enkins" + ) + } + + environment { + KEYCHAIN_PASSWORD = credentials('KEYCHAIN_PASSWORD') + MATCH_GIT_URL = credentials('MATCH_GIT_URL') + MATCH_USERNAME = credentials('MATCH_USERNAME') + MATCH_PASSWORD = credentials('MATCH_PASSWORD') + APP_STORE_CONNECT = credentials('APPSTORE-CONNECT_API-KEY') + NEXUS_CREDENTIALS = credentials('Nexus') + + APP_STORE_CONNECT_API_KEY_KEY_ID = "${APP_STORE_CONNECT_USR}" + APP_STORE_CONNECT_API_KEY_KEY = "${APP_STORE_CONNECT_PSW}" + + GEMATIK_DEVELOPMENT = "true" + } + + options { + ansiColor('xterm') + copyArtifactPermission('*') + } + + stages { + stage('Setup') { + steps { + sh label: 'Install maven for integration tests', script: '''#!/bin/bash -l + if [ -f $HOME/.bash_profile ]; then source $HOME/.bash_profile; fi + + brew list maven || brew install maven + ''' + } + } + + stage('Fastlane cibuild') { + steps { + sh label: 'starting ios test run', script: '''#!/bin/bash -l + if [ -f $HOME/.bash_profile ]; then source $HOME/.bash_profile; fi + + security -v unlock-keychain -p "${KEYCHAIN_PASSWORD}" ~/Library/Keychains/login.keychain + + make cibuild + ''' + } + } + + stage('Distribute to Appstore') { + when { + anyOf { + branch pattern: "release/.*", comparator: "REGEXP"; + expression { + return params.DEPLOY_TO_APPSTORE + } + } + } + + steps { + sh label: 'list build environment', script: '''#!/bin/bash -l + sw_vers + rvm list + brew list --versions + ''' + + // Build and Upload Appstore IPA + sh label: 'start build and uload AppStore IPA', script: '''#!/bin/bash -l + if [ -f $HOME/.bash_profile ]; then source $HOME/.bash_profile; fi + + set -ev + + security -v unlock-keychain -p "${KEYCHAIN_PASSWORD}" ~/Library/Keychains/login.keychain + + make setup + bundle exec fastlane publish + ''' + } + } + } + + post { + always { + archiveArtifacts artifacts: 'artifacts/**,fastlane/test_output/*,DerivedData/Logs/Test/**', excludes: 'artifacts/**/*.xcarchive/**', allowEmptyArchive: true + junit 'fastlane/test_output/report.junit' + } + } +} \ No newline at end of file diff --git a/doc/userguide/OHCKIT_GettingStarted.adoc b/doc/userguide/OHCKIT_GettingStarted.adoc index 402ea4c..e700f90 100644 --- a/doc/userguide/OHCKIT_GettingStarted.adoc +++ b/doc/userguide/OHCKIT_GettingStarted.adoc @@ -6,7 +6,7 @@ OpenHealthCardKit requires Swift 5.6. - **Swift Package Manager:** Put this in your `Package.swift`: - `.package(url: "https://github.com/gematik/ref-OpenHealthCardKit", from: "5.6.0"),` + .package(url: "https://github.com/gematik/ref-OpenHealthCardKit", from: "5.6.0"), - **Carthage:** Put this in your `Cartfile`: diff --git a/doc/userguide/OHCKIT_Overview.adoc b/doc/userguide/OHCKIT_Overview.adoc index 78457d0..82fc1a4 100644 --- a/doc/userguide/OHCKIT_Overview.adoc +++ b/doc/userguide/OHCKIT_Overview.adoc @@ -10,5 +10,4 @@ OpenHealthCardKit consists of the submodules - HealthCardControl - NFCCardReaderProvider -As a reference for each submodule see also the `IntegrationTests`. -Also see a https://github.com/gematik/ref-OpenHealthCardApp-iOS[Demo App] on GitHub using this framework. \ No newline at end of file +As a reference for the usage of each submodule see also the `IntegrationTests`. \ No newline at end of file