1use crate::std;
2use std::fmt;
3
4use crate::{
5 banknote::*, cash::CurrencyDenomination, impl_from_for_omnibus_reply, impl_message_ops,
6 impl_omnibus_reply_ops, len::OMNIBUS_REPLY, status::*, AdvancedBookmarkModeReply,
7 ClearAuditDataRequestAck, ClearAuditDataRequestResults, ExtendedNoteInhibitsReplyAlt,
8 ExtendedNoteReply, MessageOps, MessageType, NoteRetrievedEvent, NoteRetrievedReply,
9 QueryApplicationIdReply, QueryApplicationPartNumberReply, QueryBootPartNumberReply,
10 QueryDeviceCapabilitiesReply, QueryValueTableReply, QueryVariantIdReply, QueryVariantNameReply,
11 QueryVariantPartNumberReply, SetEscrowTimeoutReply, StandardDenomination,
12};
13
14pub mod index {
15 use crate::index::DATA;
16
17 pub const DEVICE_STATE: usize = DATA;
18 pub const DEVICE_STATUS: usize = DATA + 1;
19 pub const EXCEPTION_STATUS: usize = DATA + 2;
20 pub const MISC_DEVICE_STATE: usize = DATA + 3;
21 pub const MODEL_NUMBER: usize = DATA + 4;
22 pub const CODE_REVISION: usize = DATA + 5;
23}
24
25#[derive(Clone, Copy, Debug, Default, PartialEq)]
56#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
57pub struct OmnibusReply {
58 buf: [u8; OMNIBUS_REPLY],
59}
60
61impl OmnibusReply {
62 pub fn new() -> Self {
64 let mut message = Self {
65 buf: [0u8; OMNIBUS_REPLY],
66 };
67
68 message.init();
69 message.set_message_type(MessageType::OmnibusReply);
70
71 message
72 }
73}
74
75impl_from_for_omnibus_reply!(AdvancedBookmarkModeReply);
76impl_from_for_omnibus_reply!(ClearAuditDataRequestAck);
77impl_from_for_omnibus_reply!(ClearAuditDataRequestResults);
78impl_from_for_omnibus_reply!(ExtendedNoteReply);
79impl_from_for_omnibus_reply!(ExtendedNoteInhibitsReplyAlt);
80impl_from_for_omnibus_reply!(NoteRetrievedReply);
81impl_from_for_omnibus_reply!(NoteRetrievedEvent);
82impl_from_for_omnibus_reply!(QueryValueTableReply);
83impl_from_for_omnibus_reply!(SetEscrowTimeoutReply);
84impl_from_for_omnibus_reply!(QueryBootPartNumberReply);
85impl_from_for_omnibus_reply!(QueryApplicationPartNumberReply);
86impl_from_for_omnibus_reply!(QueryVariantNameReply);
87impl_from_for_omnibus_reply!(QueryVariantPartNumberReply);
88impl_from_for_omnibus_reply!(QueryDeviceCapabilitiesReply);
89impl_from_for_omnibus_reply!(QueryApplicationIdReply);
90impl_from_for_omnibus_reply!(QueryVariantIdReply);
91
92impl fmt::Display for OmnibusReply {
93 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
94 write!(
95 f,
96 "AckNak: {}, DeviceType: {}, MessageType: {}, DeviceState: {}, DeviceStatus: {}, ExceptionStatus: {}, MiscDeviceState: {}, ModelNumber: {}, CodeRevision: {}",
97 self.acknak(),
98 self.device_type(),
99 self.message_type(),
100 self.device_state(),
101 self.device_status(),
102 self.exception_status(),
103 self.misc_device_state(),
104 self.model_number(),
105 self.code_revision(),
106 )
107 }
108}
109
110pub trait OmnibusReplyOps: MessageOps {
111 fn device_state(&self) -> DeviceState {
113 self.buf()[index::DEVICE_STATE].into()
114 }
115
116 fn set_device_state(&mut self, device_state: DeviceState) {
118 self.buf_mut()[index::DEVICE_STATE] = device_state.into();
119 }
120
121 fn idling(&self) -> Idling {
123 self.device_state().idling().into()
124 }
125
126 fn set_idling(&mut self, idling: Idling) {
128 let mut state = self.device_state();
129 state.set_idling(idling.into());
130 self.set_device_state(state);
131 }
132
133 fn accepting(&self) -> Accepting {
135 self.device_state().accepting().into()
136 }
137
138 fn set_accepting(&mut self, accepting: Accepting) {
140 let mut state = self.device_state();
141 state.set_accepting(accepting.into());
142 self.set_device_state(state);
143 }
144
145 fn escrowed_state(&self) -> EscrowedState {
147 self.device_state().escrowed_state().into()
148 }
149
150 fn set_escrowed_state(&mut self, escrowed_state: EscrowedState) {
152 let mut state = self.device_state();
153 state.set_escrowed_state(escrowed_state.into());
154 self.set_device_state(state);
155 }
156
157 fn stacking(&self) -> Stacking {
159 self.device_state().stacking().into()
160 }
161
162 fn set_stacking(&mut self, stacking: Stacking) {
164 let mut state = self.device_state();
165 state.set_stacking(stacking.into());
166 self.set_device_state(state);
167 }
168
169 fn stacked_event(&self) -> StackedEvent {
171 self.device_state().stacked_event().into()
172 }
173
174 fn set_stacked_event(&mut self, stacked_event: StackedEvent) {
176 let mut state = self.device_state();
177 state.set_stacked_event(stacked_event.into());
178 self.set_device_state(state);
179 }
180
181 fn returning(&self) -> Returning {
183 self.device_state().returning().into()
184 }
185
186 fn set_returning(&mut self, returning: Returning) {
188 let mut state = self.device_state();
189 state.set_returning(returning.into());
190 self.set_device_state(state);
191 }
192
193 fn returned_event(&self) -> ReturnedEvent {
195 self.device_state().returned_event().into()
196 }
197
198 fn set_returned_event(&mut self, returned_event: ReturnedEvent) {
200 let mut state = self.device_state();
201 state.set_returned_event(returned_event.into());
202 self.set_device_state(state);
203 }
204
205 fn device_status(&self) -> DeviceStatus {
207 self.buf()[index::DEVICE_STATUS].into()
208 }
209
210 fn set_device_status(&mut self, device_status: DeviceStatus) {
211 self.buf_mut()[index::DEVICE_STATUS] = device_status.into();
212 }
213
214 fn cheated(&self) -> Cheated {
216 self.device_status().cheated().into()
217 }
218
219 fn set_cheated(&mut self, cheated: Cheated) {
221 let mut status = self.device_status();
222 status.set_cheated(cheated.into());
223 self.set_device_status(status);
224 }
225
226 fn rejected(&self) -> Rejected {
228 self.device_status().rejected().into()
229 }
230
231 fn set_rejected(&mut self, rejected: Rejected) {
233 let mut status = self.device_status();
234 status.set_rejected(rejected.into());
235 self.set_device_status(status);
236 }
237
238 fn jammed(&self) -> Jammed {
240 self.device_status().jammed().into()
241 }
242
243 fn set_jammed(&mut self, jammed: Jammed) {
245 let mut status = self.device_status();
246 status.set_jammed(jammed.into());
247 self.set_device_status(status);
248 }
249
250 fn stacker_full(&self) -> StackerFull {
252 self.device_status().stacker_full().into()
253 }
254
255 fn set_stacker_full(&mut self, stacker_full: StackerFull) {
257 let mut status = self.device_status();
258 status.set_stacker_full(stacker_full.into());
259 self.set_device_status(status);
260 }
261
262 fn cassette_attached(&self) -> CassetteAttached {
264 self.device_status().cassette_attached().into()
265 }
266
267 fn set_cassette_attached(&mut self, cassette_attached: CassetteAttached) {
269 let mut status = self.device_status();
270 status.set_cassette_attached(cassette_attached.into());
271 self.set_device_status(status);
272 }
273
274 fn cash_box_status(&self) -> CashBoxStatus {
276 let status = self.device_status();
277
278 if status.stacker_full() {
279 CashBoxStatus::Full
280 } else if status.cassette_attached() {
281 CashBoxStatus::Attached
282 } else {
283 CashBoxStatus::Removed
284 }
285 }
286
287 fn paused(&self) -> Paused {
289 self.device_status().paused().into()
290 }
291
292 fn set_paused(&mut self, paused: Paused) {
294 let mut status = self.device_status();
295 status.set_paused(paused.into());
296 self.set_device_status(status);
297 }
298
299 fn calibration(&self) -> Calibration {
301 self.device_status().calibration().into()
302 }
303
304 fn set_calibration(&mut self, calibration: Calibration) {
306 let mut status = self.device_status();
307 status.set_calibration(calibration.into());
308 self.set_device_status(status);
309 }
310
311 fn exception_status(&self) -> ExceptionStatus {
313 self.buf()[index::EXCEPTION_STATUS].into()
314 }
315
316 fn set_exception_status(&mut self, exception_status: ExceptionStatus) {
317 self.buf_mut()[index::EXCEPTION_STATUS] = exception_status.into();
318 }
319
320 fn power_up(&self) -> PowerUpStatus {
322 self.exception_status().power_up().into()
323 }
324
325 fn set_power_up(&mut self, power_up: PowerUpStatus) {
327 let mut ex = self.exception_status();
328 ex.set_power_up(power_up.into());
329 self.set_exception_status(ex);
330 }
331
332 fn invalid_command(&self) -> InvalidCommand {
334 self.exception_status().invalid_command().into()
335 }
336
337 fn set_invalid_command(&mut self, invalid_command: InvalidCommand) {
339 let mut ex = self.exception_status();
340 ex.set_invalid_command(invalid_command.into());
341 self.set_exception_status(ex);
342 }
343
344 fn failure(&self) -> Failure {
346 self.exception_status().failure().into()
347 }
348
349 fn set_failure(&mut self, failure: Failure) {
351 let mut ex = self.exception_status();
352 ex.set_failure(failure.into());
353 self.set_exception_status(ex);
354 }
355
356 fn note_value(&self) -> StandardDenomination {
358 self.exception_status().note_value().into()
359 }
360
361 fn set_note_value(&mut self, note_value: StandardDenomination) {
363 let mut ex = self.exception_status();
364 ex.set_note_value(note_value.into());
365 self.set_exception_status(ex);
366 }
367
368 fn transport_open(&self) -> TransportOpen {
370 self.exception_status().transport_open().into()
371 }
372
373 fn set_transport_open(&mut self, transport_open: TransportOpen) {
375 let mut ex = self.exception_status();
376 ex.set_transport_open(transport_open.into());
377 self.set_exception_status(ex);
378 }
379
380 fn misc_device_state(&self) -> MiscDeviceState {
382 self.buf()[index::MISC_DEVICE_STATE].into()
383 }
384
385 fn set_misc_device_state(&mut self, misc_device_state: MiscDeviceState) {
386 self.buf_mut()[index::MISC_DEVICE_STATE] = misc_device_state.into();
387 }
388
389 fn stalled(&self) -> Stalled {
391 self.misc_device_state().stalled().into()
392 }
393
394 fn set_stalled(&mut self, stalled: Stalled) {
396 let mut misc = self.misc_device_state();
397 misc.set_stalled(stalled.into());
398 self.set_misc_device_state(misc);
399 }
400
401 fn flash_download(&self) -> FlashDownload {
403 self.misc_device_state().flash_download().into()
404 }
405
406 fn set_flash_download(&mut self, flash_download: FlashDownload) {
408 let mut misc = self.misc_device_state();
409 misc.set_flash_download(flash_download.into());
410 self.set_misc_device_state(misc);
411 }
412
413 fn pre_stack(&self) -> PreStack {
415 self.misc_device_state().pre_stack().into()
416 }
417
418 fn set_pre_stack(&mut self, pre_stack: PreStack) {
420 let mut misc = self.misc_device_state();
421 misc.set_pre_stack(pre_stack.into());
422 self.set_misc_device_state(misc);
423 }
424
425 fn raw_barcode(&self) -> RawBarcode {
427 self.misc_device_state().raw_barcode().into()
428 }
429
430 fn set_raw_barcode(&mut self, raw_barcode: RawBarcode) {
432 let mut misc = self.misc_device_state();
433 misc.set_raw_barcode(raw_barcode.into());
434 self.set_misc_device_state(misc);
435 }
436
437 fn device_capabilities(&self) -> DeviceCapabilities {
439 self.misc_device_state().device_capabilities().into()
440 }
441
442 fn set_device_capabilities(&mut self, device_capabilities: DeviceCapabilities) {
444 let mut misc = self.misc_device_state();
445 misc.set_device_capabilities(device_capabilities.into());
446 self.set_misc_device_state(misc);
447 }
448
449 fn disabled(&self) -> Disabled {
451 self.misc_device_state().disabled().into()
452 }
453
454 fn set_disabled(&mut self, disabled: Disabled) {
456 let mut misc = self.misc_device_state();
457 misc.set_disabled(disabled.into());
458 self.set_misc_device_state(misc);
459 }
460
461 fn model_number(&self) -> ModelNumber {
463 self.buf()[index::MODEL_NUMBER].into()
464 }
465
466 fn set_model_number(&mut self, model_number: ModelNumber) {
468 self.buf_mut()[index::MODEL_NUMBER] = model_number.into();
469 }
470
471 fn code_revision(&self) -> CodeRevision {
473 self.buf()[index::CODE_REVISION].into()
474 }
475
476 fn set_code_revision(&mut self, code_revision: CodeRevision) {
478 self.buf_mut()[index::CODE_REVISION] = code_revision.into()
479 }
480}
481
482impl_message_ops!(OmnibusReply);
483impl_omnibus_reply_ops!(OmnibusReply);
484
485impl From<&OmnibusReply> for Banknote {
486 fn from(reply: &OmnibusReply) -> Self {
487 use crate::bau_currency;
488
489 let note_value = bau_currency().denomination_value_base(reply.note_value());
490 Self::default().with_value(note_value.into())
491 }
492}
493
494impl From<&dyn OmnibusReplyOps> for DocumentStatus {
495 fn from(reply: &dyn OmnibusReplyOps) -> Self {
496 Self::default().with_standard_denomination(reply.note_value())
497 }
498}
499
500#[cfg(test)]
501mod tests {
502 use super::*;
503 use crate::Result;
504
505 #[test]
506 #[rustfmt::skip]
507 fn test_omnibus_reply_from_buf() -> Result<()> {
508 let msg_bytes = [
509 0x02, 0x0b, 0x20,
511 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
513 0x03, 0x2b,
515 ];
516
517 let mut msg = OmnibusReply::new();
518 msg.from_buf(msg_bytes.as_ref())?;
519
520 assert_eq!(msg.message_type(), MessageType::OmnibusReply);
521 assert_eq!(msg.device_state(), DeviceState::from(0));
522 assert_eq!(msg.device_status(), DeviceStatus::from(0));
523 assert_eq!(msg.exception_status(), ExceptionStatus::from(0));
524 assert_eq!(msg.misc_device_state(), MiscDeviceState::from(0));
525 assert_eq!(msg.model_number(), ModelNumber::from(0));
526 assert_eq!(msg.code_revision(), CodeRevision::from(0));
527
528 Ok(())
529 }
530}