check_monitoreditem_filter.c 39 KB

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