Esempio n. 1
0
 // Set the publishing mode
 // =============================================================================================
 Status Subscription::setPublishingMode(
         bool                   publishingEnabled,
         const ServiceSettings& serviceSettings)
 {
     OpcUa_Boolean uaPublishingEnabled = publishingEnabled ? OpcUa_True : OpcUa_False;
     UaClientSdk::ServiceSettings uaServiceSettings;
     serviceSettings.toSdk(uaServiceSettings);
     UaStatus uaStatus = uaSubscription_->setPublishingMode(uaServiceSettings,
                                                            uaPublishingEnabled);
     Status ret;
     ret.fromSdk(uaStatus.statusCode(), "Couldn't set the publishing mode");
     return ret;
 }
Esempio n. 2
0
    Status Subscription::createSubscription()
    {

        logger_->debug("Creating the subscription to the server");

        Status ret;

        UaClientSdk::ServiceSettings serviceSettings;

        UaClientSdk::SubscriptionSettings subscriptionSettings;
        subscriptionSettings = toSdk(subscriptionSettings_);

        UaStatus uaStatus = uaSession_->createSubscription(
                serviceSettings,
                uaSubscriptionCallback_,
                clientSubscriptionHandle_,
                subscriptionSettings,
                OpcUa_True,
                &uaSubscription_);

        ret.fromSdk(uaStatus.statusCode(), "Could not create the subscription to the server");

        if (ret.isGood())
        {
            subscriptionState_ = uafc::subscriptionstates::Created;
            logger_->debug("The subscription has been successfully created to the server");
        }
        else
        {
            subscriptionState_ = uafc::subscriptionstates::Deleted;
            ret.addDiagnostic("Subscription creation to the server failed");
            logger_->error(ret);
        }

        return ret;
    }
Esempio n. 3
0
    Status Subscription::deleteSubscription()
    {
        Status ret;

        if (uaSession_->isConnected())
        {

            if (isCreated())
            {
                logger_->debug("Now deleting subscription %d and thereby deleting all monitored items",
                               clientSubscriptionHandle_);
                UaClientSdk::ServiceSettings serviceSettings;
                UaStatus uaStatus = uaSession_->deleteSubscription(serviceSettings, &uaSubscription_);

                ret.fromSdk(uaStatus.statusCode(), "Could not delete the subscription");
            }
            else
            {
                logger_->debug("No need to delete subscription %d on the server side, as it was " \
                               "already deleted", clientSubscriptionHandle_);
                ret.setGood();
            }
        }
        else
        {
            ret.setStatus(statuscodes::ConnectionError, "Could not delete the subscription");
        }

        // now update the persistent requests
        MonitoredItemsMap::iterator it = monitoredItemsMap_.begin();
        while (it != monitoredItemsMap_.end())
        {
            // remove the notification buffer according to the kind
            if (it->second.settings.kind() == MonitoredItemSettings::Data)
            {
                database_->createMonitoredDataRequestStore.updateTargetStatus(
                        it->second.requestHandle,
                        it->second.targetRank,
                        Status(statuscodes::SubscriptionError, "The subscription was deleted"));
            }
            else
            {
                database_->createMonitoredEventsRequestStore.updateTargetStatus(
                        it->second.requestHandle,
                        it->second.targetRank,
                        Status(statuscodes::SubscriptionError, "The subscription was deleted"));
            }

            // remove the monitoredItemsMap_ entry
            monitoredItemsMap_.erase(it++);
        }

        // log the result
        if (ret.isGood())
        {
            logger_->debug("The subscription has been deleted successfully");
            setSubscriptionState(uafc::subscriptionstates::Deleted);
        } else
        {
            logger_->error(ret);
        }

        return ret;
    }
    // Invoke the service synchronously
    // =============================================================================================
    Status HistoryReadRawModifiedInvocation::invokeSyncSdkService(UaClientSdk::UaSession* uaSession)
    {
        Status ret;

        UaStatus uaStatus = uaSession->historyReadRawModified(
                uaServiceSettings_,
                uaContext_,
                uaNodesToRead_,
                uaResults_);

        ret.fromSdk(uaStatus.statusCode(), "Synchronous HistoryRead invocation failed");

        uint32_t autoReadMore    = 0;
        uint32_t maxAutoReadMore = this->serviceSettings().maxAutoReadMore;

        // do we still have to automatically invoke another read, or are we finished?
        bool finished = (maxAutoReadMore == 0);


        // if we're not finished already, and the initial request was successful, we
        // may need to invoke the history read service again
        while ((!finished) && ret.isGood())
        {
            UaHistoryReadValueIds               uaNextNodesToRead;
            UaClientSdk::HistoryReadDataResults uaNextResults;
            vector<uint32_t>                    ranks; // the rank numbers of the original request

            // loop through the results and append "unfinished" read results to the
            // variables for the next read call, as defined above
            for (uint32_t i = 0; i < uaResults_.length(); i++)
            {
                if (   uaResults_[i].m_continuationPoint.length() > 0
                    && uaResults_[i].m_status.isGood())
                {
                    // get the rank number for the next call
                    uint32_t current = uaNextNodesToRead.length();

                    // increase the size of the continuation points for the next BrowseNext call
                    uaNextNodesToRead.resize(current + 1);

                    // store the rank number of the current result
                    ranks.push_back(i);

                    uaResults_[i].m_continuationPoint.copyTo(
                            &uaNextNodesToRead[current].ContinuationPoint);

                    UaNodeId(uaNodesToRead_[i].NodeId).copyTo(
                            &uaNextNodesToRead[current].NodeId);

                    if (!UaQualifiedName(uaNodesToRead_[i].DataEncoding).isNull())
                        UaQualifiedName(uaNodesToRead_[i].DataEncoding).copyTo(
                                &uaNextNodesToRead[current].DataEncoding);

                    if (!UaString(&uaNodesToRead_[i].IndexRange).isNull())
                        UaString(&uaNodesToRead_[i].IndexRange).copyTo(
                                &uaNextNodesToRead[current].IndexRange);
                }
            }

            // if necessary, call the historyReadRawModified service again
            if (uaNextNodesToRead.length() > 0)
            {
                // perform the BrowseNext call
                UaStatus uaNextStatus = uaSession->historyReadRawModified(
                        uaServiceSettings_,
                        uaContext_,
                        uaNextNodesToRead,
                        uaNextResults);

                ret.fromSdk(uaNextStatus.statusCode(),
                            "Synchronous HistoryReadRawModified invocation failed");

                // we've finished an automatic read call, so increment the counter
                autoReadMore++;

                // now append the results to the results of the original read call
                for (uint32_t iNext = 0; iNext < uaNextResults.length() && ret.isGood(); iNext++)
                {
                    // get the rank number of the original request
                    uint32_t rank = ranks[iNext];

                    // increment the autoBrowsedNext
                    autoReadMorePerTarget_[rank] = autoReadMore;

                    // update the status
                    uaResults_[rank].m_status = uaNextResults[iNext].m_status;

                    if (uaResults_[rank].m_status.isGood())
                    {
                        // update the continuation point
                        uaResults_[rank].m_continuationPoint = uaNextResults[iNext].m_continuationPoint;

                        // now we want to append the retrieved data values to the existing data
                        // values
                        int32_t oldDataLength  = uaResults_[rank].m_dataValues.length();
                        int32_t nextDataLength = uaNextResults[iNext].m_dataValues.length();

                        // resize the original results, so that it can hold the new results
                        uaResults_[rank].m_dataValues.resize(oldDataLength + nextDataLength);

                        // now copy the data from the new results to the original results:
                        for (uint32_t i=0, j=oldDataLength; i<nextDataLength; i++, j++)
                        {
                            UaVariant(uaNextResults[iNext].m_dataValues[i].Value).copyTo(
                                    &uaResults_[rank].m_dataValues[j].Value);

                            uaResults_[rank].m_dataValues[j].SourceTimestamp \
                                = uaNextResults[iNext].m_dataValues[i].SourceTimestamp;

                            uaResults_[rank].m_dataValues[j].ServerTimestamp \
                                = uaNextResults[iNext].m_dataValues[i].ServerTimestamp;

                            uaResults_[rank].m_dataValues[j].SourcePicoseconds \
                                = uaNextResults[iNext].m_dataValues[i].SourcePicoseconds;

                            uaResults_[rank].m_dataValues[j].ServerPicoseconds \
                                = uaNextResults[iNext].m_dataValues[i].ServerPicoseconds;
                        }

                        // now we want to append the retrieved modification info values to the
                        // existing modification info values
                        oldDataLength  = uaResults_[rank].m_modificationInformation.length();
                        nextDataLength = uaNextResults[iNext].m_modificationInformation.length();

                        // resize the original results, so that it can hold the new results
                        uaResults_[rank].m_modificationInformation.resize(oldDataLength + nextDataLength);

                        // now copy the data from the new results to the original results:
                        for (uint32_t i=0, j=oldDataLength; i<nextDataLength; i++, j++)
                        {
                            UaString userName(&uaNextResults[iNext].m_modificationInformation[i].UserName);
                            if (!userName.isNull())
                                userName.copyTo(&uaResults_[rank].m_modificationInformation[j].UserName);

                            uaResults_[rank].m_modificationInformation[j].ModificationTime \
                                = uaNextResults[iNext].m_modificationInformation[i].ModificationTime;

                            uaResults_[rank].m_modificationInformation[j].UpdateType \
                                = uaNextResults[iNext].m_modificationInformation[i].UpdateType;
                        }
                    }
                }

                // check if we may still need to do another automatic BrowseNext
                finished = autoReadMore >= maxAutoReadMore;
            }
            else
            {
                // ok, no more automatic BrowseNext invocations needed!
                finished = true;
            }
        }

        return ret;
    }