check_monitoreditem_filter.c 39 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900
  1. /* This Source Code Form is subject to the terms of the Mozilla Public
  2. * License, v. 2.0. If a copy of the MPL was not distributed with this
  3. * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  4. *
  5. * Copyright 2018 (c) basysKom GmbH <opensource@basyskom.com> (Author: Peter Rustler)
  6. */
  7. #include <open62541/client.h>
  8. #include <open62541/client_config_default.h>
  9. #include <open62541/client_highlevel.h>
  10. #include <open62541/server.h>
  11. #include <open62541/server_config_default.h>
  12. #include "client/ua_client_internal.h"
  13. #include <check.h>
  14. #include "testing_clock.h"
  15. #include "testing_networklayers.h"
  16. #include "thread_wrapper.h"
  17. UA_Server *server;
  18. UA_ServerConfig *config;
  19. UA_Boolean running;
  20. THREAD_HANDLE server_thread;
  21. UA_Client *client;
  22. UA_UInt32 subId;
  23. UA_NodeId parentNodeId;
  24. UA_NodeId parentReferenceNodeId;
  25. UA_NodeId outNodeId;
  26. UA_Boolean notificationReceived = false;
  27. UA_UInt32 countNotificationReceived = 0;
  28. UA_Double publishingInterval = 500.0;
  29. UA_DataValue lastValue;
  30. THREAD_CALLBACK(serverloop) {
  31. while(running)
  32. UA_Server_run_iterate(server, true);
  33. return 0;
  34. }
  35. static void setup(void) {
  36. UA_DataValue_init(&lastValue);
  37. running = true;
  38. config = UA_ServerConfig_new_default();
  39. server = UA_Server_new(config);
  40. UA_Server_run_startup(server);
  41. THREAD_CREATE(server_thread, serverloop);
  42. /* Define the attribute of the double variable node */
  43. UA_VariableAttributes attr = UA_VariableAttributes_default;
  44. UA_Double myDouble = 40.0;
  45. UA_Variant_setScalar(&attr.value, &myDouble, &UA_TYPES[UA_TYPES_DOUBLE]);
  46. attr.description = UA_LOCALIZEDTEXT("en-US","the answer");
  47. attr.displayName = UA_LOCALIZEDTEXT("en-US","the answer");
  48. attr.dataType = UA_TYPES[UA_TYPES_DOUBLE].typeId;
  49. attr.accessLevel = UA_ACCESSLEVELMASK_READ | UA_ACCESSLEVELMASK_WRITE;
  50. UA_NodeId doubleNodeId = UA_NODEID_STRING(1, "the.answer");
  51. UA_QualifiedName doubleName = UA_QUALIFIEDNAME(1, "the answer");
  52. parentNodeId = UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER);
  53. parentReferenceNodeId = UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES);
  54. UA_NodeId_init(&outNodeId);
  55. ck_assert_uint_eq(UA_Server_addVariableNode(server,
  56. doubleNodeId, parentNodeId,
  57. parentReferenceNodeId,
  58. doubleName,
  59. UA_NODEID_NUMERIC(0, UA_NS0ID_BASEDATAVARIABLETYPE),
  60. attr,
  61. NULL,
  62. &outNodeId)
  63. , UA_STATUSCODE_GOOD);
  64. /* Add a boolean node */
  65. UA_Boolean myBool = false;
  66. UA_Variant_setScalar(&attr.value, &myBool, &UA_TYPES[UA_TYPES_BOOLEAN]);
  67. attr.description = UA_LOCALIZEDTEXT("en-US","the answer bool");
  68. attr.displayName = UA_LOCALIZEDTEXT("en-US","the answer bool");
  69. attr.dataType = UA_TYPES[UA_TYPES_BOOLEAN].typeId;
  70. ck_assert_uint_eq(UA_Server_addVariableNode(server,
  71. UA_NODEID_STRING(1, "the.bool"),
  72. parentNodeId, parentReferenceNodeId,
  73. UA_QUALIFIEDNAME(1, "the bool"),
  74. UA_NODEID_NUMERIC(0, UA_NS0ID_BASEDATAVARIABLETYPE),
  75. attr, NULL, NULL)
  76. , UA_STATUSCODE_GOOD);
  77. client = UA_Client_new();
  78. UA_ClientConfig_setDefault(UA_Client_getConfig(client));
  79. UA_StatusCode retval = UA_Client_connect(client, "opc.tcp://localhost:4840");
  80. ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD);
  81. UA_Client_recv = client->connection.recv;
  82. client->connection.recv = UA_Client_recvTesting;
  83. UA_CreateSubscriptionRequest request = UA_CreateSubscriptionRequest_default();
  84. request.requestedMaxKeepAliveCount = 100;
  85. UA_CreateSubscriptionResponse response = UA_Client_Subscriptions_create(client, request,
  86. NULL, NULL, NULL);
  87. ck_assert_uint_eq(response.responseHeader.serviceResult, UA_STATUSCODE_GOOD);
  88. subId = response.subscriptionId;
  89. notificationReceived = false;
  90. countNotificationReceived = 0;
  91. }
  92. static void teardown(void) {
  93. ck_assert_uint_eq(UA_Client_Subscriptions_deleteSingle(client, subId)
  94. , UA_STATUSCODE_GOOD);
  95. /* cleanup */
  96. UA_Client_disconnect(client);
  97. UA_Client_delete(client);
  98. UA_NodeId_deleteMembers(&parentNodeId);
  99. UA_NodeId_deleteMembers(&parentReferenceNodeId);
  100. UA_NodeId_deleteMembers(&outNodeId);
  101. running = false;
  102. THREAD_JOIN(server_thread);
  103. UA_Server_run_shutdown(server);
  104. UA_Server_delete(server);
  105. UA_ServerConfig_delete(config);
  106. UA_DataValue_deleteMembers(&lastValue);
  107. }
  108. #ifdef UA_ENABLE_SUBSCRIPTIONS
  109. static void
  110. dataChangeHandler(UA_Client *thisClient, UA_UInt32 thisSubId, void *subContext,
  111. UA_UInt32 monId, void *monContext, UA_DataValue *value) {
  112. notificationReceived = true;
  113. ++countNotificationReceived;
  114. UA_DataValue_deleteMembers(&lastValue);
  115. UA_DataValue_copy(value, &lastValue);
  116. }
  117. static UA_StatusCode
  118. setDouble(UA_Client *thisClient, UA_NodeId node, UA_Double value) {
  119. UA_Variant variant;
  120. UA_Variant_setScalar(&variant, &value, &UA_TYPES[UA_TYPES_DOUBLE]);
  121. return UA_Client_writeValueAttribute(thisClient, node, &variant);
  122. }
  123. static UA_StatusCode waitForNotification(UA_UInt32 notifications, UA_UInt32 maxTries) {
  124. UA_StatusCode retval = UA_STATUSCODE_GOOD;
  125. for (UA_UInt32 i = 0; i < maxTries; ++i) {
  126. UA_fakeSleep((UA_UInt32)publishingInterval + 100);
  127. retval = UA_Client_run_iterate(client, (UA_UInt16)(publishingInterval + 100));
  128. if (retval != UA_STATUSCODE_GOOD)
  129. return retval;
  130. if (countNotificationReceived == notifications)
  131. return retval;
  132. }
  133. return retval;
  134. }
  135. static UA_Boolean fuzzyLastValueIsEqualTo(UA_Double value) {
  136. double offset = 0.001;
  137. if(lastValue.hasValue
  138. && lastValue.value.type == &UA_TYPES[UA_TYPES_DOUBLE]) {
  139. double lastDouble = *((UA_Double*)(lastValue.value.data));
  140. if (lastDouble > value - offset && lastDouble < value + offset) {
  141. return true;
  142. }
  143. }
  144. return false;
  145. }
  146. START_TEST(Server_MonitoredItemsAbsoluteFilterSetLater) {
  147. UA_DataValue_init(&lastValue);
  148. /* define a monitored item with no filter */
  149. UA_MonitoredItemCreateRequest item = UA_MonitoredItemCreateRequest_default(outNodeId);;
  150. UA_UInt32 newMonitoredItemIds[1];
  151. UA_Client_DataChangeNotificationCallback callbacks[1];
  152. callbacks[0] = dataChangeHandler;
  153. UA_Client_DeleteMonitoredItemCallback deleteCallbacks[1] = {NULL};
  154. void *contexts[1];
  155. contexts[0] = NULL;
  156. UA_CreateMonitoredItemsRequest createRequest;
  157. UA_CreateMonitoredItemsRequest_init(&createRequest);
  158. createRequest.subscriptionId = subId;
  159. createRequest.timestampsToReturn = UA_TIMESTAMPSTORETURN_BOTH;
  160. createRequest.itemsToCreate = &item;
  161. createRequest.itemsToCreateSize = 1;
  162. UA_CreateMonitoredItemsResponse createResponse =
  163. UA_Client_MonitoredItems_createDataChanges(client, createRequest, contexts,
  164. callbacks, deleteCallbacks);
  165. ck_assert_uint_eq(createResponse.responseHeader.serviceResult, UA_STATUSCODE_GOOD);
  166. ck_assert_uint_eq(createResponse.resultsSize, 1);
  167. ck_assert_uint_eq(createResponse.results[0].statusCode, UA_STATUSCODE_GOOD);
  168. newMonitoredItemIds[0] = createResponse.results[0].monitoredItemId;
  169. UA_CreateMonitoredItemsResponse_deleteMembers(&createResponse);
  170. // Do we get initial value ?
  171. notificationReceived = false;
  172. countNotificationReceived = 0;
  173. ck_assert_uint_eq(waitForNotification(1, 10), UA_STATUSCODE_GOOD);
  174. ck_assert_uint_eq(notificationReceived, true);
  175. ck_assert_uint_eq(countNotificationReceived, 1);
  176. ck_assert(fuzzyLastValueIsEqualTo(40.0));
  177. // This should trigger because no filter
  178. notificationReceived = false;
  179. countNotificationReceived = 0;
  180. ck_assert_uint_eq(setDouble(client, outNodeId, 41.0), UA_STATUSCODE_GOOD);
  181. ck_assert_uint_eq(waitForNotification(1, 10), UA_STATUSCODE_GOOD);
  182. ck_assert_uint_eq(setDouble(client, outNodeId, 42.0), UA_STATUSCODE_GOOD);
  183. ck_assert_uint_eq(waitForNotification(2, 10), UA_STATUSCODE_GOOD);
  184. ck_assert_uint_eq(notificationReceived, true);
  185. ck_assert_uint_eq(countNotificationReceived, 2);
  186. ck_assert(fuzzyLastValueIsEqualTo(42.0));
  187. notificationReceived = false;
  188. countNotificationReceived = 0;
  189. ck_assert_uint_eq(setDouble(client, outNodeId, 43.0), UA_STATUSCODE_GOOD);
  190. ck_assert_uint_eq(waitForNotification(1, 10), UA_STATUSCODE_GOOD);
  191. ck_assert_uint_eq(setDouble(client, outNodeId, 44.0), UA_STATUSCODE_GOOD);
  192. ck_assert_uint_eq(waitForNotification(2, 10), UA_STATUSCODE_GOOD);
  193. ck_assert_uint_eq(notificationReceived, true);
  194. ck_assert_uint_eq(countNotificationReceived, 2);
  195. ck_assert(fuzzyLastValueIsEqualTo(44.0));
  196. // set back to 40.0
  197. notificationReceived = false;
  198. countNotificationReceived = 0;
  199. ck_assert_uint_eq(setDouble(client, outNodeId, 40.0), UA_STATUSCODE_GOOD);
  200. ck_assert_uint_eq(waitForNotification(1, 10), UA_STATUSCODE_GOOD);
  201. ck_assert_uint_eq(notificationReceived, true);
  202. ck_assert_uint_eq(countNotificationReceived, 1);
  203. ck_assert(fuzzyLastValueIsEqualTo(40.0));
  204. /* modify the monitored item with an absolute filter with deadbandvalue = 2.0 */
  205. UA_MonitoredItemModifyRequest itemModify;
  206. UA_MonitoredItemModifyRequest_init(&itemModify);
  207. itemModify.monitoredItemId = newMonitoredItemIds[0];
  208. itemModify.requestedParameters.samplingInterval = 250;
  209. itemModify.requestedParameters.discardOldest = true;
  210. itemModify.requestedParameters.queueSize = 1;
  211. itemModify.requestedParameters.clientHandle = newMonitoredItemIds[0];
  212. UA_DataChangeFilter filter;
  213. UA_DataChangeFilter_init(&filter);
  214. filter.trigger = UA_DATACHANGETRIGGER_STATUSVALUE;
  215. filter.deadbandType = UA_DEADBANDTYPE_ABSOLUTE;
  216. filter.deadbandValue = 2.0;
  217. itemModify.requestedParameters.filter.encoding = UA_EXTENSIONOBJECT_DECODED;
  218. itemModify.requestedParameters.filter.content.decoded.type = &UA_TYPES[UA_TYPES_DATACHANGEFILTER];
  219. itemModify.requestedParameters.filter.content.decoded.data = &filter;
  220. UA_ModifyMonitoredItemsRequest modifyRequest;
  221. UA_ModifyMonitoredItemsRequest_init(&modifyRequest);
  222. modifyRequest.subscriptionId = subId;
  223. modifyRequest.timestampsToReturn = UA_TIMESTAMPSTORETURN_BOTH;
  224. modifyRequest.itemsToModify = &itemModify;
  225. modifyRequest.itemsToModifySize = 1;
  226. UA_ModifyMonitoredItemsResponse modifyResponse =
  227. UA_Client_MonitoredItems_modify(client, modifyRequest);
  228. ck_assert_uint_eq(modifyResponse.resultsSize, 1);
  229. ck_assert_uint_eq(modifyResponse.results[0].statusCode, UA_STATUSCODE_GOOD);
  230. UA_ModifyMonitoredItemsResponse_deleteMembers(&modifyResponse);
  231. // This should trigger only once for the new filter
  232. notificationReceived = false;
  233. countNotificationReceived = 0;
  234. ck_assert_uint_eq(setDouble(client, outNodeId, 39.0), UA_STATUSCODE_GOOD);
  235. ck_assert_uint_eq(waitForNotification(1, 10), UA_STATUSCODE_GOOD);
  236. ck_assert_uint_eq(notificationReceived, true);
  237. ck_assert_uint_eq(countNotificationReceived, 1);
  238. ck_assert_uint_eq(setDouble(client, outNodeId, 41.0), UA_STATUSCODE_GOOD);
  239. ck_assert_uint_eq(waitForNotification(2, 10), UA_STATUSCODE_GOOD);
  240. ck_assert_uint_eq(countNotificationReceived, 1);
  241. ck_assert(fuzzyLastValueIsEqualTo(39.0));
  242. // This should trigger once at 43.0.
  243. notificationReceived = false;
  244. countNotificationReceived = 0;
  245. ck_assert_uint_eq(setDouble(client, outNodeId, 43.0), UA_STATUSCODE_GOOD);
  246. ck_assert_uint_eq(waitForNotification(1, 10), UA_STATUSCODE_GOOD);
  247. ck_assert_uint_eq(setDouble(client, outNodeId, 44.0), UA_STATUSCODE_GOOD);
  248. ck_assert_uint_eq(waitForNotification(1, 10), UA_STATUSCODE_GOOD);
  249. ck_assert_uint_eq(notificationReceived, true);
  250. ck_assert_uint_eq(countNotificationReceived, 1);
  251. ck_assert(fuzzyLastValueIsEqualTo(43.0));
  252. // remove monitored item
  253. UA_DeleteMonitoredItemsRequest deleteRequest;
  254. UA_DeleteMonitoredItemsRequest_init(&deleteRequest);
  255. deleteRequest.subscriptionId = subId;
  256. deleteRequest.monitoredItemIds = newMonitoredItemIds;
  257. deleteRequest.monitoredItemIdsSize = 1;
  258. UA_DeleteMonitoredItemsResponse deleteResponse =
  259. UA_Client_MonitoredItems_delete(client, deleteRequest);
  260. ck_assert_uint_eq(deleteResponse.responseHeader.serviceResult, UA_STATUSCODE_GOOD);
  261. ck_assert_uint_eq(deleteResponse.resultsSize, 1);
  262. ck_assert_uint_eq(deleteResponse.results[0], UA_STATUSCODE_GOOD);
  263. UA_DeleteMonitoredItemsResponse_deleteMembers(&deleteResponse);
  264. }
  265. END_TEST
  266. START_TEST(Server_MonitoredItemsAbsoluteFilterSetOnCreateRemoveLater) {
  267. UA_DataValue_init(&lastValue);
  268. /* define a monitored item with absolute filter */
  269. UA_MonitoredItemCreateRequest item = UA_MonitoredItemCreateRequest_default(outNodeId);;
  270. UA_DataChangeFilter filter;
  271. UA_DataChangeFilter_init(&filter);
  272. filter.trigger = UA_DATACHANGETRIGGER_STATUSVALUE;
  273. filter.deadbandType = UA_DEADBANDTYPE_ABSOLUTE;
  274. filter.deadbandValue = 2.0;
  275. item.requestedParameters.filter.encoding = UA_EXTENSIONOBJECT_DECODED;
  276. item.requestedParameters.filter.content.decoded.type = &UA_TYPES[UA_TYPES_DATACHANGEFILTER];
  277. item.requestedParameters.filter.content.decoded.data = &filter;
  278. UA_UInt32 newMonitoredItemIds[1];
  279. UA_Client_DataChangeNotificationCallback callbacks[1];
  280. callbacks[0] = dataChangeHandler;
  281. UA_Client_DeleteMonitoredItemCallback deleteCallbacks[1] = {NULL};
  282. void *contexts[1];
  283. contexts[0] = NULL;
  284. UA_CreateMonitoredItemsRequest createRequest;
  285. UA_CreateMonitoredItemsRequest_init(&createRequest);
  286. createRequest.subscriptionId = subId;
  287. createRequest.timestampsToReturn = UA_TIMESTAMPSTORETURN_BOTH;
  288. createRequest.itemsToCreate = &item;
  289. createRequest.itemsToCreateSize = 1;
  290. UA_CreateMonitoredItemsResponse createResponse =
  291. UA_Client_MonitoredItems_createDataChanges(client, createRequest, contexts,
  292. callbacks, deleteCallbacks);
  293. ck_assert_uint_eq(createResponse.responseHeader.serviceResult, UA_STATUSCODE_GOOD);
  294. ck_assert_uint_eq(createResponse.resultsSize, 1);
  295. ck_assert_uint_eq(createResponse.results[0].statusCode, UA_STATUSCODE_GOOD);
  296. newMonitoredItemIds[0] = createResponse.results[0].monitoredItemId;
  297. UA_CreateMonitoredItemsResponse_deleteMembers(&createResponse);
  298. // Do we get initial value ?
  299. notificationReceived = false;
  300. countNotificationReceived = 0;
  301. ck_assert_uint_eq(waitForNotification(1, 10), UA_STATUSCODE_GOOD);
  302. ck_assert_uint_eq(notificationReceived, true);
  303. ck_assert_uint_eq(countNotificationReceived, 1);
  304. ck_assert(fuzzyLastValueIsEqualTo(40.0));
  305. // This should not trigger because of filter
  306. notificationReceived = false;
  307. countNotificationReceived = 0;
  308. ck_assert_uint_eq(setDouble(client, outNodeId, 41.0), UA_STATUSCODE_GOOD);
  309. ck_assert_uint_eq(waitForNotification(0, 10), UA_STATUSCODE_GOOD);
  310. ck_assert_uint_eq(setDouble(client, outNodeId, 42.0), UA_STATUSCODE_GOOD);
  311. ck_assert_uint_eq(waitForNotification(0, 10), UA_STATUSCODE_GOOD);
  312. ck_assert_uint_eq(notificationReceived, false);
  313. ck_assert_uint_eq(countNotificationReceived, 0);
  314. ck_assert(fuzzyLastValueIsEqualTo(40.0));
  315. // This should trigger once at 43.0.
  316. notificationReceived = false;
  317. countNotificationReceived = 0;
  318. ck_assert_uint_eq(setDouble(client, outNodeId, 43.0), UA_STATUSCODE_GOOD);
  319. ck_assert_uint_eq(waitForNotification(1, 10), UA_STATUSCODE_GOOD);
  320. ck_assert_uint_eq(setDouble(client, outNodeId, 44.0), UA_STATUSCODE_GOOD);
  321. ck_assert_uint_eq(waitForNotification(1, 10), UA_STATUSCODE_GOOD);
  322. ck_assert_uint_eq(notificationReceived, true);
  323. ck_assert_uint_eq(countNotificationReceived, 1);
  324. ck_assert(fuzzyLastValueIsEqualTo(43.0));
  325. // set back to 40.0
  326. notificationReceived = false;
  327. countNotificationReceived = 0;
  328. ck_assert_uint_eq(setDouble(client, outNodeId, 40.0), UA_STATUSCODE_GOOD);
  329. ck_assert_uint_eq(waitForNotification(1, 10), UA_STATUSCODE_GOOD);
  330. ck_assert_uint_eq(notificationReceived, true);
  331. ck_assert_uint_eq(countNotificationReceived, 1);
  332. ck_assert(fuzzyLastValueIsEqualTo(40.0));
  333. /* modify the monitored item with no filter */
  334. UA_MonitoredItemModifyRequest itemModify;
  335. UA_MonitoredItemModifyRequest_init(&itemModify);
  336. itemModify.monitoredItemId = newMonitoredItemIds[0];
  337. itemModify.requestedParameters.samplingInterval = 250;
  338. itemModify.requestedParameters.discardOldest = true;
  339. itemModify.requestedParameters.queueSize = 1;
  340. itemModify.requestedParameters.clientHandle = newMonitoredItemIds[0];
  341. UA_DataChangeFilter unsetfilter;
  342. UA_DataChangeFilter_init(&unsetfilter);
  343. unsetfilter.trigger = UA_DATACHANGETRIGGER_STATUSVALUE;
  344. unsetfilter.deadbandType = UA_DEADBANDTYPE_NONE;
  345. unsetfilter.deadbandValue = 0.0;
  346. itemModify.requestedParameters.filter.encoding = UA_EXTENSIONOBJECT_DECODED;
  347. itemModify.requestedParameters.filter.content.decoded.type = &UA_TYPES[UA_TYPES_DATACHANGEFILTER];
  348. itemModify.requestedParameters.filter.content.decoded.data = &unsetfilter;
  349. UA_ModifyMonitoredItemsRequest modifyRequest;
  350. UA_ModifyMonitoredItemsRequest_init(&modifyRequest);
  351. modifyRequest.subscriptionId = subId;
  352. modifyRequest.timestampsToReturn = UA_TIMESTAMPSTORETURN_BOTH;
  353. modifyRequest.itemsToModify = &itemModify;
  354. modifyRequest.itemsToModifySize = 1;
  355. UA_ModifyMonitoredItemsResponse modifyResponse =
  356. UA_Client_MonitoredItems_modify(client, modifyRequest);
  357. ck_assert_uint_eq(modifyResponse.resultsSize, 1);
  358. ck_assert_uint_eq(modifyResponse.results[0].statusCode, UA_STATUSCODE_GOOD);
  359. UA_ModifyMonitoredItemsResponse_deleteMembers(&modifyResponse);
  360. // This should trigger because now we do not filter
  361. notificationReceived = false;
  362. countNotificationReceived = 0;
  363. ck_assert_uint_eq(setDouble(client, outNodeId, 41.0), UA_STATUSCODE_GOOD);
  364. ck_assert_uint_eq(waitForNotification(1, 10), UA_STATUSCODE_GOOD);
  365. ck_assert_uint_eq(setDouble(client, outNodeId, 42.0), UA_STATUSCODE_GOOD);
  366. ck_assert_uint_eq(waitForNotification(2, 10), UA_STATUSCODE_GOOD);
  367. ck_assert_uint_eq(notificationReceived, true);
  368. ck_assert_uint_eq(countNotificationReceived, 2);
  369. ck_assert(fuzzyLastValueIsEqualTo(42.0));
  370. notificationReceived = false;
  371. countNotificationReceived = 0;
  372. ck_assert_uint_eq(setDouble(client, outNodeId, 43.0), UA_STATUSCODE_GOOD);
  373. ck_assert_uint_eq(waitForNotification(1, 10), UA_STATUSCODE_GOOD);
  374. ck_assert_uint_eq(setDouble(client, outNodeId, 44.0), UA_STATUSCODE_GOOD);
  375. ck_assert_uint_eq(waitForNotification(2, 10), UA_STATUSCODE_GOOD);
  376. ck_assert_uint_eq(notificationReceived, true);
  377. ck_assert_uint_eq(countNotificationReceived, 2);
  378. ck_assert(fuzzyLastValueIsEqualTo(44.0));
  379. // remove monitored item
  380. UA_DeleteMonitoredItemsRequest deleteRequest;
  381. UA_DeleteMonitoredItemsRequest_init(&deleteRequest);
  382. deleteRequest.subscriptionId = subId;
  383. deleteRequest.monitoredItemIds = newMonitoredItemIds;
  384. deleteRequest.monitoredItemIdsSize = 1;
  385. UA_DeleteMonitoredItemsResponse deleteResponse =
  386. UA_Client_MonitoredItems_delete(client, deleteRequest);
  387. ck_assert_uint_eq(deleteResponse.responseHeader.serviceResult, UA_STATUSCODE_GOOD);
  388. ck_assert_uint_eq(deleteResponse.resultsSize, 1);
  389. ck_assert_uint_eq(deleteResponse.results[0], UA_STATUSCODE_GOOD);
  390. UA_DeleteMonitoredItemsResponse_deleteMembers(&deleteResponse);
  391. }
  392. END_TEST
  393. START_TEST(Server_MonitoredItemsPercentFilterSetLater) {
  394. UA_DataValue_init(&lastValue);
  395. /* define a monitored item with no filter */
  396. UA_MonitoredItemCreateRequest item = UA_MonitoredItemCreateRequest_default(outNodeId);;
  397. UA_UInt32 newMonitoredItemIds[1];
  398. UA_Client_DataChangeNotificationCallback callbacks[1];
  399. callbacks[0] = dataChangeHandler;
  400. UA_Client_DeleteMonitoredItemCallback deleteCallbacks[1] = {NULL};
  401. void *contexts[1];
  402. contexts[0] = NULL;
  403. UA_CreateMonitoredItemsRequest createRequest;
  404. UA_CreateMonitoredItemsRequest_init(&createRequest);
  405. createRequest.subscriptionId = subId;
  406. createRequest.timestampsToReturn = UA_TIMESTAMPSTORETURN_BOTH;
  407. createRequest.itemsToCreate = &item;
  408. createRequest.itemsToCreateSize = 1;
  409. UA_CreateMonitoredItemsResponse createResponse =
  410. UA_Client_MonitoredItems_createDataChanges(client, createRequest, contexts,
  411. callbacks, deleteCallbacks);
  412. ck_assert_uint_eq(createResponse.responseHeader.serviceResult, UA_STATUSCODE_GOOD);
  413. ck_assert_uint_eq(createResponse.resultsSize, 1);
  414. ck_assert_uint_eq(createResponse.results[0].statusCode, UA_STATUSCODE_GOOD);
  415. newMonitoredItemIds[0] = createResponse.results[0].monitoredItemId;
  416. UA_CreateMonitoredItemsResponse_deleteMembers(&createResponse);
  417. // Do we get initial value ?
  418. notificationReceived = false;
  419. countNotificationReceived = 0;
  420. ck_assert_uint_eq(waitForNotification(1, 10), UA_STATUSCODE_GOOD);
  421. ck_assert_uint_eq(notificationReceived, true);
  422. ck_assert_uint_eq(countNotificationReceived, 1);
  423. ck_assert(fuzzyLastValueIsEqualTo(40.0));
  424. // This should trigger because no filter
  425. notificationReceived = false;
  426. countNotificationReceived = 0;
  427. ck_assert_uint_eq(setDouble(client, outNodeId, 41.0), UA_STATUSCODE_GOOD);
  428. ck_assert_uint_eq(waitForNotification(1, 10), UA_STATUSCODE_GOOD);
  429. ck_assert_uint_eq(setDouble(client, outNodeId, 42.0), UA_STATUSCODE_GOOD);
  430. ck_assert_uint_eq(waitForNotification(2, 10), UA_STATUSCODE_GOOD);
  431. ck_assert_uint_eq(notificationReceived, true);
  432. ck_assert_uint_eq(countNotificationReceived, 2);
  433. ck_assert(fuzzyLastValueIsEqualTo(42.0));
  434. notificationReceived = false;
  435. countNotificationReceived = 0;
  436. ck_assert_uint_eq(setDouble(client, outNodeId, 43.0), UA_STATUSCODE_GOOD);
  437. ck_assert_uint_eq(waitForNotification(1, 10), UA_STATUSCODE_GOOD);
  438. ck_assert_uint_eq(setDouble(client, outNodeId, 44.0), UA_STATUSCODE_GOOD);
  439. ck_assert_uint_eq(waitForNotification(2, 10), UA_STATUSCODE_GOOD);
  440. ck_assert_uint_eq(notificationReceived, true);
  441. ck_assert_uint_eq(countNotificationReceived, 2);
  442. ck_assert(fuzzyLastValueIsEqualTo(44.0));
  443. // set back to 40.0
  444. notificationReceived = false;
  445. countNotificationReceived = 0;
  446. ck_assert_uint_eq(setDouble(client, outNodeId, 40.0), UA_STATUSCODE_GOOD);
  447. ck_assert_uint_eq(waitForNotification(1, 10), UA_STATUSCODE_GOOD);
  448. ck_assert_uint_eq(notificationReceived, true);
  449. ck_assert_uint_eq(countNotificationReceived, 1);
  450. ck_assert(fuzzyLastValueIsEqualTo(40.0));
  451. /* modify the monitored item with an percent filter with deadbandvalue = 2.0 */
  452. UA_MonitoredItemModifyRequest itemModify;
  453. UA_MonitoredItemModifyRequest_init(&itemModify);
  454. itemModify.monitoredItemId = newMonitoredItemIds[0];
  455. itemModify.requestedParameters.samplingInterval = 250;
  456. itemModify.requestedParameters.discardOldest = true;
  457. itemModify.requestedParameters.queueSize = 1;
  458. itemModify.requestedParameters.clientHandle = newMonitoredItemIds[0];
  459. UA_DataChangeFilter filter;
  460. UA_DataChangeFilter_init(&filter);
  461. filter.trigger = UA_DATACHANGETRIGGER_STATUSVALUE;
  462. filter.deadbandType = UA_DEADBANDTYPE_PERCENT;
  463. filter.deadbandValue = 2.0;
  464. itemModify.requestedParameters.filter.encoding = UA_EXTENSIONOBJECT_DECODED;
  465. itemModify.requestedParameters.filter.content.decoded.type = &UA_TYPES[UA_TYPES_DATACHANGEFILTER];
  466. itemModify.requestedParameters.filter.content.decoded.data = &filter;
  467. UA_ModifyMonitoredItemsRequest modifyRequest;
  468. UA_ModifyMonitoredItemsRequest_init(&modifyRequest);
  469. modifyRequest.subscriptionId = subId;
  470. modifyRequest.timestampsToReturn = UA_TIMESTAMPSTORETURN_BOTH;
  471. modifyRequest.itemsToModify = &itemModify;
  472. modifyRequest.itemsToModifySize = 1;
  473. UA_ModifyMonitoredItemsResponse modifyResponse =
  474. UA_Client_MonitoredItems_modify(client, modifyRequest);
  475. ck_assert_uint_eq(modifyResponse.resultsSize, 1);
  476. ck_assert_uint_eq(modifyResponse.results[0].statusCode, UA_STATUSCODE_BADMONITOREDITEMFILTERUNSUPPORTED);
  477. UA_ModifyMonitoredItemsResponse_deleteMembers(&modifyResponse);
  478. // This should trigger because setting filter failed
  479. notificationReceived = false;
  480. countNotificationReceived = 0;
  481. ck_assert_uint_eq(setDouble(client, outNodeId, 41.0), UA_STATUSCODE_GOOD);
  482. ck_assert_uint_eq(waitForNotification(1, 10), UA_STATUSCODE_GOOD);
  483. ck_assert_uint_eq(setDouble(client, outNodeId, 42.0), UA_STATUSCODE_GOOD);
  484. ck_assert_uint_eq(waitForNotification(2, 10), UA_STATUSCODE_GOOD);
  485. ck_assert_uint_eq(notificationReceived, true);
  486. ck_assert_uint_eq(countNotificationReceived, 2);
  487. ck_assert(fuzzyLastValueIsEqualTo(42.0));
  488. notificationReceived = false;
  489. countNotificationReceived = 0;
  490. ck_assert_uint_eq(setDouble(client, outNodeId, 43.0), UA_STATUSCODE_GOOD);
  491. ck_assert_uint_eq(waitForNotification(1, 10), UA_STATUSCODE_GOOD);
  492. ck_assert_uint_eq(setDouble(client, outNodeId, 44.0), UA_STATUSCODE_GOOD);
  493. ck_assert_uint_eq(waitForNotification(2, 10), UA_STATUSCODE_GOOD);
  494. ck_assert_uint_eq(notificationReceived, true);
  495. ck_assert_uint_eq(countNotificationReceived, 2);
  496. ck_assert(fuzzyLastValueIsEqualTo(44.0));
  497. // remove monitored item
  498. UA_DeleteMonitoredItemsRequest deleteRequest;
  499. UA_DeleteMonitoredItemsRequest_init(&deleteRequest);
  500. deleteRequest.subscriptionId = subId;
  501. deleteRequest.monitoredItemIds = newMonitoredItemIds;
  502. deleteRequest.monitoredItemIdsSize = 1;
  503. UA_DeleteMonitoredItemsResponse deleteResponse =
  504. UA_Client_MonitoredItems_delete(client, deleteRequest);
  505. ck_assert_uint_eq(deleteResponse.responseHeader.serviceResult, UA_STATUSCODE_GOOD);
  506. ck_assert_uint_eq(deleteResponse.resultsSize, 1);
  507. ck_assert_uint_eq(deleteResponse.results[0], UA_STATUSCODE_GOOD);
  508. UA_DeleteMonitoredItemsResponse_deleteMembers(&deleteResponse);
  509. }
  510. END_TEST
  511. START_TEST(Server_MonitoredItemsNoFilter) {
  512. UA_DataValue_init(&lastValue);
  513. /* define a monitored item with an absolute filter with deadbandvalue = 2.0 */
  514. UA_MonitoredItemCreateRequest item = UA_MonitoredItemCreateRequest_default(outNodeId);;
  515. UA_UInt32 newMonitoredItemIds[1];
  516. UA_Client_DataChangeNotificationCallback callbacks[1];
  517. callbacks[0] = dataChangeHandler;
  518. UA_Client_DeleteMonitoredItemCallback deleteCallbacks[1] = {NULL};
  519. void *contexts[1];
  520. contexts[0] = NULL;
  521. UA_CreateMonitoredItemsRequest createRequest;
  522. UA_CreateMonitoredItemsRequest_init(&createRequest);
  523. createRequest.subscriptionId = subId;
  524. createRequest.timestampsToReturn = UA_TIMESTAMPSTORETURN_BOTH;
  525. createRequest.itemsToCreate = &item;
  526. createRequest.itemsToCreateSize = 1;
  527. UA_CreateMonitoredItemsResponse createResponse =
  528. UA_Client_MonitoredItems_createDataChanges(client, createRequest, contexts,
  529. callbacks, deleteCallbacks);
  530. ck_assert_uint_eq(createResponse.responseHeader.serviceResult, UA_STATUSCODE_GOOD);
  531. ck_assert_uint_eq(createResponse.resultsSize, 1);
  532. ck_assert_uint_eq(createResponse.results[0].statusCode, UA_STATUSCODE_GOOD);
  533. newMonitoredItemIds[0] = createResponse.results[0].monitoredItemId;
  534. UA_CreateMonitoredItemsResponse_deleteMembers(&createResponse);
  535. // Do we get initial value ?
  536. notificationReceived = false;
  537. countNotificationReceived = 0;
  538. ck_assert_uint_eq(waitForNotification(1, 10), UA_STATUSCODE_GOOD);
  539. ck_assert_uint_eq(notificationReceived, true);
  540. ck_assert_uint_eq(countNotificationReceived, 1);
  541. ck_assert(fuzzyLastValueIsEqualTo(40.0));
  542. // This should trigger because no filter
  543. notificationReceived = false;
  544. countNotificationReceived = 0;
  545. ck_assert_uint_eq(setDouble(client, outNodeId, 41.0), UA_STATUSCODE_GOOD);
  546. ck_assert_uint_eq(waitForNotification(1, 10), UA_STATUSCODE_GOOD);
  547. ck_assert_uint_eq(setDouble(client, outNodeId, 42.0), UA_STATUSCODE_GOOD);
  548. ck_assert_uint_eq(waitForNotification(2, 10), UA_STATUSCODE_GOOD);
  549. ck_assert_uint_eq(notificationReceived, true);
  550. ck_assert_uint_eq(countNotificationReceived, 2);
  551. ck_assert(fuzzyLastValueIsEqualTo(42.0));
  552. notificationReceived = false;
  553. countNotificationReceived = 0;
  554. ck_assert_uint_eq(setDouble(client, outNodeId, 43.0), UA_STATUSCODE_GOOD);
  555. ck_assert_uint_eq(waitForNotification(1, 10), UA_STATUSCODE_GOOD);
  556. ck_assert_uint_eq(setDouble(client, outNodeId, 44.0), UA_STATUSCODE_GOOD);
  557. ck_assert_uint_eq(waitForNotification(2, 10), UA_STATUSCODE_GOOD);
  558. ck_assert_uint_eq(notificationReceived, true);
  559. ck_assert_uint_eq(countNotificationReceived, 2);
  560. ck_assert(fuzzyLastValueIsEqualTo(44.0));
  561. // remove monitored item
  562. UA_DeleteMonitoredItemsRequest deleteRequest;
  563. UA_DeleteMonitoredItemsRequest_init(&deleteRequest);
  564. deleteRequest.subscriptionId = subId;
  565. deleteRequest.monitoredItemIds = newMonitoredItemIds;
  566. deleteRequest.monitoredItemIdsSize = 1;
  567. UA_DeleteMonitoredItemsResponse deleteResponse =
  568. UA_Client_MonitoredItems_delete(client, deleteRequest);
  569. ck_assert_uint_eq(deleteResponse.responseHeader.serviceResult, UA_STATUSCODE_GOOD);
  570. ck_assert_uint_eq(deleteResponse.resultsSize, 1);
  571. ck_assert_uint_eq(deleteResponse.results[0], UA_STATUSCODE_GOOD);
  572. UA_DeleteMonitoredItemsResponse_deleteMembers(&deleteResponse);
  573. }
  574. END_TEST
  575. /* Test if an absolute filter can be added for boolean variables */
  576. START_TEST(Server_MonitoredItemsAbsoluteFilterOnBool) {
  577. UA_DataValue_init(&lastValue);
  578. /* define a monitored item with an absolute filter with deadbandvalue = 2.0 */
  579. UA_MonitoredItemCreateRequest item =
  580. UA_MonitoredItemCreateRequest_default(UA_NODEID_STRING(1, "the.bool"));;
  581. UA_DataChangeFilter filter;
  582. UA_DataChangeFilter_init(&filter);
  583. filter.trigger = UA_DATACHANGETRIGGER_STATUSVALUE;
  584. filter.deadbandType = UA_DEADBANDTYPE_ABSOLUTE;
  585. filter.deadbandValue = 0.5;
  586. item.requestedParameters.filter.encoding = UA_EXTENSIONOBJECT_DECODED;
  587. item.requestedParameters.filter.content.decoded.type = &UA_TYPES[UA_TYPES_DATACHANGEFILTER];
  588. item.requestedParameters.filter.content.decoded.data = &filter;
  589. UA_Client_DataChangeNotificationCallback callbacks[1];
  590. callbacks[0] = dataChangeHandler;
  591. UA_Client_DeleteMonitoredItemCallback deleteCallbacks[1] = {NULL};
  592. void *contexts[1];
  593. contexts[0] = NULL;
  594. UA_CreateMonitoredItemsRequest createRequest;
  595. UA_CreateMonitoredItemsRequest_init(&createRequest);
  596. createRequest.subscriptionId = subId;
  597. createRequest.timestampsToReturn = UA_TIMESTAMPSTORETURN_BOTH;
  598. createRequest.itemsToCreate = &item;
  599. createRequest.itemsToCreateSize = 1;
  600. UA_CreateMonitoredItemsResponse createResponse =
  601. UA_Client_MonitoredItems_createDataChanges(client, createRequest, contexts,
  602. callbacks, deleteCallbacks);
  603. ck_assert_uint_eq(createResponse.responseHeader.serviceResult, UA_STATUSCODE_GOOD);
  604. ck_assert_uint_eq(createResponse.resultsSize, 1);
  605. ck_assert_uint_eq(createResponse.results[0].statusCode, UA_STATUSCODE_GOOD);
  606. UA_CreateMonitoredItemsResponse_deleteMembers(&createResponse);
  607. }
  608. END_TEST
  609. START_TEST(Server_MonitoredItemsAbsoluteFilterSetOnCreate) {
  610. UA_DataValue_init(&lastValue);
  611. /* define a monitored item with an absolute filter with deadbandvalue = 2.0 */
  612. UA_MonitoredItemCreateRequest item = UA_MonitoredItemCreateRequest_default(outNodeId);;
  613. UA_DataChangeFilter filter;
  614. UA_DataChangeFilter_init(&filter);
  615. filter.trigger = UA_DATACHANGETRIGGER_STATUSVALUE;
  616. filter.deadbandType = UA_DEADBANDTYPE_ABSOLUTE;
  617. filter.deadbandValue = 2.0;
  618. item.requestedParameters.filter.encoding = UA_EXTENSIONOBJECT_DECODED;
  619. item.requestedParameters.filter.content.decoded.type = &UA_TYPES[UA_TYPES_DATACHANGEFILTER];
  620. item.requestedParameters.filter.content.decoded.data = &filter;
  621. UA_UInt32 newMonitoredItemIds[1];
  622. UA_Client_DataChangeNotificationCallback callbacks[1];
  623. callbacks[0] = dataChangeHandler;
  624. UA_Client_DeleteMonitoredItemCallback deleteCallbacks[1] = {NULL};
  625. void *contexts[1];
  626. contexts[0] = NULL;
  627. UA_CreateMonitoredItemsRequest createRequest;
  628. UA_CreateMonitoredItemsRequest_init(&createRequest);
  629. createRequest.subscriptionId = subId;
  630. createRequest.timestampsToReturn = UA_TIMESTAMPSTORETURN_BOTH;
  631. createRequest.itemsToCreate = &item;
  632. createRequest.itemsToCreateSize = 1;
  633. UA_CreateMonitoredItemsResponse createResponse =
  634. UA_Client_MonitoredItems_createDataChanges(client, createRequest, contexts,
  635. callbacks, deleteCallbacks);
  636. ck_assert_uint_eq(createResponse.responseHeader.serviceResult, UA_STATUSCODE_GOOD);
  637. ck_assert_uint_eq(createResponse.resultsSize, 1);
  638. ck_assert_uint_eq(createResponse.results[0].statusCode, UA_STATUSCODE_GOOD);
  639. newMonitoredItemIds[0] = createResponse.results[0].monitoredItemId;
  640. UA_CreateMonitoredItemsResponse_deleteMembers(&createResponse);
  641. // Do we get initial value ?
  642. notificationReceived = false;
  643. countNotificationReceived = 0;
  644. ck_assert_uint_eq(waitForNotification(1, 10), UA_STATUSCODE_GOOD);
  645. ck_assert_uint_eq(notificationReceived, true);
  646. ck_assert_uint_eq(countNotificationReceived, 1);
  647. ck_assert(fuzzyLastValueIsEqualTo(40.0));
  648. // This should not trigger because of filter
  649. notificationReceived = false;
  650. countNotificationReceived = 0;
  651. ck_assert_uint_eq(setDouble(client, outNodeId, 41.0), UA_STATUSCODE_GOOD);
  652. ck_assert_uint_eq(waitForNotification(0, 10), UA_STATUSCODE_GOOD);
  653. ck_assert_uint_eq(setDouble(client, outNodeId, 42.0), UA_STATUSCODE_GOOD);
  654. ck_assert_uint_eq(waitForNotification(0, 10), UA_STATUSCODE_GOOD);
  655. ck_assert_uint_eq(notificationReceived, false);
  656. ck_assert_uint_eq(countNotificationReceived, 0);
  657. ck_assert(fuzzyLastValueIsEqualTo(40.0));
  658. // This should trigger once at 43.0.
  659. notificationReceived = false;
  660. countNotificationReceived = 0;
  661. ck_assert_uint_eq(setDouble(client, outNodeId, 43.0), UA_STATUSCODE_GOOD);
  662. ck_assert_uint_eq(waitForNotification(1, 10), UA_STATUSCODE_GOOD);
  663. ck_assert_uint_eq(setDouble(client, outNodeId, 44.0), UA_STATUSCODE_GOOD);
  664. ck_assert_uint_eq(waitForNotification(1, 10), UA_STATUSCODE_GOOD);
  665. ck_assert_uint_eq(notificationReceived, true);
  666. ck_assert_uint_eq(countNotificationReceived, 1);
  667. ck_assert(fuzzyLastValueIsEqualTo(43.0));
  668. // remove monitored item
  669. UA_DeleteMonitoredItemsRequest deleteRequest;
  670. UA_DeleteMonitoredItemsRequest_init(&deleteRequest);
  671. deleteRequest.subscriptionId = subId;
  672. deleteRequest.monitoredItemIds = newMonitoredItemIds;
  673. deleteRequest.monitoredItemIdsSize = 1;
  674. UA_DeleteMonitoredItemsResponse deleteResponse =
  675. UA_Client_MonitoredItems_delete(client, deleteRequest);
  676. ck_assert_uint_eq(deleteResponse.responseHeader.serviceResult, UA_STATUSCODE_GOOD);
  677. ck_assert_uint_eq(deleteResponse.resultsSize, 1);
  678. ck_assert_uint_eq(deleteResponse.results[0], UA_STATUSCODE_GOOD);
  679. UA_DeleteMonitoredItemsResponse_deleteMembers(&deleteResponse);
  680. }
  681. END_TEST
  682. START_TEST(Server_MonitoredItemsPercentFilterSetOnCreate) {
  683. UA_DataValue_init(&lastValue);
  684. /* define a monitored item with an percent filter with deadbandvalue = 2.0 */
  685. UA_MonitoredItemCreateRequest item = UA_MonitoredItemCreateRequest_default(outNodeId);;
  686. UA_DataChangeFilter filter;
  687. UA_DataChangeFilter_init(&filter);
  688. filter.trigger = UA_DATACHANGETRIGGER_STATUSVALUE;
  689. filter.deadbandType = UA_DEADBANDTYPE_PERCENT;
  690. filter.deadbandValue = 2.0;
  691. item.requestedParameters.filter.encoding = UA_EXTENSIONOBJECT_DECODED;
  692. item.requestedParameters.filter.content.decoded.type = &UA_TYPES[UA_TYPES_DATACHANGEFILTER];
  693. item.requestedParameters.filter.content.decoded.data = &filter;
  694. UA_UInt32 newMonitoredItemIds[1];
  695. UA_Client_DataChangeNotificationCallback callbacks[1];
  696. callbacks[0] = dataChangeHandler;
  697. UA_Client_DeleteMonitoredItemCallback deleteCallbacks[1] = {NULL};
  698. void *contexts[1];
  699. contexts[0] = NULL;
  700. UA_CreateMonitoredItemsRequest createRequest;
  701. UA_CreateMonitoredItemsRequest_init(&createRequest);
  702. createRequest.subscriptionId = subId;
  703. createRequest.timestampsToReturn = UA_TIMESTAMPSTORETURN_BOTH;
  704. createRequest.itemsToCreate = &item;
  705. createRequest.itemsToCreateSize = 1;
  706. UA_CreateMonitoredItemsResponse createResponse =
  707. UA_Client_MonitoredItems_createDataChanges(client, createRequest, contexts,
  708. callbacks, deleteCallbacks);
  709. ck_assert_uint_eq(createResponse.responseHeader.serviceResult, UA_STATUSCODE_GOOD);
  710. ck_assert_uint_eq(createResponse.resultsSize, 1);
  711. ck_assert_uint_eq(createResponse.results[0].statusCode, UA_STATUSCODE_BADMONITOREDITEMFILTERUNSUPPORTED);
  712. newMonitoredItemIds[0] = createResponse.results[0].monitoredItemId;
  713. UA_CreateMonitoredItemsResponse_deleteMembers(&createResponse);
  714. // Do we get initial value ? (must fail)
  715. notificationReceived = false;
  716. countNotificationReceived = 0;
  717. ck_assert_uint_eq(waitForNotification(0, 10), UA_STATUSCODE_GOOD);
  718. ck_assert_uint_eq(notificationReceived, false);
  719. ck_assert_uint_eq(countNotificationReceived, 0);
  720. // remove monitored item (must fail)
  721. UA_DeleteMonitoredItemsRequest deleteRequest;
  722. UA_DeleteMonitoredItemsRequest_init(&deleteRequest);
  723. deleteRequest.subscriptionId = subId;
  724. deleteRequest.monitoredItemIds = newMonitoredItemIds;
  725. deleteRequest.monitoredItemIdsSize = 1;
  726. UA_DeleteMonitoredItemsResponse deleteResponse =
  727. UA_Client_MonitoredItems_delete(client, deleteRequest);
  728. ck_assert_uint_eq(deleteResponse.responseHeader.serviceResult, UA_STATUSCODE_GOOD);
  729. ck_assert_uint_eq(deleteResponse.resultsSize, 1);
  730. ck_assert_uint_eq(deleteResponse.results[0], UA_STATUSCODE_BADMONITOREDITEMIDINVALID);
  731. UA_DeleteMonitoredItemsResponse_deleteMembers(&deleteResponse);
  732. }
  733. END_TEST
  734. #endif /*UA_ENABLE_SUBSCRIPTIONS*/
  735. static Suite* testSuite_Client(void) {
  736. Suite *s = suite_create("Server monitored item filter");
  737. TCase *tc_server = tcase_create("Server monitored item filter Basic");
  738. tcase_add_checked_fixture(tc_server, setup, teardown);
  739. #ifdef UA_ENABLE_SUBSCRIPTIONS
  740. tcase_add_test(tc_server, Server_MonitoredItemsNoFilter);
  741. tcase_add_test(tc_server, Server_MonitoredItemsAbsoluteFilterSetOnCreate);
  742. tcase_add_test(tc_server, Server_MonitoredItemsAbsoluteFilterOnBool);
  743. tcase_add_test(tc_server, Server_MonitoredItemsAbsoluteFilterSetLater);
  744. tcase_add_test(tc_server, Server_MonitoredItemsAbsoluteFilterSetOnCreateRemoveLater);
  745. tcase_add_test(tc_server, Server_MonitoredItemsPercentFilterSetOnCreate);
  746. tcase_add_test(tc_server, Server_MonitoredItemsPercentFilterSetLater);
  747. #endif /* UA_ENABLE_SUBSCRIPTIONS */
  748. suite_add_tcase(s, tc_server);
  749. return s;
  750. }
  751. int main(void) {
  752. Suite *s = testSuite_Client();
  753. SRunner *sr = srunner_create(s);
  754. srunner_set_fork_status(sr, CK_NOFORK);
  755. srunner_run_all(sr,CK_NORMAL);
  756. int number_failed = srunner_ntests_failed(sr);
  757. srunner_free(sr);
  758. return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
  759. }