check_monitoreditem_filter.c 39 KB

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