1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
use crate::client::*;
use crate::protocol::*;

pub struct CCTalkDevice {
    pub client: Box<dyn CCTalkClient + 'static>,
    address: Address,
    checksum_type: ChecksumType,
    pub counter: u8,
}

impl CCTalkDevice {
    pub fn new(
        port_name: &String,
        serial_settings: &serial::PortSettings,
        address: Address,
        checksum_type: ChecksumType,
        mock: bool,
    ) -> Result<CCTalkDevice, ClientError> {
        let temp_client: Box<dyn CCTalkClient + 'static> = match mock {
            false => Box::new(SerialClient::new(port_name, serial_settings)?),
            true => Box::new(DummyClient::new()),
        };

        Ok(CCTalkDevice {
            client: temp_client,
            address: address,
            checksum_type: checksum_type,
            counter: 0,
        })
    }

    pub fn set_bill_event(&mut self, bill_event: BillEvent) {
        self.client.set_bill_event(bill_event);
    }

    pub fn create_message(&mut self, payload: Payload) -> Message {
        Message::new(
            self.address,
            self.client.get_address(),
            payload,
            self.checksum_type,
        )
    }

    pub fn reset(&mut self) -> Result<Payload, ClientError> {
        let message = self.create_message(Payload {
            header: HeaderType::ResetDevice,
            data: Vec::<u8>::new(),
        });
        self.client.send_and_check_reply(&message)
    }

    pub fn simple_poll(&mut self) -> Result<Payload, ClientError> {
        let message = self.create_message(Payload {
            header: HeaderType::SimplePoll,
            data: Vec::<u8>::new(),
        });
        self.client.send_and_check_reply(&message)
    }

    pub fn modify_inhibit_status(
        &mut self,
        inhibit_status: Vec<u8>,
    ) -> Result<Payload, ClientError> {
        let message = self.create_message(Payload {
            header: HeaderType::ModifyInhibitStatus,
            data: inhibit_status,
        });
        self.client.send_and_check_reply(&message)
    }

    pub fn modify_master_inhibit_status(
        &mut self,
        inhibit_status: u8,
    ) -> Result<Payload, ClientError> {
        let message = self.create_message(Payload {
            header: HeaderType::ModifyMasterInhibitStatus,
            data: vec![inhibit_status],
        });
        self.client.send_and_check_reply(&message)
    }

    pub fn read_buffered_credit(&mut self) -> Result<Payload, ClientError> {
        let message = self.create_message(Payload {
            header: HeaderType::ReadBufferedCreditOrErrorCodes,
            data: Vec::<u8>::new(),
        });
        self.client.send_and_check_reply(&message)
    }

    pub fn interpret_buffered_bill_payload(
        payload: Payload,
    ) -> Result<(u8, BillEvent), ClientError> {
        let mut data = payload.data;
        if data.len() < 3 {
            return Err(ClientError::CCTalkError(ErrorType::ParseError));
        }
        let counter: u8 = data.remove(0);
        Ok((counter, BillEvent::from_u8((data[0], data[1]))))
    }

    pub fn read_buffered_bill(&mut self) -> Result<(u8, BillEvent), ClientError> {
        let message = self.create_message(Payload {
            header: HeaderType::ReadBufferedBillEvents,
            data: Vec::<u8>::new(),
        });
        let response = self.client.send_and_check_reply(&message)?;
        let res = CCTalkDevice::interpret_buffered_bill_payload(response)?;
        Ok(res)
    }

    pub fn modify_bill_operating_mode(&mut self, mode: u8) -> Result<Payload, ClientError> {
        let message = self.create_message(Payload {
            header: HeaderType::ModifyBillOperatingMode,
            data: vec![mode],
        });
        self.client.send_and_check_reply(&message)
    }

    pub fn route_bill(&mut self, route: u8) -> Result<Payload, ClientError> {
        let message = self.create_message(Payload {
            header: HeaderType::RouteBill,
            data: vec![route],
        });
        self.client.send_and_check_reply(&message)
    }

    pub fn request_equipment_category(&mut self) -> Result<String, ClientError> {
        let message = self.create_message(Payload {
            header: HeaderType::RequestEquipmentCategoryId,
            data: Vec::<u8>::new(),
        });
        let payload = self.client.send_and_check_reply(&message);

        match payload {
            Ok(equipment_category) => Ok(equipment_category.as_str().unwrap()),
            Err(e) => Err(e),
        }
    }

    pub fn read_coin_ids(&mut self) -> Result<(), ClientError> {
        for x in 1..10 {
            let message = self.create_message(Payload {
                header: HeaderType::RequestCoinId,
                data: vec![x],
            });
            let payload = self.client.send_and_check_reply(&message);

            match payload {
                Ok(coin_id) => {
                    // log::debug!("Coin id raw: {:?}", coin_id);
                    log::debug!("Coin id: {}", coin_id.as_str().unwrap());
                }
                Err(e) => log::error!("Response error: {:?}", e),
            }
        }
        Ok(())
    }

    pub fn read_bill_ids(&mut self) -> Result<(), ClientError> {
        for x in 1..10 {
            let message = self.create_message(Payload {
                header: HeaderType::RequestBillId,
                data: vec![x],
            });
            let payload = self.client.send_and_check_reply(&message);

            match payload {
                Ok(bill_id) => {
                    log::debug!("Bill id: {}", bill_id.as_str().unwrap());
                }
                Err(e) => log::error!("Response error: {:?}", e),
            }
        }
        Ok(())
    }

    pub fn request_scaling_factor(&mut self) -> Result<Payload, ClientError> {
        let message = self.create_message(Payload {
            header: HeaderType::RequestCountryScalingFactor,
            data: Vec::<u8>::new(),
        });
        self.client.send_and_check_reply(&message)
    }
}