1use std::{
2 collections::HashSet,
3 time::{Duration, Instant},
4};
5
6use crate::{
7 session::{
8 process_service_result, process_unexpected_response,
9 request_builder::{builder_base, builder_debug, builder_error, RequestHeaderBuilder},
10 services::subscriptions::{
11 callbacks::OnSubscriptionNotificationCore, ModifyMonitoredItem,
12 PreInsertMonitoredItems, Subscription,
13 },
14 session_debug, session_error, session_warn,
15 },
16 Session, UARequest,
17};
18use opcua_core::{handle::AtomicHandle, sync::Mutex, trace_lock, ResponseMessage};
19use opcua_types::{
20 AttributeId, CreateMonitoredItemsRequest, CreateSubscriptionRequest,
21 CreateSubscriptionResponse, DeleteMonitoredItemsRequest, DeleteMonitoredItemsResponse,
22 DeleteSubscriptionsRequest, DeleteSubscriptionsResponse, DiagnosticInfo, Error,
23 ExtensionObject, IntegerId, ModifyMonitoredItemsRequest, ModifyMonitoredItemsResponse,
24 ModifySubscriptionRequest, ModifySubscriptionResponse, MonitoredItemCreateRequest,
25 MonitoredItemCreateResult, MonitoredItemModifyRequest, MonitoredItemModifyResult,
26 MonitoringMode, MonitoringParameters, NodeId, NotificationMessage, PublishRequest,
27 PublishResponse, ReadValueId, RepublishRequest, RepublishResponse, ResponseHeader,
28 SetMonitoringModeRequest, SetMonitoringModeResponse, SetPublishingModeRequest,
29 SetPublishingModeResponse, SetTriggeringRequest, SetTriggeringResponse, StatusCode,
30 SubscriptionAcknowledgement, TimestampsToReturn, TransferResult, TransferSubscriptionsRequest,
31 TransferSubscriptionsResponse,
32};
33use tracing::{debug_span, enabled, Instrument};
34
35use super::state::SubscriptionState;
36
37pub struct CreateSubscription {
41 publishing_interval: Duration,
42 lifetime_count: u32,
43 keep_alive_count: u32,
44 max_notifications_per_publish: u32,
45 publishing_enabled: bool,
46 priority: u8,
47
48 header: RequestHeaderBuilder,
49}
50
51builder_base!(CreateSubscription);
52
53impl CreateSubscription {
54 pub fn new(session: &Session) -> Self {
56 Self {
57 publishing_interval: Duration::from_millis(500),
58 lifetime_count: 60,
59 keep_alive_count: 20,
60 max_notifications_per_publish: 0,
61 publishing_enabled: true,
62 priority: 0,
63 header: RequestHeaderBuilder::new_from_session(session),
64 }
65 }
66
67 pub fn new_manual(
69 session_id: u32,
70 timeout: Duration,
71 auth_token: NodeId,
72 request_handle: IntegerId,
73 ) -> Self {
74 Self {
75 publishing_interval: Duration::from_millis(500),
76 lifetime_count: 60,
77 keep_alive_count: 20,
78 max_notifications_per_publish: 0,
79 publishing_enabled: true,
80 priority: 0,
81 header: RequestHeaderBuilder::new(session_id, timeout, auth_token, request_handle),
82 }
83 }
84
85 pub fn publishing_interval(mut self, interval: Duration) -> Self {
93 self.publishing_interval = interval;
94 self
95 }
96
97 pub fn max_lifetime_count(mut self, lifetime_count: u32) -> Self {
102 self.lifetime_count = lifetime_count;
103 self
104 }
105
106 pub fn max_keep_alive_count(mut self, keep_alive_count: u32) -> Self {
112 self.keep_alive_count = keep_alive_count;
113 self
114 }
115
116 pub fn max_notifications_per_publish(mut self, max_notifications_per_publish: u32) -> Self {
121 self.max_notifications_per_publish = max_notifications_per_publish;
122 self
123 }
124
125 pub fn priority(mut self, priority: u8) -> Self {
130 self.priority = priority;
131 self
132 }
133
134 pub fn publishing_enabled(mut self, publishing_enabled: bool) -> Self {
139 self.publishing_enabled = publishing_enabled;
140 self
141 }
142}
143
144impl UARequest for CreateSubscription {
145 type Out = CreateSubscriptionResponse;
146
147 async fn send<'a>(self, channel: &'a crate::AsyncSecureChannel) -> Result<Self::Out, Error>
148 where
149 Self: 'a,
150 {
151 let request = CreateSubscriptionRequest {
152 request_header: self.header.header,
153 requested_publishing_interval: self.publishing_interval.as_millis() as f64,
154 requested_lifetime_count: self.lifetime_count,
155 requested_max_keep_alive_count: self.keep_alive_count,
156 max_notifications_per_publish: self.max_notifications_per_publish,
157 publishing_enabled: self.publishing_enabled,
158 priority: self.priority,
159 };
160 let span = debug_span!(
161 "Sending CreateSubscription request",
162 publishing_interval_ms = self.publishing_interval.as_millis(),
163 lifetime_count = self.lifetime_count,
164 keep_alive_count = self.keep_alive_count,
165 max_notifications_per_publish = self.max_notifications_per_publish,
166 publishing_enabled = self.publishing_enabled,
167 priority = self.priority
168 );
169
170 let response = channel
171 .send(request, self.header.timeout)
172 .instrument(span.clone())
173 .await?;
174
175 let _h = span.enter();
176 if let ResponseMessage::CreateSubscription(response) = response {
177 process_service_result(&response.response_header)?;
178 builder_debug!(
179 self,
180 "create_subscription, created a subscription with id {}",
181 response.subscription_id
182 );
183 Ok(*response)
184 } else {
185 builder_error!(self, "create_subscription failed {:?}", response);
186 Err(process_unexpected_response(response))
187 }
188 }
189}
190
191#[derive(Clone)]
195pub struct ModifySubscription {
196 subscription_id: u32,
197 publishing_interval: Duration,
198 lifetime_count: u32,
199 keep_alive_count: u32,
200 max_notifications_per_publish: u32,
201 priority: u8,
202
203 header: RequestHeaderBuilder,
204}
205
206builder_base!(ModifySubscription);
207
208impl ModifySubscription {
209 pub fn new(subscription_id: u32, session: &Session) -> Self {
211 Self {
212 subscription_id,
213 publishing_interval: Duration::from_millis(500),
214 lifetime_count: 60,
215 keep_alive_count: 20,
216 max_notifications_per_publish: 0,
217 priority: 0,
218 header: RequestHeaderBuilder::new_from_session(session),
219 }
220 }
221
222 pub fn new_manual(
224 subscription_id: u32,
225 session_id: u32,
226 timeout: Duration,
227 auth_token: NodeId,
228 request_handle: IntegerId,
229 ) -> Self {
230 Self {
231 subscription_id,
232 publishing_interval: Duration::from_millis(500),
233 lifetime_count: 60,
234 keep_alive_count: 20,
235 max_notifications_per_publish: 0,
236 priority: 0,
237 header: RequestHeaderBuilder::new(session_id, timeout, auth_token, request_handle),
238 }
239 }
240
241 pub fn publishing_interval(mut self, interval: Duration) -> Self {
249 self.publishing_interval = interval;
250 self
251 }
252
253 pub fn max_lifetime_count(mut self, lifetime_count: u32) -> Self {
258 self.lifetime_count = lifetime_count;
259 self
260 }
261
262 pub fn max_keep_alive_count(mut self, keep_alive_count: u32) -> Self {
268 self.keep_alive_count = keep_alive_count;
269 self
270 }
271
272 pub fn max_notifications_per_publish(mut self, max_notifications_per_publish: u32) -> Self {
277 self.max_notifications_per_publish = max_notifications_per_publish;
278 self
279 }
280
281 pub fn priority(mut self, priority: u8) -> Self {
286 self.priority = priority;
287 self
288 }
289}
290
291impl UARequest for ModifySubscription {
292 type Out = ModifySubscriptionResponse;
293
294 async fn send<'a>(self, channel: &'a crate::AsyncSecureChannel) -> Result<Self::Out, Error>
295 where
296 Self: 'a,
297 {
298 let span = debug_span!(
299 "Sending ModifySubscription request",
300 subscription_id = self.subscription_id,
301 publishing_interval_ms = self.publishing_interval.as_millis(),
302 lifetime_count = self.lifetime_count,
303 keep_alive_count = self.keep_alive_count,
304 max_notifications_per_publish = self.max_notifications_per_publish,
305 priority = self.priority
306 );
307 let request = {
308 let _h = span.enter();
309 if self.subscription_id == 0 {
310 builder_error!(
311 self,
312 "modify_subscription, subscription id must be non-zero"
313 );
314 return Err(Error::new(
315 StatusCode::BadInvalidArgument,
316 "modify_subscription, subscription id must be non-zero",
317 ));
318 }
319
320 ModifySubscriptionRequest {
321 request_header: self.header.header,
322 subscription_id: self.subscription_id,
323 requested_publishing_interval: self.publishing_interval.as_millis() as f64,
324 requested_lifetime_count: self.lifetime_count,
325 requested_max_keep_alive_count: self.keep_alive_count,
326 max_notifications_per_publish: self.max_notifications_per_publish,
327 priority: self.priority,
328 }
329 };
330
331 let response = channel
332 .send(request, self.header.timeout)
333 .instrument(span.clone())
334 .await?;
335
336 let _h = span.enter();
337 if let ResponseMessage::ModifySubscription(response) = response {
338 process_service_result(&response.response_header)?;
339 builder_debug!(
340 self,
341 "modify_subscription success for {}",
342 self.subscription_id
343 );
344 Ok(*response)
345 } else {
346 builder_debug!(self, "modify_subscription failed");
347 Err(process_unexpected_response(response))
348 }
349 }
350}
351
352#[derive(Clone)]
356pub struct SetPublishingMode {
357 subscription_ids: Vec<u32>,
358 publishing_enabled: bool,
359
360 header: RequestHeaderBuilder,
361}
362
363builder_base!(SetPublishingMode);
364
365impl SetPublishingMode {
366 pub fn new(publishing_enabled: bool, session: &Session) -> Self {
368 Self {
369 subscription_ids: Vec::new(),
370 publishing_enabled,
371 header: RequestHeaderBuilder::new_from_session(session),
372 }
373 }
374
375 pub fn new_manual(
377 publishing_enabled: bool,
378 session_id: u32,
379 timeout: Duration,
380 auth_token: NodeId,
381 request_handle: IntegerId,
382 ) -> Self {
383 Self {
384 subscription_ids: Vec::new(),
385 publishing_enabled,
386 header: RequestHeaderBuilder::new(session_id, timeout, auth_token, request_handle),
387 }
388 }
389
390 pub fn subscription_ids(mut self, subscription_ids: Vec<u32>) -> Self {
392 self.subscription_ids = subscription_ids;
393 self
394 }
395
396 pub fn subscription(mut self, subscription_id: u32) -> Self {
398 self.subscription_ids.push(subscription_id);
399 self
400 }
401}
402
403impl UARequest for SetPublishingMode {
404 type Out = SetPublishingModeResponse;
405
406 async fn send<'a>(self, channel: &'a crate::AsyncSecureChannel) -> Result<Self::Out, Error>
407 where
408 Self: 'a,
409 {
410 let span = debug_span!(
411 "Sending SetPublishingMode request",
412 subscription_ids = ?self.subscription_ids,
413 publishing_enabled = self.publishing_enabled
414 );
415 let request = {
416 let _h = span.enter();
417 if self.subscription_ids.is_empty() {
418 builder_error!(
419 self,
420 "set_publishing_mode, no subscription ids were provided"
421 );
422 return Err(Error::new(
423 StatusCode::BadNothingToDo,
424 "set_publishing_mode, no subscription ids were provided",
425 ));
426 }
427
428 SetPublishingModeRequest {
429 request_header: self.header.header,
430 publishing_enabled: self.publishing_enabled,
431 subscription_ids: Some(self.subscription_ids.clone()),
432 }
433 };
434
435 let response = channel
436 .send(request, self.header.timeout)
437 .instrument(span.clone())
438 .await?;
439 let _h = span.enter();
440 if let ResponseMessage::SetPublishingMode(response) = response {
441 process_service_result(&response.response_header)?;
442 let num_results = response
443 .results
444 .as_ref()
445 .map(|l| l.len())
446 .unwrap_or_default();
447
448 if num_results != self.subscription_ids.len() {
449 builder_error!(
450 self,
451 "set_publishing_mode returned an incorrect number of results. Expected {}, got {}",
452 self.subscription_ids.len(),
453 num_results
454 );
455 return Err(Error::new(StatusCode::BadUnexpectedError, format!("set_publishing_mode returned an incorrect number of results. Expected {}, got {}",
456 self.subscription_ids.len(),
457 num_results)
458 ));
459 }
460
461 builder_debug!(self, "set_publishing_mode success");
462 Ok(*response)
463 } else {
464 builder_error!(self, "set_publishing_mode failed {:?}", response);
465 Err(process_unexpected_response(response))
466 }
467 }
468}
469
470#[derive(Clone)]
471pub struct Publish {
475 header: RequestHeaderBuilder,
476 acks: Vec<SubscriptionAcknowledgement>,
477}
478
479builder_base!(Publish);
480
481impl Publish {
482 pub fn new(session: &Session) -> Self {
484 Self {
485 header: RequestHeaderBuilder::new_from_session(session),
486 acks: Vec::new(),
487 }
488 .timeout(session.publish_timeout)
489 }
490
491 pub fn new_manual(
493 session_id: u32,
494 timeout: Duration,
495 auth_token: NodeId,
496 request_handle: IntegerId,
497 ) -> Self {
498 Self {
499 header: RequestHeaderBuilder::new(session_id, timeout, auth_token, request_handle),
500 acks: Vec::new(),
501 }
502 }
503
504 pub fn acks(mut self, acks: Vec<SubscriptionAcknowledgement>) -> Self {
506 self.acks = acks;
507 self
508 }
509
510 pub fn ack(mut self, subscription_id: u32, sequence_number: u32) -> Self {
512 self.acks.push(SubscriptionAcknowledgement {
513 subscription_id,
514 sequence_number,
515 });
516 self
517 }
518}
519
520impl UARequest for Publish {
521 type Out = PublishResponse;
522
523 async fn send<'a>(self, channel: &'a crate::AsyncSecureChannel) -> Result<Self::Out, Error>
524 where
525 Self: 'a,
526 {
527 let span = debug_span!(
528 "Sending Publish request",
529 num_acks = self.acks.len(),
530 timeout_ms = self.header.timeout.as_millis()
531 );
532 let request = {
533 let _h = span.enter();
534 if enabled!(tracing::Level::DEBUG) {
535 let sequence_nrs: Vec<u32> =
536 self.acks.iter().map(|ack| ack.sequence_number).collect();
537 builder_debug!(
538 self,
539 "publish, acknowledging subscription acknowledgements with sequence nrs {:?}",
540 sequence_nrs
541 );
542 }
543 PublishRequest {
544 request_header: self.header.header,
545 subscription_acknowledgements: if self.acks.is_empty() {
546 None
547 } else {
548 Some(self.acks.clone())
549 },
550 }
551 };
552
553 let response = channel
554 .send(request, self.header.timeout)
555 .instrument(span.clone())
556 .await?;
557 let _h = span.enter();
558 if let ResponseMessage::Publish(response) = response {
559 process_service_result(&response.response_header)?;
560 builder_debug!(self, "publish success");
561 Ok(*response)
562 } else {
563 builder_error!(self, "publish failed {:?}", response);
564 Err(process_unexpected_response(response))
565 }
566 }
567}
568
569pub struct Republish {
573 subscription_id: u32,
574 retransmit_sequence_number: u32,
575
576 header: RequestHeaderBuilder,
577}
578
579builder_base!(Republish);
580
581impl Republish {
582 pub fn new(subscription_id: u32, retransmit_sequence_number: u32, session: &Session) -> Self {
584 Self {
585 subscription_id,
586 retransmit_sequence_number,
587 header: RequestHeaderBuilder::new_from_session(session),
588 }
589 }
590
591 pub fn new_manual(
593 subscription_id: u32,
594 retransmit_sequence_number: u32,
595 session_id: u32,
596 timeout: Duration,
597 auth_token: NodeId,
598 request_handle: IntegerId,
599 ) -> Self {
600 Self {
601 subscription_id,
602 retransmit_sequence_number,
603 header: RequestHeaderBuilder::new(session_id, timeout, auth_token, request_handle),
604 }
605 }
606}
607
608impl UARequest for Republish {
609 type Out = RepublishResponse;
610 async fn send<'a>(self, channel: &'a crate::AsyncSecureChannel) -> Result<Self::Out, Error>
611 where
612 Self: 'a,
613 {
614 let request = RepublishRequest {
615 request_header: self.header.header,
616 subscription_id: self.subscription_id,
617 retransmit_sequence_number: self.retransmit_sequence_number,
618 };
619 let span = debug_span!(
620 "Sending Republish request",
621 subscription_id = self.subscription_id,
622 retransmit_sequence_number = self.retransmit_sequence_number
623 );
624
625 let response = channel
626 .send(request, self.header.timeout)
627 .instrument(span.clone())
628 .await?;
629
630 let _h = span.enter();
631 if let ResponseMessage::Republish(response) = response {
632 process_service_result(&response.response_header)?;
633 builder_debug!(self, "republish success");
634 Ok(*response)
635 } else {
636 builder_error!(self, "republish failed {:?}", response);
637 Err(process_unexpected_response(response))
638 }
639 }
640}
641
642#[derive(Clone)]
643pub struct TransferSubscriptions {
655 subscription_ids: Vec<u32>,
656 send_initial_values: bool,
657
658 header: RequestHeaderBuilder,
659}
660
661builder_base!(TransferSubscriptions);
662
663impl TransferSubscriptions {
664 pub fn new(session: &Session) -> Self {
666 Self {
667 subscription_ids: Vec::new(),
668 send_initial_values: false,
669 header: RequestHeaderBuilder::new_from_session(session),
670 }
671 }
672
673 pub fn new_manual(
675 session_id: u32,
676 timeout: Duration,
677 auth_token: NodeId,
678 request_handle: IntegerId,
679 ) -> Self {
680 Self {
681 subscription_ids: Vec::new(),
682 send_initial_values: false,
683 header: RequestHeaderBuilder::new(session_id, timeout, auth_token, request_handle),
684 }
685 }
686 pub fn send_initial_values(mut self, send_initial_values: bool) -> Self {
691 self.send_initial_values = send_initial_values;
692 self
693 }
694
695 pub fn subscription_ids(mut self, subscription_ids: Vec<u32>) -> Self {
697 self.subscription_ids = subscription_ids;
698 self
699 }
700
701 pub fn subscription(mut self, subscription_id: u32) -> Self {
703 self.subscription_ids.push(subscription_id);
704 self
705 }
706}
707
708impl UARequest for TransferSubscriptions {
709 type Out = TransferSubscriptionsResponse;
710
711 async fn send<'a>(self, channel: &'a crate::AsyncSecureChannel) -> Result<Self::Out, Error>
712 where
713 Self: 'a,
714 {
715 let span = debug_span!(
716 "Sending TransferSubscriptions request",
717 subscription_ids = ?self.subscription_ids,
718 send_initial_values = self.send_initial_values
719 );
720 let request = {
721 let _h = span.enter();
722 if self.subscription_ids.is_empty() {
723 builder_error!(
724 self,
725 "transfer_subscriptions, no subscription ids were provided"
726 );
727 return Err(Error::new(
728 StatusCode::BadNothingToDo,
729 "transfer_subscriptions, no subscription ids were provided",
730 ));
731 }
732 TransferSubscriptionsRequest {
733 request_header: self.header.header,
734 subscription_ids: Some(self.subscription_ids),
735 send_initial_values: self.send_initial_values,
736 }
737 };
738 let response = channel
739 .send(request, self.header.timeout)
740 .instrument(span.clone())
741 .await?;
742 let _h = span.enter();
743 if let ResponseMessage::TransferSubscriptions(response) = response {
744 process_service_result(&response.response_header)?;
745 builder_debug!(self, "transfer_subscriptions success");
746 Ok(*response)
747 } else {
748 builder_error!(self, "transfer_subscriptions failed {:?}", response);
749 Err(process_unexpected_response(response))
750 }
751 }
752}
753
754#[derive(Clone)]
755pub struct DeleteSubscriptions {
760 subscription_ids: Vec<u32>,
761
762 header: RequestHeaderBuilder,
763}
764
765builder_base!(DeleteSubscriptions);
766
767impl DeleteSubscriptions {
768 pub fn new(session: &Session) -> Self {
770 Self {
771 subscription_ids: Vec::new(),
772 header: RequestHeaderBuilder::new_from_session(session),
773 }
774 }
775
776 pub fn new_manual(
778 session_id: u32,
779 timeout: Duration,
780 auth_token: NodeId,
781 request_handle: IntegerId,
782 ) -> Self {
783 Self {
784 subscription_ids: Vec::new(),
785 header: RequestHeaderBuilder::new(session_id, timeout, auth_token, request_handle),
786 }
787 }
788
789 pub fn subscription_ids(mut self, subscription_ids: Vec<u32>) -> Self {
791 self.subscription_ids = subscription_ids;
792 self
793 }
794
795 pub fn subscription(mut self, subscription_id: u32) -> Self {
797 self.subscription_ids.push(subscription_id);
798 self
799 }
800}
801
802impl UARequest for DeleteSubscriptions {
803 type Out = DeleteSubscriptionsResponse;
804
805 async fn send<'a>(self, channel: &'a crate::AsyncSecureChannel) -> Result<Self::Out, Error>
806 where
807 Self: 'a,
808 {
809 let span = debug_span!(
810 "Sending DeleteSubscriptions request",
811 subscription_ids = ?self.subscription_ids
812 );
813 let request = {
814 let _h = span.enter();
815 if self.subscription_ids.is_empty() {
816 builder_error!(self, "delete_subscriptions called with no subscription IDs");
817 return Err(Error::new(
818 StatusCode::BadNothingToDo,
819 "delete_subscriptions called with no subscription IDs",
820 ));
821 }
822 DeleteSubscriptionsRequest {
823 request_header: self.header.header,
824 subscription_ids: Some(self.subscription_ids.clone()),
825 }
826 };
827 let response = channel
828 .send(request, self.header.timeout)
829 .instrument(span.clone())
830 .await?;
831 let _h = span.enter();
832 if let ResponseMessage::DeleteSubscriptions(response) = response {
833 process_service_result(&response.response_header)?;
834
835 builder_debug!(self, "delete_subscriptions success");
836 Ok(*response)
837 } else {
838 builder_error!(self, "delete_subscriptions failed {:?}", response);
839 Err(process_unexpected_response(response))
840 }
841 }
842}
843
844#[derive(Clone)]
845pub struct CreateMonitoredItems<'a> {
849 subscription_id: u32,
850 timestamps_to_return: TimestampsToReturn,
851 items_to_create: Vec<MonitoredItemCreateRequest>,
852 handle: &'a AtomicHandle,
853
854 header: RequestHeaderBuilder,
855}
856
857builder_base!(CreateMonitoredItems<'a>);
858
859impl<'a> CreateMonitoredItems<'a> {
860 pub fn new(subscription_id: u32, session: &'a Session) -> Self {
862 Self {
863 subscription_id,
864 timestamps_to_return: TimestampsToReturn::Neither,
865 items_to_create: Vec::new(),
866 handle: &session.monitored_item_handle,
867 header: RequestHeaderBuilder::new_from_session(session),
868 }
869 }
870
871 pub fn new_manual(
873 subscription_id: u32,
874 monitored_item_handle: &'a AtomicHandle,
875 session_id: u32,
876 timeout: Duration,
877 auth_token: NodeId,
878 request_handle: IntegerId,
879 ) -> Self {
880 Self {
881 subscription_id,
882 timestamps_to_return: TimestampsToReturn::Neither,
883 items_to_create: Vec::new(),
884 handle: monitored_item_handle,
885 header: RequestHeaderBuilder::new(session_id, timeout, auth_token, request_handle),
886 }
887 }
888
889 pub fn timestamps_to_return(mut self, timestamps_to_return: TimestampsToReturn) -> Self {
891 self.timestamps_to_return = timestamps_to_return;
892 self
893 }
894
895 pub fn items_to_create(mut self, items_to_create: Vec<MonitoredItemCreateRequest>) -> Self {
897 self.items_to_create = items_to_create;
898 self
899 }
900
901 pub fn item(mut self, item: MonitoredItemCreateRequest) -> Self {
903 self.items_to_create.push(item);
904 self
905 }
906
907 pub fn value(mut self, node_id: NodeId, sampling_interval: f64, queue_size: u32) -> Self {
910 self.items_to_create.push(MonitoredItemCreateRequest {
911 item_to_monitor: ReadValueId {
912 node_id,
913 attribute_id: AttributeId::Value as u32,
914 ..Default::default()
915 },
916 monitoring_mode: MonitoringMode::Reporting,
917 requested_parameters: MonitoringParameters {
918 client_handle: self.handle.next(),
919 sampling_interval,
920 queue_size,
921 discard_oldest: true,
922 ..Default::default()
923 },
924 });
925 self
926 }
927}
928
929#[derive(Debug, Clone)]
930pub struct CreatedMonitoredItem {
933 pub result: MonitoredItemCreateResult,
935 pub requested_parameters: MonitoringParameters,
937 pub monitoring_mode: MonitoringMode,
939 pub item_to_monitor: ReadValueId,
941}
942
943#[derive(Debug, Clone)]
944pub struct CreateMonitoredItemsResult {
947 pub response_header: ResponseHeader,
949 pub diagnostic_infos: Option<Vec<DiagnosticInfo>>,
951 pub results: Vec<CreatedMonitoredItem>,
953}
954
955impl UARequest for CreateMonitoredItems<'_> {
956 type Out = CreateMonitoredItemsResult;
957
958 async fn send<'a>(mut self, channel: &'a crate::AsyncSecureChannel) -> Result<Self::Out, Error>
959 where
960 Self: 'a,
961 {
962 let span = debug_span!(
963 "Sending CreateMonitoredItems request",
964 subscription_id = self.subscription_id,
965 num_items = self.items_to_create.len(),
966 timestamps_to_return = ?self.timestamps_to_return
967 );
968 let num_items = self.items_to_create.len();
969
970 let request = {
971 let _h = span.enter();
972 if self.subscription_id == 0 {
973 builder_error!(self, "create_monitored_items, subscription id 0 is invalid");
974 return Err(Error::new(
975 StatusCode::BadSubscriptionIdInvalid,
976 "create_monitored_items, subscription id 0 is invalid",
977 ));
978 }
979
980 if self.items_to_create.is_empty() {
981 builder_error!(
982 self,
983 "create_monitored_items, called with no items to create"
984 );
985 return Err(Error::new(
986 StatusCode::BadNothingToDo,
987 "create_monitored_items, called with no items to create",
988 ));
989 }
990 for item in &mut self.items_to_create {
991 if item.requested_parameters.client_handle == 0 {
992 item.requested_parameters.client_handle = self.handle.next();
993 }
994 }
995
996 CreateMonitoredItemsRequest {
997 request_header: self.header.header,
998 subscription_id: self.subscription_id,
999 timestamps_to_return: self.timestamps_to_return,
1000 items_to_create: Some(self.items_to_create.clone()),
1001 }
1002 };
1003
1004 let response = channel
1005 .send(request, self.header.timeout)
1006 .instrument(span.clone())
1007 .await?;
1008
1009 let _h = span.enter();
1010 if let ResponseMessage::CreateMonitoredItems(response) = response {
1011 process_service_result(&response.response_header)?;
1012 if let Some(ref results) = response.results {
1013 if results.len() != num_items {
1014 builder_error!(
1015 self,
1016 "create_monitored_items, unexpected number of results. Got {}, expected {}",
1017 results.len(),
1018 num_items
1019 );
1020 return Err(Error::new(StatusCode::BadUnexpectedError, format!("create_monitored_items, unexpected number of results. Got {}, expected {}",
1021 results.len(),
1022 num_items)
1023 ));
1024 }
1025 builder_debug!(self, "create_monitored_items, {} items created", num_items);
1026 } else {
1027 builder_error!(
1028 self,
1029 "create_monitored_items, success but no monitored items were created"
1030 );
1031 return Err(Error::new(
1032 StatusCode::BadUnexpectedError,
1033 "create_monitored_items, success but no monitored items were created",
1034 ));
1035 }
1036
1037 let created = response
1038 .results
1039 .unwrap_or_default()
1040 .into_iter()
1041 .zip(self.items_to_create)
1042 .map(|(result, item)| CreatedMonitoredItem {
1043 result,
1044 requested_parameters: item.requested_parameters,
1045 monitoring_mode: item.monitoring_mode,
1046 item_to_monitor: item.item_to_monitor,
1047 })
1048 .collect();
1049
1050 Ok(CreateMonitoredItemsResult {
1051 response_header: response.response_header,
1052 diagnostic_infos: response.diagnostic_infos,
1053 results: created,
1054 })
1055 } else {
1056 builder_error!(self, "create_monitored_items failed {:?}", response);
1057 Err(process_unexpected_response(response))
1058 }
1059 }
1060}
1061
1062#[derive(Clone)]
1063pub struct ModifyMonitoredItems {
1067 subscription_id: u32,
1068 timestamps_to_return: TimestampsToReturn,
1069 items_to_modify: Vec<MonitoredItemModifyRequest>,
1070
1071 header: RequestHeaderBuilder,
1072}
1073
1074builder_base!(ModifyMonitoredItems);
1075
1076impl ModifyMonitoredItems {
1077 pub fn new(subscription_id: u32, session: &Session) -> Self {
1079 Self {
1080 subscription_id,
1081 timestamps_to_return: TimestampsToReturn::Neither,
1082 items_to_modify: Vec::new(),
1083 header: RequestHeaderBuilder::new_from_session(session),
1084 }
1085 }
1086
1087 pub fn new_manual(
1089 subscription_id: u32,
1090 session_id: u32,
1091 timeout: Duration,
1092 auth_token: NodeId,
1093 request_handle: IntegerId,
1094 ) -> Self {
1095 Self {
1096 subscription_id,
1097 timestamps_to_return: TimestampsToReturn::Neither,
1098 items_to_modify: Vec::new(),
1099 header: RequestHeaderBuilder::new(session_id, timeout, auth_token, request_handle),
1100 }
1101 }
1102
1103 pub fn timestamps_to_return(mut self, timestamps_to_return: TimestampsToReturn) -> Self {
1105 self.timestamps_to_return = timestamps_to_return;
1106 self
1107 }
1108
1109 pub fn items_to_modify(mut self, items_to_modify: Vec<MonitoredItemModifyRequest>) -> Self {
1111 self.items_to_modify = items_to_modify;
1112 self
1113 }
1114
1115 pub fn item(mut self, item: MonitoredItemModifyRequest) -> Self {
1117 self.items_to_modify.push(item);
1118 self
1119 }
1120}
1121
1122impl UARequest for ModifyMonitoredItems {
1123 type Out = ModifyMonitoredItemsResponse;
1124
1125 async fn send<'a>(self, channel: &'a crate::AsyncSecureChannel) -> Result<Self::Out, Error>
1126 where
1127 Self: 'a,
1128 {
1129 let span = debug_span!(
1130 "Sending ModifyMonitoredItems request",
1131 subscription_id = self.subscription_id,
1132 num_items = self.items_to_modify.len(),
1133 timestamps_to_return = ?self.timestamps_to_return
1134 );
1135 let num_items = self.items_to_modify.len();
1136 let request = {
1137 let _h = span.enter();
1138 if self.subscription_id == 0 {
1139 builder_error!(self, "modify_monitored_items, subscription id 0 is invalid");
1140 return Err(Error::new(
1141 StatusCode::BadInvalidArgument,
1142 "modify_monitored_items, subscription id 0 is invalid",
1143 ));
1144 }
1145 if self.items_to_modify.is_empty() {
1146 builder_error!(
1147 self,
1148 "modify_monitored_items, called with no items to modify"
1149 );
1150 return Err(Error::new(
1151 StatusCode::BadNothingToDo,
1152 "modify_monitored_items, called with no items to modify",
1153 ));
1154 }
1155 ModifyMonitoredItemsRequest {
1156 request_header: self.header.header,
1157 subscription_id: self.subscription_id,
1158 timestamps_to_return: self.timestamps_to_return,
1159 items_to_modify: Some(self.items_to_modify),
1160 }
1161 };
1162 let response = channel
1163 .send(request, self.header.timeout)
1164 .instrument(span.clone())
1165 .await?;
1166 let _h = span.enter();
1167 if let ResponseMessage::ModifyMonitoredItems(response) = response {
1168 process_service_result(&response.response_header)?;
1169 let Some(results) = &response.results else {
1170 builder_error!(self, "modify_monitored_items, got empty response");
1171 return Err(Error::new(
1172 StatusCode::BadUnexpectedError,
1173 "modify_monitored_items, got empty response",
1174 ));
1175 };
1176 if results.len() != num_items {
1177 builder_error!(
1178 self,
1179 "modify_monitored_items, unexpected number of results. Expected {}, got {}",
1180 num_items,
1181 results.len()
1182 );
1183 return Err(Error::new(
1184 StatusCode::BadUnexpectedError,
1185 format!(
1186 "modify_monitored_items, unexpected number of results. Expected {}, got {}",
1187 num_items,
1188 results.len()
1189 ),
1190 ));
1191 }
1192
1193 builder_debug!(self, "modify_monitored_items, success");
1194 Ok(*response)
1195 } else {
1196 builder_error!(self, "modify_monitored_items failed {:?}", response);
1197 Err(process_unexpected_response(response))
1198 }
1199 }
1200}
1201
1202#[derive(Clone)]
1203pub struct SetMonitoringMode {
1208 subscription_id: u32,
1209 monitoring_mode: MonitoringMode,
1210 monitored_item_ids: Vec<u32>,
1211
1212 header: RequestHeaderBuilder,
1213}
1214
1215builder_base!(SetMonitoringMode);
1216
1217impl SetMonitoringMode {
1218 pub fn new(subscription_id: u32, monitoring_mode: MonitoringMode, session: &Session) -> Self {
1220 Self {
1221 subscription_id,
1222 monitored_item_ids: Vec::new(),
1223 monitoring_mode,
1224 header: RequestHeaderBuilder::new_from_session(session),
1225 }
1226 }
1227
1228 pub fn new_manual(
1230 subscription_id: u32,
1231 monitoring_mode: MonitoringMode,
1232 session_id: u32,
1233 timeout: Duration,
1234 auth_token: NodeId,
1235 request_handle: IntegerId,
1236 ) -> Self {
1237 Self {
1238 subscription_id,
1239 monitored_item_ids: Vec::new(),
1240 monitoring_mode,
1241 header: RequestHeaderBuilder::new(session_id, timeout, auth_token, request_handle),
1242 }
1243 }
1244
1245 pub fn monitored_item_ids(mut self, monitored_item_ids: Vec<u32>) -> Self {
1247 self.monitored_item_ids = monitored_item_ids;
1248 self
1249 }
1250
1251 pub fn item(mut self, item: u32) -> Self {
1253 self.monitored_item_ids.push(item);
1254 self
1255 }
1256}
1257
1258impl UARequest for SetMonitoringMode {
1259 type Out = SetMonitoringModeResponse;
1260
1261 async fn send<'a>(self, channel: &'a crate::AsyncSecureChannel) -> Result<Self::Out, Error>
1262 where
1263 Self: 'a,
1264 {
1265 let span = debug_span!(
1266 "Sending SetMonitoringMode request",
1267 subscription_id = self.subscription_id,
1268 monitoring_mode = ?self.monitoring_mode,
1269 num_items = self.monitored_item_ids.len()
1270 );
1271 let num_items = self.monitored_item_ids.len();
1272
1273 let request = {
1274 let _h = span.enter();
1275 if self.subscription_id == 0 {
1276 builder_error!(self, "set_monitoring_mode, subscription id 0 is invalid");
1277 return Err(Error::new(
1278 StatusCode::BadInvalidArgument,
1279 "set_monitoring_mode, subscription id 0 is invalid",
1280 ));
1281 }
1282 if self.monitored_item_ids.is_empty() {
1283 builder_error!(self, "set_monitoring_mode, called with no items to modify");
1284 return Err(Error::new(
1285 StatusCode::BadNothingToDo,
1286 "set_monitoring_mode, subscription id 0 is invalid",
1287 ));
1288 }
1289
1290 SetMonitoringModeRequest {
1291 request_header: self.header.header,
1292 subscription_id: self.subscription_id,
1293 monitoring_mode: self.monitoring_mode,
1294 monitored_item_ids: Some(self.monitored_item_ids),
1295 }
1296 };
1297 let response = channel.send(request, self.header.timeout).await?;
1298 let _h = span.enter();
1299 if let ResponseMessage::SetMonitoringMode(response) = response {
1300 let Some(results) = &response.results else {
1301 builder_error!(self, "set_monitoring_mode, got empty response");
1302 return Err(Error::new(
1303 StatusCode::BadUnexpectedError,
1304 "set_monitoring_mode, got empty response",
1305 ));
1306 };
1307 if results.len() != num_items {
1308 builder_error!(
1309 self,
1310 "set_monitoring_mode, unexpected number of results. Expected {}, got {}",
1311 num_items,
1312 results.len()
1313 );
1314 return Err(Error::new(
1315 StatusCode::BadUnexpectedError,
1316 format!(
1317 "set_monitoring_mode, unexpected number of results. Expected {}, got {}",
1318 num_items,
1319 results.len()
1320 ),
1321 ));
1322 }
1323
1324 Ok(*response)
1325 } else {
1326 builder_error!(self, "set_monitoring_mode failed {:?}", response);
1327 Err(process_unexpected_response(response))
1328 }
1329 }
1330}
1331
1332#[derive(Clone)]
1333pub struct SetTriggering {
1339 subscription_id: u32,
1340 triggering_item_id: u32,
1341 links_to_add: Vec<u32>,
1342 links_to_remove: Vec<u32>,
1343
1344 header: RequestHeaderBuilder,
1345}
1346
1347builder_base!(SetTriggering);
1348
1349impl SetTriggering {
1350 pub fn new(subscription_id: u32, triggering_item_id: u32, session: &Session) -> Self {
1352 Self {
1353 subscription_id,
1354 triggering_item_id,
1355 links_to_add: Vec::new(),
1356 links_to_remove: Vec::new(),
1357 header: RequestHeaderBuilder::new_from_session(session),
1358 }
1359 }
1360
1361 pub fn new_manual(
1363 subscription_id: u32,
1364 triggering_item_id: u32,
1365 session_id: u32,
1366 timeout: Duration,
1367 auth_token: NodeId,
1368 request_handle: IntegerId,
1369 ) -> Self {
1370 Self {
1371 subscription_id,
1372 triggering_item_id,
1373 links_to_add: Vec::new(),
1374 links_to_remove: Vec::new(),
1375 header: RequestHeaderBuilder::new(session_id, timeout, auth_token, request_handle),
1376 }
1377 }
1378
1379 pub fn links_to_add(mut self, links_to_add: Vec<u32>) -> Self {
1381 self.links_to_add = links_to_add;
1382 self
1383 }
1384
1385 pub fn add_link(mut self, item: u32) -> Self {
1387 self.links_to_add.push(item);
1388 self
1389 }
1390
1391 pub fn links_to_remove(mut self, links_to_remove: Vec<u32>) -> Self {
1393 self.links_to_remove = links_to_remove;
1394 self
1395 }
1396
1397 pub fn remove_link(mut self, item: u32) -> Self {
1399 self.links_to_remove.push(item);
1400 self
1401 }
1402}
1403
1404impl UARequest for SetTriggering {
1405 type Out = SetTriggeringResponse;
1406
1407 async fn send<'a>(self, channel: &'a crate::AsyncSecureChannel) -> Result<Self::Out, Error>
1408 where
1409 Self: 'a,
1410 {
1411 let span = debug_span!(
1412 "Sending SetTriggering request",
1413 subscription_id = self.subscription_id,
1414 triggering_item_id = self.triggering_item_id,
1415 num_links_to_add = self.links_to_add.len(),
1416 num_links_to_remove = self.links_to_remove.len()
1417 );
1418 let request = {
1419 let _h = span.enter();
1420 if self.subscription_id == 0 {
1421 builder_error!(self, "set_triggering, subscription id 0 is invalid");
1422 return Err(Error::new(
1423 StatusCode::BadInvalidArgument,
1424 "set_triggering, subscription id 0 is invalid",
1425 ));
1426 }
1427
1428 if self.links_to_add.is_empty() && self.links_to_remove.is_empty() {
1429 builder_error!(self, "set_triggering, called with nothing to add or remove");
1430 return Err(Error::new(
1431 StatusCode::BadNothingToDo,
1432 "set_triggering, subscription id 0 is invalid",
1433 ));
1434 }
1435 SetTriggeringRequest {
1436 request_header: self.header.header,
1437 subscription_id: self.subscription_id,
1438 triggering_item_id: self.triggering_item_id,
1439 links_to_add: if self.links_to_add.is_empty() {
1440 None
1441 } else {
1442 Some(self.links_to_add.clone())
1443 },
1444 links_to_remove: if self.links_to_remove.is_empty() {
1445 None
1446 } else {
1447 Some(self.links_to_remove.clone())
1448 },
1449 }
1450 };
1451
1452 let response = channel
1453 .send(request, self.header.timeout)
1454 .instrument(span.clone())
1455 .await?;
1456 let _h = span.enter();
1457 if let ResponseMessage::SetTriggering(response) = response {
1458 let to_add_res = response.add_results.as_deref().unwrap_or(&[]);
1459 let to_remove_res = response.remove_results.as_deref().unwrap_or(&[]);
1460 if to_add_res.len() != self.links_to_add.len() {
1461 builder_error!(
1462 self,
1463 "set_triggering, got unexpected number of add results: {}, expected {}",
1464 to_add_res.len(),
1465 self.links_to_add.len()
1466 );
1467 return Err(Error::new(
1468 StatusCode::BadUnexpectedError,
1469 format!(
1470 "set_triggering, got unexpected number of add results: {}, expected {}",
1471 to_add_res.len(),
1472 self.links_to_add.len()
1473 ),
1474 ));
1475 }
1476 if to_remove_res.len() != self.links_to_remove.len() {
1477 builder_error!(
1478 self,
1479 "set_triggering, got unexpected number of remove results: {}, expected {}",
1480 to_remove_res.len(),
1481 self.links_to_add.len()
1482 );
1483 return Err(Error::new(
1484 StatusCode::BadUnexpectedError,
1485 format!(
1486 "set_triggering, got unexpected number of remove results: {}, expected {}",
1487 to_remove_res.len(),
1488 self.links_to_add.len()
1489 ),
1490 ));
1491 }
1492
1493 Ok(*response)
1494 } else {
1495 builder_error!(self, "set_triggering failed {:?}", response);
1496 Err(process_unexpected_response(response))
1497 }
1498 }
1499}
1500
1501#[derive(Clone)]
1502pub struct DeleteMonitoredItems {
1506 subscription_id: u32,
1507 items_to_delete: Vec<u32>,
1508
1509 header: RequestHeaderBuilder,
1510}
1511
1512builder_base!(DeleteMonitoredItems);
1513
1514impl DeleteMonitoredItems {
1515 pub fn new(subscription_id: u32, session: &Session) -> Self {
1517 Self {
1518 subscription_id,
1519 items_to_delete: Vec::new(),
1520 header: RequestHeaderBuilder::new_from_session(session),
1521 }
1522 }
1523
1524 pub fn new_manual(
1526 subscription_id: u32,
1527 session_id: u32,
1528 timeout: Duration,
1529 auth_token: NodeId,
1530 request_handle: IntegerId,
1531 ) -> Self {
1532 Self {
1533 subscription_id,
1534 items_to_delete: Vec::new(),
1535 header: RequestHeaderBuilder::new(session_id, timeout, auth_token, request_handle),
1536 }
1537 }
1538
1539 pub fn items_to_delete(mut self, items_to_delete: Vec<u32>) -> Self {
1541 self.items_to_delete = items_to_delete;
1542 self
1543 }
1544
1545 pub fn item(mut self, item: u32) -> Self {
1547 self.items_to_delete.push(item);
1548 self
1549 }
1550}
1551
1552impl UARequest for DeleteMonitoredItems {
1553 type Out = DeleteMonitoredItemsResponse;
1554
1555 async fn send<'a>(self, channel: &'a crate::AsyncSecureChannel) -> Result<Self::Out, Error>
1556 where
1557 Self: 'a,
1558 {
1559 let span = debug_span!(
1560 "Sending DeleteMonitoredItems request",
1561 subscription_id = self.subscription_id,
1562 num_items_to_delete = self.items_to_delete.len()
1563 );
1564 let request = {
1565 let _h = span.enter();
1566 if self.subscription_id == 0 {
1567 builder_error!(self, "delete_monitored_items, subscription id 0 is invalid");
1568 return Err(Error::new(
1569 StatusCode::BadInvalidArgument,
1570 "delete_monitored_items, subscription id 0 is invalid",
1571 ));
1572 }
1573 if self.items_to_delete.is_empty() {
1574 builder_error!(
1575 self,
1576 "delete_monitored_items, called with no items to delete"
1577 );
1578 return Err(Error::new(
1579 StatusCode::BadNothingToDo,
1580 "delete_monitored_items, called with no items to delete",
1581 ));
1582 }
1583
1584 DeleteMonitoredItemsRequest {
1585 request_header: self.header.header,
1586 subscription_id: self.subscription_id,
1587 monitored_item_ids: Some(self.items_to_delete.clone()),
1588 }
1589 };
1590
1591 let response = channel
1592 .send(request, self.header.timeout)
1593 .instrument(span.clone())
1594 .await?;
1595 let _h = span.enter();
1596 if let ResponseMessage::DeleteMonitoredItems(response) = response {
1597 process_service_result(&response.response_header)?;
1598 builder_debug!(self, "delete_monitored_items, success");
1599 Ok(*response)
1600 } else {
1601 builder_error!(self, "delete_monitored_items failed {:?}", response);
1602 Err(process_unexpected_response(response))
1603 }
1604 }
1605}
1606
1607impl Session {
1608 pub fn subscription_state(&self) -> &Mutex<SubscriptionState> {
1610 &self.subscription_state
1611 }
1612
1613 pub fn trigger_publish_now(&self) {
1615 let _ = self.trigger_publish_tx.send(Instant::now());
1616 }
1617
1618 #[allow(clippy::too_many_arguments)]
1619 async fn create_subscription_inner(
1620 &self,
1621 publishing_interval: Duration,
1622 lifetime_count: u32,
1623 max_keep_alive_count: u32,
1624 max_notifications_per_publish: u32,
1625 publishing_enabled: bool,
1626 priority: u8,
1627 callback: Box<dyn OnSubscriptionNotificationCore>,
1628 ) -> Result<u32, Error> {
1629 let response = CreateSubscription::new(self)
1630 .publishing_interval(publishing_interval)
1631 .max_lifetime_count(lifetime_count)
1632 .max_keep_alive_count(max_keep_alive_count)
1633 .max_notifications_per_publish(max_notifications_per_publish)
1634 .publishing_enabled(publishing_enabled)
1635 .priority(priority)
1636 .send(&self.channel)
1637 .await?;
1638
1639 let revised_publishing_interval = if response.revised_publishing_interval.is_finite() {
1640 response.revised_publishing_interval.max(0.0).floor() as u64
1641 } else {
1642 0
1643 };
1644 let subscription = Subscription::new(
1645 response.subscription_id,
1646 Duration::from_millis(revised_publishing_interval),
1647 response.revised_lifetime_count,
1648 response.revised_max_keep_alive_count,
1649 max_notifications_per_publish,
1650 priority,
1651 publishing_enabled,
1652 callback,
1653 );
1654 {
1655 let mut subscription_state = trace_lock!(self.subscription_state);
1656 subscription_state.add_subscription(subscription);
1657 }
1658
1659 self.trigger_publish_now();
1660
1661 Ok(response.subscription_id)
1662 }
1663
1664 #[allow(clippy::too_many_arguments)]
1706 pub async fn create_subscription(
1707 &self,
1708 publishing_interval: Duration,
1709 lifetime_count: u32,
1710 max_keep_alive_count: u32,
1711 max_notifications_per_publish: u32,
1712 priority: u8,
1713 publishing_enabled: bool,
1714 callback: impl OnSubscriptionNotificationCore + 'static,
1715 ) -> Result<u32, Error> {
1716 self.create_subscription_inner(
1717 publishing_interval,
1718 lifetime_count,
1719 max_keep_alive_count,
1720 max_notifications_per_publish,
1721 publishing_enabled,
1722 priority,
1723 Box::new(callback),
1724 )
1725 .await
1726 }
1727
1728 fn subscription_exists(&self, subscription_id: u32) -> bool {
1729 let subscription_state = trace_lock!(self.subscription_state);
1730 subscription_state.subscription_exists(subscription_id)
1731 }
1732
1733 pub async fn modify_subscription(
1772 &self,
1773 subscription_id: u32,
1774 publishing_interval: Duration,
1775 lifetime_count: u32,
1776 max_keep_alive_count: u32,
1777 max_notifications_per_publish: u32,
1778 priority: u8,
1779 ) -> Result<(), Error> {
1780 if !self.subscription_exists(subscription_id) {
1781 session_error!(self, "modify_subscription, subscription id does not exist");
1782 return Err(Error::new(
1783 StatusCode::BadInvalidArgument,
1784 "modify_subscription, subscription id does not exist",
1785 ));
1786 }
1787
1788 let response = ModifySubscription::new(subscription_id, self)
1789 .publishing_interval(publishing_interval)
1790 .max_lifetime_count(lifetime_count)
1791 .max_keep_alive_count(max_keep_alive_count)
1792 .max_notifications_per_publish(max_notifications_per_publish)
1793 .priority(priority)
1794 .send(&self.channel)
1795 .await?;
1796
1797 {
1798 let mut subscription_state = trace_lock!(self.subscription_state);
1799 subscription_state.modify_subscription(
1800 subscription_id,
1801 Duration::from_millis(response.revised_publishing_interval.max(0.0).floor() as u64),
1802 response.revised_lifetime_count,
1803 response.revised_max_keep_alive_count,
1804 max_notifications_per_publish,
1805 priority,
1806 );
1807 }
1808
1809 Ok(())
1810 }
1811
1812 pub async fn set_publishing_mode(
1828 &self,
1829 subscription_ids: &[u32],
1830 publishing_enabled: bool,
1831 ) -> Result<Vec<StatusCode>, Error> {
1832 let results = SetPublishingMode::new(publishing_enabled, self)
1833 .subscription_ids(subscription_ids.to_vec())
1834 .send(&self.channel)
1835 .await?
1836 .results
1837 .unwrap_or_default();
1838
1839 {
1840 let mut subscription_state = trace_lock!(self.subscription_state);
1842 let ids = subscription_ids
1843 .iter()
1844 .zip(results.iter())
1845 .filter(|(_, s)| s.is_good())
1846 .map(|(v, _)| *v)
1847 .collect::<Vec<_>>();
1848 subscription_state.set_publishing_mode(&ids, publishing_enabled);
1849 }
1850
1851 if publishing_enabled {
1852 self.trigger_publish_now();
1853 }
1854 Ok(results)
1855 }
1856
1857 pub async fn transfer_subscriptions(
1880 &self,
1881 subscription_ids: &[u32],
1882 send_initial_values: bool,
1883 ) -> Result<Vec<TransferResult>, Error> {
1884 let r = TransferSubscriptions::new(self)
1885 .send_initial_values(send_initial_values)
1886 .subscription_ids(subscription_ids.to_vec())
1887 .send(&self.channel)
1888 .await?
1889 .results
1890 .unwrap_or_default();
1891
1892 self.trigger_publish_now();
1893
1894 Ok(r)
1895 }
1896
1897 pub async fn delete_subscription(&self, subscription_id: u32) -> Result<StatusCode, Error> {
1911 if subscription_id == 0 {
1912 session_error!(self, "delete_subscription, subscription id 0 is invalid");
1913 Err(Error::new(
1914 StatusCode::BadInvalidArgument,
1915 "delete_subscription, subscription id 0 is invalid",
1916 ))
1917 } else if !self.subscription_exists(subscription_id) {
1918 session_error!(
1919 self,
1920 "delete_subscription, subscription id {} does not exist",
1921 subscription_id
1922 );
1923 Err(Error::new(
1924 StatusCode::BadInvalidArgument,
1925 format!(
1926 "delete_subscription, subscription id {} does not exist",
1927 subscription_id
1928 ),
1929 ))
1930 } else {
1931 let result = self.delete_subscriptions(&[subscription_id]).await?;
1932 Ok(result[0])
1933 }
1934 }
1935
1936 pub async fn delete_subscriptions(
1952 &self,
1953 subscription_ids: &[u32],
1954 ) -> Result<Vec<StatusCode>, Error> {
1955 let result = DeleteSubscriptions::new(self)
1956 .subscription_ids(subscription_ids.to_vec())
1957 .send(&self.channel)
1958 .await?
1959 .results
1960 .unwrap_or_default();
1961 {
1962 let mut subscription_state = trace_lock!(self.subscription_state);
1964 for id in subscription_ids {
1965 subscription_state.delete_subscription(*id);
1966 }
1967 }
1968
1969 Ok(result)
1970 }
1971
1972 pub async fn create_monitored_items(
1989 &self,
1990 subscription_id: u32,
1991 timestamps_to_return: TimestampsToReturn,
1992 mut items_to_create: Vec<MonitoredItemCreateRequest>,
1993 ) -> Result<Vec<CreatedMonitoredItem>, Error> {
1994 {
1995 let state = trace_lock!(self.subscription_state);
1996 if !state.subscription_exists(subscription_id) {
1997 session_error!(
1998 self,
1999 "create_monitored_items, subscription id {} does not exist",
2000 subscription_id
2001 );
2002 return Err(Error::new(
2003 StatusCode::BadSubscriptionIdInvalid,
2004 format!(
2005 "create_monitored_items, subscription id {} does not exist",
2006 subscription_id
2007 ),
2008 ));
2009 }
2010 }
2011
2012 for item in &mut items_to_create {
2013 if item.requested_parameters.client_handle == 0 {
2014 item.requested_parameters.client_handle = self.monitored_item_handle.next();
2015 }
2016 }
2017
2018 let pre_insert = PreInsertMonitoredItems::new(
2022 &self.subscription_state,
2023 subscription_id,
2024 &items_to_create,
2025 );
2026
2027 let result = CreateMonitoredItems::new(subscription_id, self)
2028 .items_to_create(items_to_create)
2029 .timestamps_to_return(timestamps_to_return)
2030 .send(&self.channel)
2031 .await?;
2032
2033 pre_insert.finish(&result.results);
2035
2036 Ok(result.results)
2037 }
2038
2039 pub async fn modify_monitored_items(
2056 &self,
2057 subscription_id: u32,
2058 timestamps_to_return: TimestampsToReturn,
2059 items_to_modify: &[MonitoredItemModifyRequest],
2060 ) -> Result<Vec<MonitoredItemModifyResult>, Error> {
2061 {
2062 let state = trace_lock!(self.subscription_state);
2063 if !state.subscription_exists(subscription_id) {
2064 session_error!(
2065 self,
2066 "modify_monitored_items, subscription id {} does not exist",
2067 subscription_id
2068 );
2069 return Err(Error::new(
2070 StatusCode::BadSubscriptionIdInvalid,
2071 format!(
2072 "modify_monitored_items, subscription id {} does not exist",
2073 subscription_id
2074 ),
2075 ));
2076 }
2077 }
2078 let id_and_filter: Vec<(u32, ExtensionObject)> = items_to_modify
2079 .iter()
2080 .map(|i| (i.monitored_item_id, i.requested_parameters.filter.clone()))
2081 .collect();
2082 let results = ModifyMonitoredItems::new(subscription_id, self)
2083 .timestamps_to_return(timestamps_to_return)
2084 .items_to_modify(items_to_modify.to_vec())
2085 .send(&self.channel)
2086 .await?
2087 .results
2088 .unwrap_or_default();
2089
2090 let items_to_modify = id_and_filter
2091 .iter()
2092 .zip(results.iter())
2093 .map(|((id, requested_filter), r)| {
2094 let filter = if r.filter_result.is_null() {
2095 requested_filter.clone()
2096 } else {
2097 r.filter_result.clone()
2098 };
2099 ModifyMonitoredItem {
2100 id: *id,
2101 queue_size: r.revised_queue_size,
2102 sampling_interval: r.revised_sampling_interval,
2103 filter,
2104 }
2105 })
2106 .collect::<Vec<ModifyMonitoredItem>>();
2107 {
2108 let mut subscription_state = trace_lock!(self.subscription_state);
2109 subscription_state.modify_monitored_items(subscription_id, &items_to_modify);
2110 }
2111
2112 Ok(results)
2113 }
2114
2115 pub async fn set_monitoring_mode(
2132 &self,
2133 subscription_id: u32,
2134 monitoring_mode: MonitoringMode,
2135 monitored_item_ids: &[u32],
2136 ) -> Result<Vec<StatusCode>, Error> {
2137 {
2138 let state = trace_lock!(self.subscription_state);
2139 if !state.subscription_exists(subscription_id) {
2140 session_error!(
2141 self,
2142 "set_monitoring_mode, subscription id {} does not exist",
2143 subscription_id
2144 );
2145 return Err(Error::new(
2146 StatusCode::BadSubscriptionIdInvalid,
2147 format!(
2148 "set_monitoring_mode, subscription id {} does not exist",
2149 subscription_id
2150 ),
2151 ));
2152 }
2153 }
2154 let results = SetMonitoringMode::new(subscription_id, monitoring_mode, self)
2155 .monitored_item_ids(monitored_item_ids.to_vec())
2156 .send(&self.channel)
2157 .await?
2158 .results
2159 .unwrap_or_default();
2160
2161 let ok_ids: Vec<_> = monitored_item_ids
2162 .iter()
2163 .zip(results.iter())
2164 .filter(|(_, s)| s.is_good())
2165 .map(|(v, _)| *v)
2166 .collect();
2167 {
2168 let mut subscription_state = trace_lock!(self.subscription_state);
2169 subscription_state.set_monitoring_mode(subscription_id, &ok_ids, monitoring_mode);
2170 }
2171
2172 Ok(results)
2173 }
2174
2175 pub async fn set_triggering(
2194 &self,
2195 subscription_id: u32,
2196 triggering_item_id: u32,
2197 links_to_add: &[u32],
2198 links_to_remove: &[u32],
2199 ) -> Result<(Option<Vec<StatusCode>>, Option<Vec<StatusCode>>), Error> {
2200 {
2201 let state = trace_lock!(self.subscription_state);
2202 if !state.subscription_exists(subscription_id) {
2203 session_error!(
2204 self,
2205 "set_triggering, subscription id {} does not exist",
2206 subscription_id
2207 );
2208 return Err(Error::new(
2209 StatusCode::BadSubscriptionIdInvalid,
2210 format!(
2211 "set_triggering, subscription id {} does not exist",
2212 subscription_id
2213 ),
2214 ));
2215 }
2216 }
2217 let response = SetTriggering::new(subscription_id, triggering_item_id, self)
2218 .links_to_add(links_to_add.to_vec())
2219 .links_to_remove(links_to_remove.to_vec())
2220 .send(&self.channel)
2221 .await?;
2222
2223 let to_add_res = response.add_results.as_deref().unwrap_or(&[]);
2224 let to_remove_res = response.remove_results.as_deref().unwrap_or(&[]);
2225
2226 let ok_adds = to_add_res
2227 .iter()
2228 .zip(links_to_add)
2229 .filter(|(s, _)| s.is_good())
2230 .map(|(_, v)| v)
2231 .copied()
2232 .collect::<Vec<_>>();
2233 let ok_removes = to_remove_res
2234 .iter()
2235 .zip(links_to_remove)
2236 .filter(|(s, _)| s.is_good())
2237 .map(|(_, v)| v)
2238 .copied()
2239 .collect::<Vec<_>>();
2240
2241 let mut subscription_state = trace_lock!(self.subscription_state);
2243 subscription_state.set_triggering(
2244 subscription_id,
2245 triggering_item_id,
2246 &ok_adds,
2247 &ok_removes,
2248 );
2249 Ok((response.add_results, response.remove_results))
2250 }
2251
2252 pub async fn delete_monitored_items(
2268 &self,
2269 subscription_id: u32,
2270 items_to_delete: &[u32],
2271 ) -> Result<Vec<StatusCode>, Error> {
2272 {
2273 let state = trace_lock!(self.subscription_state);
2274 if !state.subscription_exists(subscription_id) {
2275 session_error!(
2276 self,
2277 "delete_monitored_items, subscription id {} does not exist",
2278 subscription_id
2279 );
2280 return Err(Error::new(
2281 StatusCode::BadSubscriptionIdInvalid,
2282 format!(
2283 "delete_monitored_items, subscription id {} does not exist",
2284 subscription_id
2285 ),
2286 ));
2287 }
2288 }
2289 let response = DeleteMonitoredItems::new(subscription_id, self)
2290 .items_to_delete(items_to_delete.to_vec())
2291 .send(&self.channel)
2292 .await?
2293 .results
2294 .unwrap_or_default();
2295 let mut subscription_state = trace_lock!(self.subscription_state);
2296 subscription_state.delete_monitored_items(subscription_id, items_to_delete);
2297 Ok(response)
2298 }
2299
2300 pub(crate) fn next_publish_time(&self, set_last_publish: bool) -> Option<Instant> {
2301 let mut subscription_state = trace_lock!(self.subscription_state);
2302 if set_last_publish {
2303 subscription_state.set_last_publish();
2304 }
2305 subscription_state.next_publish_time()
2306 }
2307
2308 pub(crate) async fn publish(&self) -> Result<bool, Error> {
2311 let acks = {
2312 let mut subscription_state = trace_lock!(self.subscription_state);
2313 let acks = subscription_state.take_acknowledgements();
2314 if !acks.is_empty() {
2315 Some(acks)
2316 } else {
2317 None
2318 }
2319 };
2320
2321 match Publish::new(self)
2322 .acks(acks.clone().unwrap_or_default())
2323 .send(&self.channel)
2324 .await
2325 {
2326 Ok(r) => {
2327 if let (Some(sent), Some(results)) = (acks.as_ref(), r.results.as_ref()) {
2328 for (ack, status) in sent.iter().zip(results.iter()) {
2329 if !status.is_good() && *status != StatusCode::BadSequenceNumberUnknown {
2330 tracing::warn!(
2331 "Server rejected ack for subscription {} seq {}: {status}",
2332 ack.subscription_id,
2333 ack.sequence_number,
2334 );
2335 }
2336 }
2337 }
2338 let mut subscription_state = trace_lock!(self.subscription_state);
2339 subscription_state.handle_notification(r.subscription_id, r.notification_message);
2340 Ok(r.more_notifications)
2341 }
2342 Err(e) => {
2343 if let Some(acks) = acks {
2344 let mut subscription_state = trace_lock!(self.subscription_state);
2345 subscription_state.re_queue_acknowledgements(acks);
2346 }
2347 Err(e)
2348 }
2349 }
2350 }
2351
2352 pub async fn republish(
2367 &self,
2368 subscription_id: u32,
2369 sequence_number: u32,
2370 ) -> Result<NotificationMessage, Error> {
2371 let res = Republish::new(subscription_id, sequence_number, self)
2372 .send(&self.channel)
2373 .await?;
2374
2375 {
2376 let mut lck = trace_lock!(self.subscription_state);
2377 lck.add_acknowledgement(subscription_id, sequence_number);
2378 }
2379
2380 Ok(res.notification_message)
2381 }
2382
2383 pub(crate) async fn transfer_subscriptions_from_old_session(&self) {
2386 let subscription_ids = {
2387 let mut subscription_state = trace_lock!(self.subscription_state);
2388 let _stale_acks = subscription_state.take_acknowledgements();
2389 subscription_state.subscription_ids()
2390 };
2391
2392 let Some(subscription_ids) = subscription_ids else {
2393 return;
2394 };
2395
2396 let mut subscription_ids_to_recreate =
2400 subscription_ids.iter().copied().collect::<HashSet<u32>>();
2401 if let Ok(transfer_results) = self.transfer_subscriptions(&subscription_ids, true).await {
2402 session_debug!(self, "transfer_results = {:?}", transfer_results);
2403 transfer_results.iter().enumerate().for_each(|(i, r)| {
2404 if r.status_code.is_good() {
2405 subscription_ids_to_recreate.remove(&subscription_ids[i]);
2407 }
2408 });
2409 }
2410
2411 if !subscription_ids_to_recreate.is_empty() {
2413 session_warn!(self, "Some or all of the existing subscriptions could not be transferred and must be created manually");
2414 }
2415
2416 for subscription_id in subscription_ids_to_recreate {
2417 session_debug!(self, "Recreating subscription {}", subscription_id);
2418
2419 let deleted_subscription = {
2420 let mut subscription_state = trace_lock!(self.subscription_state);
2421 subscription_state.delete_subscription(subscription_id)
2422 };
2423
2424 let Some(subscription) = deleted_subscription else {
2425 session_warn!(
2426 self,
2427 "Subscription removed from session while transfer in progress"
2428 );
2429 continue;
2430 };
2431
2432 let Ok(subscription_id) = self
2433 .create_subscription_inner(
2434 subscription.publishing_interval,
2435 subscription.lifetime_count,
2436 subscription.max_keep_alive_count,
2437 subscription.max_notifications_per_publish,
2438 subscription.publishing_enabled,
2439 subscription.priority,
2440 subscription.callback,
2441 )
2442 .await
2443 else {
2444 session_warn!(
2445 self,
2446 "Could not create a subscription from the existing subscription {}",
2447 subscription_id
2448 );
2449 continue;
2450 };
2451
2452 let items_to_create = subscription
2453 .monitored_items
2454 .values()
2455 .map(|item| MonitoredItemCreateRequest {
2456 item_to_monitor: item.item_to_monitor().clone(),
2457 monitoring_mode: item.monitoring_mode,
2458 requested_parameters: MonitoringParameters {
2459 client_handle: item.client_handle(),
2460 sampling_interval: item.sampling_interval(),
2461 filter: item.filter.clone(),
2462 queue_size: item.queue_size() as u32,
2463 discard_oldest: item.discard_oldest(),
2464 },
2465 })
2466 .collect::<Vec<MonitoredItemCreateRequest>>();
2467
2468 let mut iter = items_to_create.into_iter();
2469
2470 loop {
2471 let chunk = (&mut iter)
2472 .take(self.recreate_monitored_items_chunk)
2473 .collect::<Vec<_>>();
2474
2475 if chunk.is_empty() {
2476 break;
2477 }
2478
2479 let _ = self
2480 .create_monitored_items(subscription_id, TimestampsToReturn::Both, chunk)
2481 .await;
2482 }
2483
2484 for item in subscription.monitored_items.values() {
2485 let triggered_items = item.triggered_items();
2486 if !triggered_items.is_empty() {
2487 let links_to_add = triggered_items.iter().copied().collect::<Vec<u32>>();
2488 if let Err(e) = self
2489 .set_triggering(subscription_id, item.id(), links_to_add.as_slice(), &[])
2490 .await
2491 {
2492 session_warn!(
2493 self,
2494 "Failed to re-apply triggering links for monitored item {} on recreated subscription {}: {e}",
2495 item.id(),
2496 subscription_id,
2497 );
2498 }
2499 }
2500 }
2501 }
2502 }
2503}