|
@@ -21,12 +21,6 @@
|
|
|
|
|
|
#ifdef UA_ENABLE_SUBSCRIPTIONS
|
|
|
|
|
|
-#define UA_BOUNDEDVALUE_SETWBOUNDS(BOUNDS, SRC, DST) { \
|
|
|
- if(SRC > BOUNDS.max) DST = BOUNDS.max; \
|
|
|
- else if(SRC < BOUNDS.min) DST = BOUNDS.min; \
|
|
|
- else DST = SRC; \
|
|
|
- }
|
|
|
-
|
|
|
static UA_StatusCode
|
|
|
setSubscriptionSettings(UA_Server *server, UA_Subscription *subscription,
|
|
|
UA_Double requestedPublishingInterval,
|
|
@@ -165,454 +159,6 @@ Service_SetPublishingMode(UA_Server *server, UA_Session *session,
|
|
|
&response->resultsSize, &UA_TYPES[UA_TYPES_STATUSCODE]);
|
|
|
}
|
|
|
|
|
|
-static UA_StatusCode
|
|
|
-setMonitoredItemSettings(UA_Server *server, UA_MonitoredItem *mon,
|
|
|
- UA_MonitoringMode monitoringMode,
|
|
|
- const UA_MonitoringParameters *params,
|
|
|
- const UA_DataType* dataType) {
|
|
|
- UA_StatusCode retval = UA_STATUSCODE_GOOD;
|
|
|
-
|
|
|
- if(mon->attributeId == UA_ATTRIBUTEID_EVENTNOTIFIER) {
|
|
|
-
|
|
|
-#ifndef UA_ENABLE_SUBSCRIPTIONS_EVENTS
|
|
|
- return UA_STATUSCODE_BADNOTSUPPORTED;
|
|
|
-#else
|
|
|
- if(params->filter.encoding != UA_EXTENSIONOBJECT_DECODED &&
|
|
|
- params->filter.encoding != UA_EXTENSIONOBJECT_DECODED_NODELETE)
|
|
|
- return UA_STATUSCODE_BADEVENTFILTERINVALID;
|
|
|
- if(params->filter.content.decoded.type != &UA_TYPES[UA_TYPES_EVENTFILTER])
|
|
|
- return UA_STATUSCODE_BADEVENTFILTERINVALID;
|
|
|
- UA_EventFilter_clear(&mon->filter.eventFilter);
|
|
|
- retval = UA_EventFilter_copy((UA_EventFilter *)params->filter.content.decoded.data,
|
|
|
- &mon->filter.eventFilter);
|
|
|
-#endif
|
|
|
- } else {
|
|
|
-
|
|
|
- if(params->filter.encoding != UA_EXTENSIONOBJECT_DECODED &&
|
|
|
- params->filter.encoding != UA_EXTENSIONOBJECT_DECODED_NODELETE) {
|
|
|
-
|
|
|
- UA_DataChangeFilter_clear(&mon->filter.dataChangeFilter);
|
|
|
- mon->filter.dataChangeFilter.trigger = UA_DATACHANGETRIGGER_STATUSVALUE;
|
|
|
- } else if(params->filter.content.decoded.type == &UA_TYPES[UA_TYPES_DATACHANGEFILTER]) {
|
|
|
- UA_DataChangeFilter *filter = (UA_DataChangeFilter *)params->filter.content.decoded.data;
|
|
|
-
|
|
|
- switch(filter->deadbandType) {
|
|
|
- case UA_DEADBANDTYPE_NONE:
|
|
|
- break;
|
|
|
- case UA_DEADBANDTYPE_ABSOLUTE:
|
|
|
- if(!dataType || !UA_DataType_isNumeric(dataType))
|
|
|
- return UA_STATUSCODE_BADFILTERNOTALLOWED;
|
|
|
- break;
|
|
|
- case UA_DEADBANDTYPE_PERCENT:
|
|
|
- return UA_STATUSCODE_BADMONITOREDITEMFILTERUNSUPPORTED;
|
|
|
- default:
|
|
|
- return UA_STATUSCODE_BADMONITOREDITEMFILTERUNSUPPORTED;
|
|
|
- }
|
|
|
- retval = UA_DataChangeFilter_copy(filter, &mon->filter.dataChangeFilter);
|
|
|
- } else {
|
|
|
- return UA_STATUSCODE_BADMONITOREDITEMFILTERUNSUPPORTED;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- if(retval != UA_STATUSCODE_GOOD)
|
|
|
- return retval;
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
- UA_MonitoredItem_unregisterSampleCallback(server, mon);
|
|
|
-
|
|
|
-
|
|
|
- UA_ByteString_deleteMembers(&mon->lastSampledValue);
|
|
|
- UA_Variant_deleteMembers(&mon->lastValue);
|
|
|
-
|
|
|
-
|
|
|
- mon->clientHandle = params->clientHandle;
|
|
|
-
|
|
|
-
|
|
|
- UA_Double samplingInterval = params->samplingInterval;
|
|
|
-
|
|
|
- if(mon->attributeId == UA_ATTRIBUTEID_VALUE) {
|
|
|
- const UA_VariableNode *vn = (const UA_VariableNode *)
|
|
|
- UA_Nodestore_getNode(server->nsCtx, &mon->monitoredNodeId);
|
|
|
- if(vn) {
|
|
|
- if(vn->nodeClass == UA_NODECLASS_VARIABLE &&
|
|
|
- samplingInterval < vn->minimumSamplingInterval)
|
|
|
- samplingInterval = vn->minimumSamplingInterval;
|
|
|
- UA_Nodestore_releaseNode(server->nsCtx, (const UA_Node *)vn);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- UA_BOUNDEDVALUE_SETWBOUNDS(server->config.samplingIntervalLimits,
|
|
|
- samplingInterval, mon->samplingInterval);
|
|
|
- if(samplingInterval != samplingInterval)
|
|
|
- mon->samplingInterval = server->config.samplingIntervalLimits.min;
|
|
|
-
|
|
|
-
|
|
|
- UA_BOUNDEDVALUE_SETWBOUNDS(server->config.queueSizeLimits,
|
|
|
- params->queueSize, mon->maxQueueSize);
|
|
|
-
|
|
|
-
|
|
|
- mon->discardOldest = params->discardOldest;
|
|
|
-
|
|
|
-
|
|
|
- mon->monitoringMode = monitoringMode;
|
|
|
- if(monitoringMode == UA_MONITORINGMODE_REPORTING)
|
|
|
- return UA_MonitoredItem_registerSampleCallback(server, mon);
|
|
|
-
|
|
|
- return UA_STATUSCODE_GOOD;
|
|
|
-}
|
|
|
-
|
|
|
-static const UA_String binaryEncoding = {sizeof("Default Binary") - 1, (UA_Byte *)"Default Binary"};
|
|
|
-
|
|
|
-#ifdef UA_ENABLE_SUBSCRIPTIONS_EVENTS
|
|
|
-static UA_StatusCode
|
|
|
-UA_Server_addMonitoredItemToNodeEditNodeCallback(UA_Server *server, UA_Session *session,
|
|
|
- UA_Node *node, void *data) {
|
|
|
-
|
|
|
-
|
|
|
- ((UA_MonitoredItem *)data)->next = ((UA_ObjectNode *)node)->monitoredItemQueue;
|
|
|
- ((UA_ObjectNode *)node)->monitoredItemQueue = (UA_MonitoredItem *)data;
|
|
|
- return UA_STATUSCODE_GOOD;
|
|
|
-}
|
|
|
-#endif
|
|
|
-
|
|
|
-
|
|
|
-struct createMonContext {
|
|
|
- UA_Subscription *sub;
|
|
|
- UA_TimestampsToReturn timestampsToReturn;
|
|
|
-
|
|
|
-
|
|
|
- UA_Server_DataChangeNotificationCallback dataChangeCallback;
|
|
|
- void *context;
|
|
|
-};
|
|
|
-
|
|
|
-static void
|
|
|
-Operation_CreateMonitoredItem(UA_Server *server, UA_Session *session, struct createMonContext *cmc,
|
|
|
- const UA_MonitoredItemCreateRequest *request,
|
|
|
- UA_MonitoredItemCreateResult *result) {
|
|
|
-
|
|
|
- if(cmc->sub &&
|
|
|
- (((server->config.maxMonitoredItems != 0) &&
|
|
|
- (server->numMonitoredItems >= server->config.maxMonitoredItems)) ||
|
|
|
- ((server->config.maxMonitoredItemsPerSubscription != 0) &&
|
|
|
- (cmc->sub->monitoredItemsSize >= server->config.maxMonitoredItemsPerSubscription)))) {
|
|
|
- result->statusCode = UA_STATUSCODE_BADTOOMANYMONITOREDITEMS;
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- * codes "good" and "uncertain", as well as a list of statuscodes that might
|
|
|
- * be repaired inside the data source. */
|
|
|
- UA_DataValue v = UA_Server_readWithSession(server, session, &request->itemToMonitor,
|
|
|
- cmc->timestampsToReturn);
|
|
|
- if(v.hasStatus && (v.status >> 30) > 1 &&
|
|
|
- v.status != UA_STATUSCODE_BADRESOURCEUNAVAILABLE &&
|
|
|
- v.status != UA_STATUSCODE_BADCOMMUNICATIONERROR &&
|
|
|
- v.status != UA_STATUSCODE_BADWAITINGFORINITIALDATA &&
|
|
|
- v.status != UA_STATUSCODE_BADUSERACCESSDENIED &&
|
|
|
- v.status != UA_STATUSCODE_BADNOTREADABLE &&
|
|
|
- v.status != UA_STATUSCODE_BADINDEXRANGENODATA) {
|
|
|
- result->statusCode = v.status;
|
|
|
- UA_DataValue_deleteMembers(&v);
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- if(request->itemToMonitor.dataEncoding.name.length > 0 &&
|
|
|
- (!UA_String_equal(&binaryEncoding, &request->itemToMonitor.dataEncoding.name) ||
|
|
|
- request->itemToMonitor.dataEncoding.namespaceIndex != 0)) {
|
|
|
- result->statusCode = UA_STATUSCODE_BADDATAENCODINGUNSUPPORTED;
|
|
|
- UA_DataValue_deleteMembers(&v);
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- if(request->itemToMonitor.attributeId != UA_ATTRIBUTEID_VALUE &&
|
|
|
- request->itemToMonitor.dataEncoding.name.length > 0) {
|
|
|
- result->statusCode = UA_STATUSCODE_BADDATAENCODINGINVALID;
|
|
|
- UA_DataValue_deleteMembers(&v);
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- size_t nmsize = sizeof(UA_MonitoredItem);
|
|
|
- if(!cmc->sub)
|
|
|
- nmsize = sizeof(UA_LocalMonitoredItem);
|
|
|
- UA_MonitoredItem *newMon = (UA_MonitoredItem*)UA_malloc(nmsize);
|
|
|
- if(!newMon) {
|
|
|
- result->statusCode = UA_STATUSCODE_BADOUTOFMEMORY;
|
|
|
- UA_DataValue_deleteMembers(&v);
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- UA_MonitoredItem_init(newMon, cmc->sub);
|
|
|
- newMon->attributeId = request->itemToMonitor.attributeId;
|
|
|
- newMon->timestampsToReturn = cmc->timestampsToReturn;
|
|
|
- UA_StatusCode retval = UA_STATUSCODE_GOOD;
|
|
|
- retval |= UA_NodeId_copy(&request->itemToMonitor.nodeId, &newMon->monitoredNodeId);
|
|
|
- retval |= UA_String_copy(&request->itemToMonitor.indexRange, &newMon->indexRange);
|
|
|
- retval |= setMonitoredItemSettings(server, newMon, request->monitoringMode,
|
|
|
- &request->requestedParameters, v.value.type);
|
|
|
- UA_DataValue_deleteMembers(&v);
|
|
|
- if(retval != UA_STATUSCODE_GOOD) {
|
|
|
- UA_LOG_INFO_SESSION(&server->config.logger, session,
|
|
|
- "Subscription %u | Could not create a MonitoredItem "
|
|
|
- "with StatusCode %s", cmc->sub ? cmc->sub->subscriptionId : 0,
|
|
|
- UA_StatusCode_name(retval));
|
|
|
- result->statusCode = retval;
|
|
|
- UA_MonitoredItem_delete(server, newMon);
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- if(cmc->sub) {
|
|
|
- newMon->monitoredItemId = ++cmc->sub->lastMonitoredItemId;
|
|
|
- UA_Subscription_addMonitoredItem(server, cmc->sub, newMon);
|
|
|
-#ifdef UA_ENABLE_SUBSCRIPTIONS_EVENTS
|
|
|
- if(newMon->attributeId == UA_ATTRIBUTEID_EVENTNOTIFIER) {
|
|
|
-
|
|
|
- UA_Server_editNode(server, NULL, &newMon->monitoredNodeId,
|
|
|
- UA_Server_addMonitoredItemToNodeEditNodeCallback, newMon);
|
|
|
- }
|
|
|
-#endif
|
|
|
- } else {
|
|
|
-
|
|
|
- UA_LocalMonitoredItem *localMon = (UA_LocalMonitoredItem*)newMon;
|
|
|
- localMon->context = cmc->context;
|
|
|
- localMon->callback.dataChangeCallback = cmc->dataChangeCallback;
|
|
|
- newMon->monitoredItemId = ++server->lastLocalMonitoredItemId;
|
|
|
- LIST_INSERT_HEAD(&server->localMonitoredItems, newMon, listEntry);
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- if(server->config.monitoredItemRegisterCallback) {
|
|
|
- void *targetContext = NULL;
|
|
|
- UA_Server_getNodeContext(server, request->itemToMonitor.nodeId, &targetContext);
|
|
|
- server->config.monitoredItemRegisterCallback(server, &session->sessionId,
|
|
|
- session->sessionHandle,
|
|
|
- &request->itemToMonitor.nodeId,
|
|
|
- targetContext, newMon->attributeId, false);
|
|
|
- newMon->registered = true;
|
|
|
- }
|
|
|
-
|
|
|
- UA_LOG_INFO_SESSION(&server->config.logger, session,
|
|
|
- "Subscription %u | MonitoredItem %i | "
|
|
|
- "Created the MonitoredItem",
|
|
|
- cmc->sub ? cmc->sub->subscriptionId : 0,
|
|
|
- newMon->monitoredItemId);
|
|
|
-
|
|
|
-
|
|
|
- if(request->monitoringMode == UA_MONITORINGMODE_REPORTING &&
|
|
|
- newMon->attributeId != UA_ATTRIBUTEID_EVENTNOTIFIER)
|
|
|
- UA_MonitoredItem_sampleCallback(server, newMon);
|
|
|
-
|
|
|
-
|
|
|
- result->revisedSamplingInterval = newMon->samplingInterval;
|
|
|
- result->revisedQueueSize = newMon->maxQueueSize;
|
|
|
- result->monitoredItemId = newMon->monitoredItemId;
|
|
|
-}
|
|
|
-
|
|
|
-void
|
|
|
-Service_CreateMonitoredItems(UA_Server *server, UA_Session *session,
|
|
|
- const UA_CreateMonitoredItemsRequest *request,
|
|
|
- UA_CreateMonitoredItemsResponse *response) {
|
|
|
- UA_LOG_DEBUG_SESSION(&server->config.logger, session, "Processing CreateMonitoredItemsRequest");
|
|
|
-
|
|
|
- if(server->config.maxMonitoredItemsPerCall != 0 &&
|
|
|
- request->itemsToCreateSize > server->config.maxMonitoredItemsPerCall) {
|
|
|
- response->responseHeader.serviceResult = UA_STATUSCODE_BADTOOMANYOPERATIONS;
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- struct createMonContext cmc;
|
|
|
- cmc.timestampsToReturn = request->timestampsToReturn;
|
|
|
- if(cmc.timestampsToReturn > UA_TIMESTAMPSTORETURN_NEITHER) {
|
|
|
- response->responseHeader.serviceResult = UA_STATUSCODE_BADTIMESTAMPSTORETURNINVALID;
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- cmc.sub = UA_Session_getSubscriptionById(session, request->subscriptionId);
|
|
|
- if(!cmc.sub) {
|
|
|
- response->responseHeader.serviceResult = UA_STATUSCODE_BADSUBSCRIPTIONIDINVALID;
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- cmc.sub->currentLifetimeCount = 0;
|
|
|
-
|
|
|
- response->responseHeader.serviceResult =
|
|
|
- UA_Server_processServiceOperations(server, session, (UA_ServiceOperation)Operation_CreateMonitoredItem, &cmc,
|
|
|
- &request->itemsToCreateSize, &UA_TYPES[UA_TYPES_MONITOREDITEMCREATEREQUEST],
|
|
|
- &response->resultsSize, &UA_TYPES[UA_TYPES_MONITOREDITEMCREATERESULT]);
|
|
|
-}
|
|
|
-
|
|
|
-UA_MonitoredItemCreateResult
|
|
|
-UA_Server_createDataChangeMonitoredItem(UA_Server *server,
|
|
|
- UA_TimestampsToReturn timestampsToReturn,
|
|
|
- const UA_MonitoredItemCreateRequest item,
|
|
|
- void *monitoredItemContext,
|
|
|
- UA_Server_DataChangeNotificationCallback callback) {
|
|
|
- struct createMonContext cmc;
|
|
|
- cmc.sub = NULL;
|
|
|
- cmc.context = monitoredItemContext;
|
|
|
- cmc.dataChangeCallback = callback;
|
|
|
- cmc.timestampsToReturn = timestampsToReturn;
|
|
|
-
|
|
|
- UA_MonitoredItemCreateResult result;
|
|
|
- UA_MonitoredItemCreateResult_init(&result);
|
|
|
- Operation_CreateMonitoredItem(server, &server->adminSession, &cmc, &item, &result);
|
|
|
- return result;
|
|
|
-}
|
|
|
-
|
|
|
-static void
|
|
|
-Operation_ModifyMonitoredItem(UA_Server *server, UA_Session *session, UA_Subscription *sub,
|
|
|
- const UA_MonitoredItemModifyRequest *request,
|
|
|
- UA_MonitoredItemModifyResult *result) {
|
|
|
-
|
|
|
- UA_MonitoredItem *mon = UA_Subscription_getMonitoredItem(sub, request->monitoredItemId);
|
|
|
- if(!mon) {
|
|
|
- result->statusCode = UA_STATUSCODE_BADMONITOREDITEMIDINVALID;
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- * Can return an empty value (v.value.type == NULL). */
|
|
|
- UA_ReadValueId rvid;
|
|
|
- UA_ReadValueId_init(&rvid);
|
|
|
- rvid.nodeId = mon->monitoredNodeId;
|
|
|
- rvid.attributeId = mon->attributeId;
|
|
|
- rvid.indexRange = mon->indexRange;
|
|
|
- UA_DataValue v = UA_Server_readWithSession(server, session, &rvid, mon->timestampsToReturn);
|
|
|
- UA_StatusCode retval = setMonitoredItemSettings(server, mon, mon->monitoringMode,
|
|
|
- &request->requestedParameters,
|
|
|
- v.value.type);
|
|
|
- UA_DataValue_deleteMembers(&v);
|
|
|
- if(retval != UA_STATUSCODE_GOOD) {
|
|
|
- result->statusCode = retval;
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- result->revisedSamplingInterval = mon->samplingInterval;
|
|
|
- result->revisedQueueSize = mon->maxQueueSize;
|
|
|
-
|
|
|
-
|
|
|
- UA_MonitoredItem_ensureQueueSpace(server, mon);
|
|
|
-}
|
|
|
-
|
|
|
-void
|
|
|
-Service_ModifyMonitoredItems(UA_Server *server, UA_Session *session,
|
|
|
- const UA_ModifyMonitoredItemsRequest *request,
|
|
|
- UA_ModifyMonitoredItemsResponse *response) {
|
|
|
- UA_LOG_DEBUG_SESSION(&server->config.logger, session, "Processing ModifyMonitoredItemsRequest");
|
|
|
-
|
|
|
- if(server->config.maxMonitoredItemsPerCall != 0 &&
|
|
|
- request->itemsToModifySize > server->config.maxMonitoredItemsPerCall) {
|
|
|
- response->responseHeader.serviceResult = UA_STATUSCODE_BADTOOMANYOPERATIONS;
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- if(request->timestampsToReturn > UA_TIMESTAMPSTORETURN_NEITHER) {
|
|
|
- response->responseHeader.serviceResult = UA_STATUSCODE_BADTIMESTAMPSTORETURNINVALID;
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- UA_Subscription *sub = UA_Session_getSubscriptionById(session, request->subscriptionId);
|
|
|
- if(!sub) {
|
|
|
- response->responseHeader.serviceResult = UA_STATUSCODE_BADSUBSCRIPTIONIDINVALID;
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- sub->currentLifetimeCount = 0;
|
|
|
-
|
|
|
- response->responseHeader.serviceResult =
|
|
|
- UA_Server_processServiceOperations(server, session,
|
|
|
- (UA_ServiceOperation)Operation_ModifyMonitoredItem, sub,
|
|
|
- &request->itemsToModifySize, &UA_TYPES[UA_TYPES_MONITOREDITEMMODIFYREQUEST],
|
|
|
- &response->resultsSize, &UA_TYPES[UA_TYPES_MONITOREDITEMMODIFYRESULT]);
|
|
|
-}
|
|
|
-
|
|
|
-struct setMonitoringContext {
|
|
|
- UA_Subscription *sub;
|
|
|
- UA_MonitoringMode monitoringMode;
|
|
|
-};
|
|
|
-
|
|
|
-static void
|
|
|
-Operation_SetMonitoringMode(UA_Server *server, UA_Session *session,
|
|
|
- struct setMonitoringContext *smc,
|
|
|
- const UA_UInt32 *monitoredItemId, UA_StatusCode *result) {
|
|
|
- UA_MonitoredItem *mon = UA_Subscription_getMonitoredItem(smc->sub, *monitoredItemId);
|
|
|
- if(!mon) {
|
|
|
- *result = UA_STATUSCODE_BADMONITOREDITEMIDINVALID;
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- if(smc->monitoringMode > UA_MONITORINGMODE_REPORTING) {
|
|
|
- *result = UA_STATUSCODE_BADMONITORINGMODEINVALID;
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- if(mon->monitoringMode == smc->monitoringMode)
|
|
|
- return;
|
|
|
-
|
|
|
- mon->monitoringMode = smc->monitoringMode;
|
|
|
-
|
|
|
- if(mon->monitoringMode == UA_MONITORINGMODE_REPORTING) {
|
|
|
- *result = UA_MonitoredItem_registerSampleCallback(server, mon);
|
|
|
- } else {
|
|
|
- UA_MonitoredItem_unregisterSampleCallback(server, mon);
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
- UA_Notification *notification, *notification_tmp;
|
|
|
- TAILQ_FOREACH_SAFE(notification, &mon->queue, listEntry, notification_tmp) {
|
|
|
- UA_Notification_dequeue(server, notification);
|
|
|
- UA_Notification_delete(notification);
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- UA_ByteString_deleteMembers(&mon->lastSampledValue);
|
|
|
- UA_Variant_deleteMembers(&mon->lastValue);
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-void
|
|
|
-Service_SetMonitoringMode(UA_Server *server, UA_Session *session,
|
|
|
- const UA_SetMonitoringModeRequest *request,
|
|
|
- UA_SetMonitoringModeResponse *response) {
|
|
|
- UA_LOG_DEBUG_SESSION(&server->config.logger, session, "Processing SetMonitoringMode");
|
|
|
-
|
|
|
- if(server->config.maxMonitoredItemsPerCall != 0 &&
|
|
|
- request->monitoredItemIdsSize > server->config.maxMonitoredItemsPerCall) {
|
|
|
- response->responseHeader.serviceResult = UA_STATUSCODE_BADTOOMANYOPERATIONS;
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- struct setMonitoringContext smc;
|
|
|
- smc.sub = UA_Session_getSubscriptionById(session, request->subscriptionId);
|
|
|
- if(!smc.sub) {
|
|
|
- response->responseHeader.serviceResult = UA_STATUSCODE_BADSUBSCRIPTIONIDINVALID;
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- smc.sub->currentLifetimeCount = 0;
|
|
|
-
|
|
|
- smc.monitoringMode = request->monitoringMode;
|
|
|
- response->responseHeader.serviceResult =
|
|
|
- UA_Server_processServiceOperations(server, session,
|
|
|
- (UA_ServiceOperation)Operation_SetMonitoringMode, &smc,
|
|
|
- &request->monitoredItemIdsSize, &UA_TYPES[UA_TYPES_UINT32],
|
|
|
- &response->resultsSize, &UA_TYPES[UA_TYPES_STATUSCODE]);
|
|
|
-}
|
|
|
-
|
|
|
|
|
|
static void
|
|
|
subscriptionSendError(UA_SecureChannel *channel, UA_UInt32 requestHandle,
|
|
@@ -786,55 +332,6 @@ Service_DeleteSubscriptions(UA_Server *server, UA_Session *session,
|
|
|
UA_Subscription_answerPublishRequestsNoSubscription(server, session);
|
|
|
}
|
|
|
|
|
|
-static void
|
|
|
-Operation_DeleteMonitoredItem(UA_Server *server, UA_Session *session, UA_Subscription *sub,
|
|
|
- const UA_UInt32 *monitoredItemId, UA_StatusCode *result) {
|
|
|
- *result = UA_Subscription_deleteMonitoredItem(server, sub, *monitoredItemId);
|
|
|
-}
|
|
|
-
|
|
|
-void
|
|
|
-Service_DeleteMonitoredItems(UA_Server *server, UA_Session *session,
|
|
|
- const UA_DeleteMonitoredItemsRequest *request,
|
|
|
- UA_DeleteMonitoredItemsResponse *response) {
|
|
|
- UA_LOG_DEBUG_SESSION(&server->config.logger, session,
|
|
|
- "Processing DeleteMonitoredItemsRequest");
|
|
|
-
|
|
|
- if(server->config.maxMonitoredItemsPerCall != 0 &&
|
|
|
- request->monitoredItemIdsSize > server->config.maxMonitoredItemsPerCall) {
|
|
|
- response->responseHeader.serviceResult = UA_STATUSCODE_BADTOOMANYOPERATIONS;
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- UA_Subscription *sub = UA_Session_getSubscriptionById(session, request->subscriptionId);
|
|
|
- if(!sub) {
|
|
|
- response->responseHeader.serviceResult = UA_STATUSCODE_BADSUBSCRIPTIONIDINVALID;
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- sub->currentLifetimeCount = 0;
|
|
|
-
|
|
|
- response->responseHeader.serviceResult =
|
|
|
- UA_Server_processServiceOperations(server, session,
|
|
|
- (UA_ServiceOperation)Operation_DeleteMonitoredItem, sub,
|
|
|
- &request->monitoredItemIdsSize, &UA_TYPES[UA_TYPES_UINT32],
|
|
|
- &response->resultsSize, &UA_TYPES[UA_TYPES_STATUSCODE]);
|
|
|
-}
|
|
|
-
|
|
|
-UA_StatusCode
|
|
|
-UA_Server_deleteMonitoredItem(UA_Server *server, UA_UInt32 monitoredItemId) {
|
|
|
- UA_MonitoredItem *mon;
|
|
|
- LIST_FOREACH(mon, &server->localMonitoredItems, listEntry) {
|
|
|
- if(mon->monitoredItemId != monitoredItemId)
|
|
|
- continue;
|
|
|
- LIST_REMOVE(mon, listEntry);
|
|
|
- UA_MonitoredItem_delete(server, mon);
|
|
|
- return UA_STATUSCODE_GOOD;
|
|
|
- }
|
|
|
- return UA_STATUSCODE_BADMONITOREDITEMIDINVALID;
|
|
|
-}
|
|
|
-
|
|
|
void
|
|
|
Service_Republish(UA_Server *server, UA_Session *session,
|
|
|
const UA_RepublishRequest *request,
|