00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include "opcua_options.h"
00013
00014 #include <opc/ua/client/addon.h>
00015 #include <opc/common/addons_core/addon_manager.h>
00016 #include <opc/common/addons_core/config_file.h>
00017 #include <opc/common/uri_facade.h>
00018 #include <opc/ua/node.h>
00019 #include <opc/ua/protocol/string_utils.h>
00020 #include <opc/ua/protocol/variant_visitor.h>
00021 #include <opc/ua/services/services.h>
00022
00023 #include <iostream>
00024 #include <stdexcept>
00025
00026 namespace
00027 {
00028
00029 using namespace OpcUa;
00030
00031 struct Tabs
00032 {
00033 Tabs(unsigned num = 0)
00034 : Num(num)
00035 {
00036 }
00037 unsigned Num;
00038 };
00039
00040 std::ostream& operator <<(std::ostream& os, const Tabs& tabs)
00041 {
00042 for (unsigned i = 0; i < tabs.Num; ++i)
00043 {
00044 os << " ";
00045 }
00046 return os;
00047 }
00048
00049
00050 std::string GetName(OpcUa::MessageSecurityMode mode)
00051 {
00052 switch (mode)
00053 {
00054 case MessageSecurityMode::None:
00055 return "none";
00056 case MessageSecurityMode::Sign:
00057 return "sign";
00058 case MessageSecurityMode::SignAndEncrypt:
00059 return "sign and encrypt";
00060
00061 default:
00062 return "unknown";
00063 }
00064 }
00065
00066 std::string GetName(OpcUa::ApplicationType type)
00067 {
00068 switch (type)
00069 {
00070 case OpcUa::ApplicationType::Server:
00071 return "server";
00072 case OpcUa::ApplicationType::Client:
00073 return "client";
00074 case OpcUa::ApplicationType::ClientAndServer:
00075 return "client and server";
00076 case OpcUa::ApplicationType::DiscoveryServer:
00077 return "discovery server";
00078 default:
00079 return "unknown";
00080 }
00081 }
00082
00083 std::string GetName(OpcUa::UserTokenType type)
00084 {
00085 switch (type)
00086 {
00087 case OpcUa::UserTokenType::Anonymous:
00088 return "anonymous";
00089 case OpcUa::UserTokenType::UserName:
00090 return "username";
00091 case OpcUa::UserTokenType::Certificate:
00092 return "x509v3 certificate";
00093 case OpcUa::UserTokenType::IssuedToken:
00094 return "WS_Security token";
00095 default:
00096 return "unknown";
00097 }
00098 };
00099
00100 std::string GetNodeClassName(unsigned cls)
00101 {
00102 std::string result;
00103 NodeClass nodeClass = static_cast<NodeClass>(cls);
00104 if (nodeClass == NodeClass::Object)
00105 {
00106 result += "object";
00107 }
00108
00109 if (nodeClass == NodeClass::Variable)
00110 {
00111 if (!result.empty())
00112 {
00113 result += ", ";
00114 }
00115 result += "variable";
00116 }
00117
00118 if (nodeClass == NodeClass::Method)
00119 {
00120 if (!result.empty())
00121 {
00122 result += ", ";
00123 }
00124 result += "method";
00125 }
00126
00127 if (nodeClass == NodeClass::ObjectType)
00128 {
00129 if (!result.empty())
00130 {
00131 result += ", ";
00132 }
00133 result += "object type";
00134 }
00135
00136 if (nodeClass == NodeClass::VariableType)
00137 {
00138 if (!result.empty())
00139 {
00140 result += ", ";
00141 }
00142 result += "variable type";
00143 }
00144
00145 if (nodeClass == NodeClass::ReferenceType)
00146 {
00147 if (!result.empty())
00148 {
00149 result += ", ";
00150 }
00151 result += "reference type";
00152 }
00153
00154 if (nodeClass == NodeClass::DataType)
00155 {
00156 if (!result.empty())
00157 {
00158 result += ", ";
00159 }
00160 result += "data type";
00161 }
00162
00163 if (nodeClass == NodeClass::View)
00164 {
00165 if (!result.empty())
00166 {
00167 result += ", ";
00168 }
00169 result += "view";
00170 }
00171
00172 return result;
00173 }
00174
00175
00176
00177
00178 void Print(const OpcUa::NodeId& nodeId, const Tabs& tabs)
00179 {
00180 OpcUa::NodeIdEncoding encoding = static_cast<OpcUa::NodeIdEncoding>(nodeId.Encoding & OpcUa::NodeIdEncoding::EV_VALUE_MASK);
00181
00182 const Tabs dataTabs(tabs.Num + 2);
00183 switch (encoding)
00184 {
00185 case OpcUa::NodeIdEncoding::EV_TWO_BYTE:
00186 {
00187 std::cout << tabs << "Two byte:" << std::endl;
00188 std::cout << dataTabs << "Identifier:" << (unsigned)nodeId.TwoByteData.Identifier << std::endl;
00189 break;
00190 }
00191
00192 case OpcUa::NodeIdEncoding::EV_FOUR_BYTE:
00193 {
00194 std::cout << tabs << "Four byte:" << std::endl;
00195 std::cout << dataTabs << "NamespaceIndex:" << (unsigned)nodeId.FourByteData.NamespaceIndex << std::endl;
00196 std::cout << dataTabs << "Identifier" << (unsigned)nodeId.FourByteData.Identifier << std::endl;
00197 break;
00198 }
00199
00200 case OpcUa::NodeIdEncoding::EV_NUMERIC:
00201 {
00202 std::cout << tabs << "Numeric:" << std::endl;
00203 std::cout << dataTabs << "NamespaceIndex" << (unsigned)nodeId.NumericData.NamespaceIndex << std::endl;
00204 std::cout << dataTabs << "Identifier" << (unsigned)nodeId.NumericData.Identifier << std::endl;
00205 break;
00206 }
00207
00208 case OpcUa::NodeIdEncoding::EV_STRING:
00209 {
00210 std::cout << tabs << "String: " << std::endl;
00211 std::cout << dataTabs << "NamespaceIndex: " << (unsigned)nodeId.StringData.NamespaceIndex << std::endl;
00212 std::cout << dataTabs << "Identifier: " << nodeId.StringData.Identifier << std::endl;
00213 break;
00214 }
00215
00216 case OpcUa::NodeIdEncoding::EV_BYTE_STRING:
00217 {
00218 std::cout << tabs << "Binary: " << std::endl;
00219 std::cout << dataTabs << "NamespaceIndex: " << (unsigned)nodeId.BinaryData.NamespaceIndex << std::endl;
00220 std::cout << dataTabs << "Identifier: ";
00221 for (auto val : nodeId.BinaryData.Identifier) {std::cout << (unsigned)val; }
00222 std::cout << std::endl;
00223 break;
00224 }
00225
00226 case OpcUa::NodeIdEncoding::EV_GUId:
00227 {
00228 std::cout << tabs << "Guid: " << std::endl;
00229 std::cout << dataTabs << "Namespace Index: " << (unsigned)nodeId.GuidData.NamespaceIndex << std::endl;
00230 const OpcUa::Guid& guid = nodeId.GuidData.Identifier;
00231 std::cout << dataTabs << "Identifier: " << std::hex << guid.Data1 << "-" << guid.Data2 << "-" << guid.Data3;
00232 for (auto val : guid.Data4) {std::cout << (unsigned)val; }
00233 break;
00234 }
00235 default:
00236 {
00237 std::cout << tabs << "unknown id type:" << (unsigned)encoding << std::endl;
00238 break;
00239 }
00240 }
00241
00242 if (nodeId.Encoding & OpcUa::NodeIdEncoding::EV_NAMESPACE_URI_FLAG)
00243 {
00244 std::cout << tabs << "Namespace URI: " << nodeId.NamespaceURI << std::endl;
00245 }
00246
00247 if (nodeId.Encoding & OpcUa::NodeIdEncoding::EV_Server_INDEX_FLAG)
00248 {
00249 std::cout << tabs << "Server index: " << nodeId.ServerIndex << std::endl;
00250 }
00251 }
00252
00253 void Print(const OpcUa::UserTokenPolicy& policy, const Tabs& tabs)
00254 {
00255 std::cout << tabs << "Id: " << policy.PolicyId << std::endl;
00256 std::cout << tabs << "TokenType: " << GetName(policy.TokenType) << std::endl;
00257 std::cout << tabs << "IssuedTokenType: " << policy.IssuedTokenType << std::endl;
00258 std::cout << tabs << "IssuerEndpointUrl: " << policy.IssuerEndpointUrl << std::endl;
00259 std::cout << tabs << "SecurityPolicyUri: " << policy.SecurityPolicyUri << std::endl;
00260 };
00261
00262
00263 void Print(const OpcUa::ApplicationDescription& desc, const Tabs& tab)
00264 {
00265 std::cout << tab << "Name: " << desc.ApplicationName.Text << " (" << desc.ApplicationName.Locale << ")" << std::endl;
00266 std::cout << tab << "Type: " << GetName(desc.ApplicationType) << std::endl;
00267 std::cout << tab << "URI: " << desc.ApplicationUri << std::endl;
00268 std::cout << tab << "ProductURI: " << desc.ProductUri << std::endl;
00269 std::cout << tab << "GatewayServerURI: " << desc.GatewayServerUri << std::endl;
00270 std::cout << tab << "DiscoveryProfileURI: " << desc.DiscoveryProfileUri << std::endl;
00271 if (!desc.DiscoveryUrls.empty())
00272 {
00273 std::cout << tab << "DiscoveryProfileURLs: ";
00274 for (auto it = desc.DiscoveryUrls.begin(); it != desc.DiscoveryUrls.end(); ++it)
00275 {
00276 std::cout << "'" << *it << "' ";
00277 }
00278 std::cout << std::endl;
00279 }
00280 }
00281
00282 void Print(const OpcUa::EndpointDescription& desc, const Tabs& tab)
00283 {
00284 std::cout << tab << "URL: " << desc.EndpointUrl << std::endl;
00285 std::cout << tab << "SecurityPolicyUri: " << desc.SecurityPolicyUri << std::endl;
00286 std::cout << tab << "SecurityLevel: " << GetName(desc.SecurityMode) << " (" << (int)desc.SecurityMode << ")" << std::endl;
00287 std::cout << tab << "TransportProfileURI: " << desc.TransportProfileUri << std::endl;
00288 std::cout << tab << "SecurityLevel: " << (int)desc.SecurityLevel << std::endl;
00289 std::cout << tab << "Server description: " << std::endl;
00290 Print(desc.Server, Tabs(tab.Num + 2));
00291
00292 if (!desc.UserIdentityTokens.empty())
00293 {
00294 std::cout << tab << "User identify tokens: " << std::endl;
00295 for (auto it = desc.UserIdentityTokens.begin(); it != desc.UserIdentityTokens.end(); ++it)
00296 {
00297 std::cout << Tabs(tab.Num + 2) << "token: " << std::endl;
00298 Print(*it, Tabs(tab.Num + 4));
00299 }
00300 std::cout << std::endl;
00301 }
00302
00303
00304 }
00305
00306 void PrintEndpoints(OpcUa::Services& computer)
00307 {
00308 std::shared_ptr<OpcUa::EndpointServices> service = computer.Endpoints();
00309 OpcUa::GetEndpointsParameters filter;
00310 std::vector<OpcUa::EndpointDescription> endpoints = service->GetEndpoints(filter);
00311 for(auto it = endpoints.begin(); it != endpoints.end(); ++it)
00312 {
00313 std::cout << "endpoint:" << std::endl;
00314 Print(*it, Tabs(2));
00315 }
00316 }
00317
00318 void PrintServers(OpcUa::Services& computer)
00319 {
00320 std::shared_ptr<OpcUa::EndpointServices> service = computer.Endpoints();
00321 OpcUa::FindServersParameters filter;
00322 std::vector<OpcUa::ApplicationDescription> applications = service->FindServers(filter);
00323 for(const OpcUa::ApplicationDescription& desc : applications)
00324 {
00325 std::cout << "Application:" << std::endl;
00326 Print(desc, Tabs(2));
00327 }
00328 }
00329
00330 inline void PrintReference(const OpcUa::ReferenceDescription& desc, const Tabs& tabs)
00331 {
00332 const Tabs tabs1(tabs.Num + 2);
00333 std::cout << tabs << "DisplayName: " << desc.DisplayName.Text << std::endl;
00334 std::cout << tabs << "Browse Name: " << desc.BrowseName.NamespaceIndex << ":" << desc.BrowseName.Name << std::endl;
00335 std::cout << tabs << "Is Forward: " << desc.IsForward << std::endl;
00336
00337 std::cout << tabs << "Target Node class: " << GetNodeClassName(static_cast<unsigned>(desc.TargetNodeClass)) << std::endl;
00338 std::cout << tabs << "Target NodeId:" << std::endl;
00339 Print(desc.TargetNodeId, tabs1);
00340
00341 std::cout << tabs << "TypeId:" << std::endl;
00342 Print(desc.ReferenceTypeId, tabs1);
00343
00344 std::cout << tabs << "Type definition Id:" << std::endl;
00345 Print(desc.TargetNodeTypeDefinition, tabs1);
00346 }
00347
00348 void Browse(OpcUa::ViewServices& view, OpcUa::NodeId nodeId)
00349 {
00350 OpcUa::BrowseDescription description;
00351 description.NodeToBrowse = nodeId;
00352 description.Direction = OpcUa::BrowseDirection::Forward;
00353 description.IncludeSubtypes = true;
00354 description.NodeClasses = OpcUa::NodeClass::Unspecified;
00355 description.ResultMask = OpcUa::BrowseResultMask::All;
00356
00357 OpcUa::NodesQuery query;
00358 query.View.Timestamp = OpcUa::DateTime::Current();
00359 query.NodesToBrowse.push_back(description);
00360 query.MaxReferenciesPerNode = 100;
00361
00362 std::vector<OpcUa::BrowseResult> results = view.Browse(query);
00363 while(true)
00364 {
00365 if (results.empty() )
00366 {
00367 return;
00368 }
00369 if (results[0].Referencies.empty())
00370 {
00371 break;
00372 }
00373 for (auto refIt : results[0].Referencies)
00374 {
00375 std::cout << "reference:" << std::endl;
00376 PrintReference(refIt, Tabs(2));
00377 std::cout << std::endl;
00378 }
00379 results = view.BrowseNext();
00380 }
00381 }
00382
00383
00384 struct VariantPrinter
00385 {
00386 template <typename T>
00387 void PrintVallue(const T& val)
00388 {
00389 std::cout << val;
00390 }
00391
00392 void PrintValue(const OpcUa::DiagnosticInfo& info)
00393 {
00394 std::cout << "!!!TODO!!!";
00395 }
00396
00397 void PrintValue(const OpcUa::Variant& info)
00398 {
00399 std::cout << "!!!TODO!!!";
00400 }
00401
00402 void PrintValue(const OpcUa::LocalizedText& text)
00403 {
00404 std::cout << text.Text << std::endl;
00405 }
00406
00407 void PrintValue(const OpcUa::StatusCode& code)
00408 {
00409 std::cout << OpcUa::ToString(code) << std::endl;
00410 }
00411
00412 template <typename T>
00413 void OnScalar(const T& val)
00414 {
00415 PrintValue(val);
00416 std::cout << std::endl;
00417 }
00418
00419 template <typename T>
00420 void OnContainer(const std::vector<T>& vals)
00421 {
00422 typedef typename std::vector<T>::const_iterator Iterator;
00423 for (Iterator it = vals.begin(); it != vals.end(); ++it)
00424 {
00425 PrintValue(*it);
00426 std::cout << " ";
00427 }
00428 std::cout << std::endl;
00429 }
00430 };
00431
00432 void Print(const OpcUa::Variant& var, const Tabs& tabs)
00433 {
00434 VariantPrinter printer;
00435 TypedVisitor<VariantPrinter> visitor(printer);
00436
00437 switch (var.Type())
00438 {
00439 case VariantType::BOOLEAN:
00440 {
00441 std::cout << tabs << "boolean: ";
00442 break;
00443 }
00444 case VariantType::SBYTE:
00445 {
00446 std::cout << tabs << "signed byte: ";
00447 break;
00448 }
00449 case VariantType::BYTE:
00450 {
00451 std::cout << tabs << "byte: ";
00452 break;
00453 }
00454 case VariantType::INT16:
00455 {
00456 std::cout << tabs << "int16: ";
00457 break;
00458 }
00459 case VariantType::UINT16:
00460 {
00461 std::cout << tabs << "unsigned int16: ";
00462 break;
00463 }
00464 case VariantType::INT32:
00465 {
00466 std::cout << tabs << "int32: ";
00467 break;
00468 }
00469 case VariantType::UINT32:
00470 {
00471 std::cout << tabs << "unsigned int32: ";
00472 break;
00473 }
00474
00475 case VariantType::INT64:
00476 {
00477 std::cout << tabs << "int64: ";
00478 break;
00479 }
00480
00481
00482 case VariantType::UINT64:
00483 {
00484 std::cout << tabs << "unsigned int64: ";
00485 break;
00486 }
00487
00488
00489 case VariantType::FLOAT:
00490 {
00491 std::cout << tabs << "float: ";
00492 break;
00493 }
00494
00495
00496 case VariantType::DOUBLE:
00497 {
00498 std::cout << tabs << "double: ";
00499 break;
00500 }
00501
00502
00503 case VariantType::STRING:
00504 {
00505 std::cout << tabs << "string: ";
00506 break;
00507 }
00508
00509
00510 case VariantType::EXPANDED_NODE_Id:
00511 case VariantType::NODE_Id:
00512 {
00513 std::cout << tabs << "NodeId: " << std::endl;
00514 break;
00515 }
00516
00517 case VariantType::QUALIFIED_NAME:
00518 {
00519 std::cout << tabs << "Name: ";
00520 break;
00521 }
00522
00523 case VariantType::LOCALIZED_TEXT:
00524 {
00525 std::cout << tabs << "Text: ";
00526 break;
00527 }
00528
00529
00530 case VariantType::DATE_TIME:
00531 {
00532 std::cout << "DateTime: " << OpcUa::ToString(var.As<DateTime>()) << std::endl;
00533 break;
00534 }
00535 case VariantType::GUId:
00536 case VariantType::BYTE_STRING:
00537 case VariantType::XML_ELEMENT:
00538 case VariantType::STATUS_CODE:
00539 case VariantType::DIAGNOSTIC_INFO:
00540 case VariantType::VARIANT:
00541 case VariantType::DATA_VALUE:
00542 case VariantType::NUL:
00543 case VariantType::EXTENSION_OBJECT:
00544 break;
00545 default:
00546 throw std::logic_error("Unknown variant type.");
00547 }
00548 var.Visit(visitor);
00549 std::cout << std::endl;
00550 }
00551
00552 void Print(const DataValue& value, const Tabs& tabs)
00553 {
00554 const Tabs tabs1(tabs.Num + 2);
00555 if (value.Encoding & DATA_VALUE_STATUS_CODE)
00556 {
00557 std::cout << tabs << "Status code:" << std::endl;
00558 std::cout << tabs1 << "0x" << std::hex << static_cast<uint32_t>(value.Status) << std::endl;
00559 }
00560 if (value.Encoding & DATA_VALUE)
00561 {
00562 std::cout << tabs << "Value:" << std::endl;
00563 Print(value.Value, tabs1);
00564 }
00565 }
00566
00567
00568 void Read(OpcUa::AttributeServices& attributes, OpcUa::NodeId nodeId, OpcUa::AttributeId attributeId)
00569 {
00570 ReadParameters params;
00571 ReadValueId attribute;
00572 attribute.NodeId = nodeId;
00573 attribute.AttributeId = attributeId;
00574 params.AttributesToRead.push_back(attribute);
00575 const std::vector<DataValue> values = attributes.Read(params);
00576 if (values.size() != 1)
00577 {
00578 std::cout << "Server returned " << values.size() << " instead of 1." << std::endl;
00579 return;
00580 }
00581 std::cout << "data value:" << std::endl;
00582 Print(values.front(), Tabs(2));
00583 }
00584
00585 void Write(OpcUa::AttributeServices& attributes, OpcUa::NodeId nodeId, OpcUa::AttributeId attributeId, const OpcUa::Variant& value)
00586 {
00587 OpcUa::WriteValue attribute;
00588 attribute.NodeId = nodeId;
00589 attribute.AttributeId = attributeId;
00590 attribute.Value = value;
00591 std::vector<StatusCode> statuses = attributes.Write(std::vector<OpcUa::WriteValue>(1, attribute));
00592 for (OpcUa::StatusCode status : statuses)
00593 {
00594 std::cout << "Status code: 0x" << std::hex << static_cast<uint32_t>(status) << std::endl;
00595 }
00596 }
00597
00598 void CreateSubscription(OpcUa::SubscriptionServices& subscriptions)
00599 {
00600 OpcUa::CreateSubscriptionRequest request;
00601 request.Parameters.MaxNotificationsPerPublish = 1;
00602 request.Parameters.Priority = 0;
00603 request.Parameters.PublishingEnabled = false;
00604 request.Parameters.RequestedLifetimeCount = 1;
00605 request.Parameters.RequestedMaxKeepAliveCount = 1;
00606 request.Parameters.RequestedPublishingInterval = 1000;
00607 const OpcUa::SubscriptionData data = subscriptions.CreateSubscription(request, [](PublishResult){});
00608 std::cout << "Id: " << data.SubscriptionId << std::endl;
00609 std::cout << "RevisedPublishingInterval: " << data.RevisedPublishingInterval << std::endl;
00610 std::cout << "RevisedLifetimeCount: " << data.RevisedLifetimeCount << std::endl;
00611 std::cout << "RevisedMaxKeepAliveCount: " << data.RevisedMaxKeepAliveCount << std::endl;
00612 }
00613
00614 void Process(OpcUa::CommandLine& cmd, const Common::AddonsManager& addons)
00615 {
00616 const std::string serverURI = cmd.GetServerURI();
00617 const Common::Uri uri(serverURI);
00618 OpcUa::Client::Addon::SharedPtr addon = addons.GetAddon<OpcUa::Client::Addon>(uri.Scheme());
00619 std::shared_ptr<OpcUa::Services> computer = addon->Connect(serverURI);
00620
00621 if (cmd.IsGetEndpointsOperation())
00622 {
00623 PrintEndpoints(*computer);
00624 return;
00625 }
00626 else if (cmd.IsFindServersOperation())
00627 {
00628 PrintServers(*computer);
00629 }
00630
00631 OpcUa::RemoteSessionParameters session;
00632 session.ClientDescription.ApplicationUri = "https://github.com/treww/opc_layer.git";
00633 session.ClientDescription.ProductUri = "https://github.com/treww/opc_layer.git";
00634 session.ClientDescription.ApplicationName.Text = "opcua client";
00635 session.ClientDescription.ApplicationType = OpcUa::ApplicationType::Client;
00636 session.SessionName = "opua command line";
00637 session.EndpointUrl = serverURI;
00638 session.Timeout = 1200000;
00639
00640 CreateSessionResponse resp = computer->CreateSession(session);
00641 ActivateSessionParameters session_parameters;
00642 computer->ActivateSession(session_parameters);
00643
00644 if (cmd.IsBrowseOperation())
00645 {
00646 const OpcUa::NodeId nodeId = cmd.GetNodeId();
00647 Print(nodeId, Tabs(0));
00648 Browse(*computer->Views(), nodeId);
00649 }
00650 else if (cmd.IsReadOperation())
00651 {
00652 const OpcUa::NodeId nodeId = cmd.GetNodeId();
00653 const OpcUa::AttributeId attributeId = cmd.GetAttribute();
00654 Read(*computer->Attributes(), nodeId, attributeId);
00655 }
00656 else if (cmd.IsWriteOperation())
00657 {
00658 const OpcUa::NodeId nodeId = cmd.GetNodeId();
00659 const OpcUa::AttributeId attributeId = cmd.GetAttribute();
00660 const OpcUa::Variant value = cmd.GetValue();
00661 Write(*computer->Attributes(), nodeId, attributeId, value);
00662 }
00663 else if (cmd.IsCreateSubscriptionOperation())
00664 {
00665 CreateSubscription(*computer->Subscriptions());
00666 }
00667 else
00668 {
00669 std::cout << "nothing to do" << std::endl;
00670 }
00671
00672
00673 computer->CloseSession();
00674 }
00675
00676 int RegisterNewModule(const OpcUa::CommandLine& cmd)
00677 {
00678 std::cout << "Registering new module." << std::endl;
00679 const std::string& configDir = cmd.GetConfigDir();
00680 const std::string& addonId = cmd.GetModuleId();
00681 const std::string& modulePath = cmd.GetModulePath();
00682
00683 std::cout << "Id: " << addonId << std::endl;
00684 std::cout << "Path: " << modulePath << std::endl;
00685 std::cout << "Configuration file: " << configDir << std::endl;
00686
00687 Common::Configuration config = Common::ParseConfigurationFiles(configDir);
00688 const Common::ModulesConfiguration::const_iterator moduleIt = std::find_if(config.Modules.begin(), config.Modules.end(), [&addonId](const Common::ModuleConfiguration& config){return config.Id == addonId;});
00689 if (moduleIt != config.Modules.end())
00690 {
00691 std::cerr << "Module already registered." << std::endl;
00692 return -1;
00693 }
00694
00695 Common::ModuleConfiguration module;
00696 module.Id = addonId;
00697 module.Path = modulePath;
00698
00699 config.Modules.push_back(module);
00700 Common::SaveConfiguration(config.Modules, configDir);
00701 std::cout << "Successfully registered." << std::endl;
00702 return 0;
00703 }
00704
00705 int UnregisterModule(const OpcUa::CommandLine& cmd)
00706 {
00707 const Common::AddonId addonId = cmd.GetModuleId();
00708 const std::string& configDir = cmd.GetConfigDir();
00709 std::cout << "Unregistering module." << std::endl;
00710 std::cout << "Id: " << addonId << std::endl;
00711 std::cout << "Configuration file: " << configDir << std::endl;
00712
00713 Common::Configuration config = Common::ParseConfigurationFiles(configDir);
00714 Common::ModulesConfiguration::iterator moduleIt = std::find_if(config.Modules.begin(), config.Modules.end(), [&addonId](const Common::ModuleConfiguration& config){return config.Id == addonId;});
00715 if (moduleIt == config.Modules.end())
00716 {
00717 std::cerr << "Module not found" << std::endl;
00718 return -1;
00719 }
00720 config.Modules.erase(moduleIt);
00721 Common::SaveConfiguration(config.Modules, configDir);
00722
00723 std::cout << "Successfully unregistered." << std::endl;
00724 return 0;
00725 }
00726 }
00727
00728 int main(int argc, char** argv)
00729 {
00730 try
00731 {
00732 OpcUa::CommandLine cmd(argc, argv);
00733 if (cmd.IsHelpOperation())
00734 {
00735 return 0;
00736 }
00737
00738 if (cmd.IsRegisterModuleOperation())
00739 {
00740 return RegisterNewModule(cmd);
00741 }
00742
00743 if (cmd.IsUnregisterModuleOperation())
00744 {
00745 return UnregisterModule(cmd);
00746 }
00747
00748 const std::string configDir = cmd.GetConfigDir();
00749 const Common::Configuration& config = Common::ParseConfigurationFiles(configDir);
00750
00751 std::vector<Common::AddonInformation> infos(config.Modules.size());
00752 std::transform(config.Modules.begin(), config.Modules.end(), infos.begin(), std::bind(&Common::GetAddonInfomation, std::placeholders::_1));
00753
00754 Common::AddonsManager::UniquePtr manager = Common::CreateAddonsManager();
00755 std::for_each(infos.begin(), infos.end(), [&manager](const Common::AddonInformation& addon){
00756 manager->Register(addon);
00757 });
00758 manager->Start();
00759 Process(cmd, *manager);
00760 manager->Stop();
00761 return 0;
00762 }
00763 catch (const std::exception& exc)
00764 {
00765 std::cout << exc.what() << std::endl;
00766 }
00767 catch (...)
00768 {
00769 std::cout << "Unknown error." << std::endl;
00770 }
00771 return -1;
00772 }
00773