/** * Copyright (c) 2020, Bosch Rexroth AG * All rights reserved. * * BSD-3-Clause * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this * list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * 3. Neither the name of the copyright holder nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ //The example app datalayer.register.node creates a new provider //with node 'myData' and different type elements to the ctrlX Data Layer. #include "comm/datalayer/datalayer.h" #include "comm/datalayer/datalayer_system.h" #include #include #include //Add some signal Handling so we are able to abort the program with sending sigint bool endProcess = false; static void sigHandler (int sig, siginfo_t *siginfo, void *context) { endProcess = true; } using comm::datalayer::IProviderNode; //Basic class Provider node interface for providing data to the system class MyProviderNode : public IProviderNode { public: MyProviderNode(comm::datalayer::Variant value) { m_data = value; }; virtual ~MyProviderNode() override {}; //Create function of an object. Function will be called whenever a object should be created. virtual void onCreate(const std::string &address, const comm::datalayer::Variant* data, const comm::datalayer::IProviderNode::ResponseCallback &callback) override { callback(comm::datalayer::DlResult::DL_FAILED, nullptr); } //Read function of a node. Function will be called whenever a node should be read. virtual void onRead(const std::string &address, const comm::datalayer::Variant* data, const comm::datalayer::IProviderNode::ResponseCallback &callback) override { comm::datalayer::Variant result; result = m_data; callback(comm::datalayer::DlResult::DL_OK, &result); } //Write function of a node. Function will be called whenever a node should be written. virtual void onWrite(const std::string &address, const comm::datalayer::Variant* data, const comm::datalayer::IProviderNode::ResponseCallback &callback) override { if(data->getType() == m_data.getType()) { m_data = *data; callback(comm::datalayer::DlResult::DL_OK, data); } else { callback(comm::datalayer::DlResult::DL_TYPE_MISMATCH, nullptr); } } //Remove function for an object. Function will be called whenever a object should be removed. virtual void onRemove(const std::string &address, const comm::datalayer::IProviderNode::ResponseCallback &callback) override { callback(comm::datalayer::DlResult::DL_FAILED, nullptr); } //Browse function of a node. Function will be called to determine children of a node. virtual void onBrowse(const std::string &address, const comm::datalayer::IProviderNode::ResponseCallback &callback) override { callback(comm::datalayer::DlResult::DL_FAILED, nullptr); } //Read function of metadata of an object. Function will be called whenever a node should be written. virtual void onMetadata(const std::string &address, const comm::datalayer::IProviderNode::ResponseCallback &callback) override { callback(comm::datalayer::DlResult::DL_UNSUPPORTED, nullptr); } private: comm::datalayer::Variant m_data; }; int main(int ac, char* av[]) { comm::datalayer::DatalayerSystem datalayer; comm::datalayer::DlResult result; //Starts the ctrlX Data Layer system without a new broker because one broker is already running on ctrlX device datalayer.start(false); std::cout << "Register 'myData' as root element with 3 nodes 'myFloat', 'myString' and 'myInt64'" << std::endl; //Creates a provider at Data Layer backend to provide data to Data Layer clients comm::datalayer::IProvider *myProvider = datalayer.factory()->createProvider("tcp://boschrexroth:boschrexroth@127.0.0.1:2070"); //or "tcp://boschrexroth:boschrexroth@192.168.1.1:2070" //Create some dummy data comm::datalayer::Variant myString; myString.setValue("Hello ctrlX AUTOMATION sample string"); comm::datalayer::Variant myFloat; myFloat.setValue(0.815f); comm::datalayer::Variant myInt64; myInt64.setValue((int64_t)-123456789); //Register a node as float value result = myProvider->registerNode("myData/myString", new MyProviderNode(myString)); if(STATUS_FAILED(result)) { std::cout << "Register node 'myData/myString' failed with: " << result.toString() << std::endl; } else { std::cout << "Register node 'myData/myString' was successful!" << std::endl; } result = myProvider->registerNode("myData/myFloat", new MyProviderNode(myFloat)); if(STATUS_FAILED(result)) { std::cout << "Register node 'myData/myFloat' failed with: " << result.toString() << std::endl; } else { std::cout << "Register node 'myData/myFloat' was successful!" << std::endl; } result = myProvider->registerNode("myData/myInt64", new MyProviderNode(myInt64)); if(STATUS_FAILED(result)) { std::cout << "Register node 'myData/myInt64' failed with: " << result.toString() << std::endl; } else { std::cout << "Register node 'myData/myInt64' was successful!" << std::endl; } //Start to add Code here to register more nodes //Start your ctrlX Data Layer provider result = myProvider->start(); if (STATUS_FAILED(result)) { std::cout << "Starting the Data Layer provider failed with: " << result.toString() << std::endl; //If the provider could not be started exit the program return -1; } else { std::cout << "Provider was started!" << std::endl; } std::this_thread::sleep_for(std::chrono::milliseconds(500)); if (!myProvider->isConnected()) { std::cout << "Failed to connect to Data Layer broker!" << std::endl; return -1; } //Prepare signal structure to interrupt the endless loop with ctrl + c struct sigaction act; memset (&act, '\0', sizeof(act)); act.sa_sigaction = &sigHandler; act.sa_flags = SA_SIGINFO; sigaction(SIGINT, &act, NULL); do { /* code */ //Time to interrupt this thread for lower cpu utilization std::this_thread::sleep_for(std::chrono::milliseconds(500)); } while (!endProcess); //Stop Datalayer Provider myProvider->stop(); std::cout << std::endl << "Provider was stopped!" << std::endl; //Delete it to free your memory delete myProvider; std::cout << "Provider was deleted!" << std::endl; }