1 /* sane - Scanner Access Now Easy.
2
3 Copyright (C) 2019 Povilas Kanapickas <povilas@radix.lt>
4
5 This file is part of the SANE package.
6
7 This program is free software; you can redistribute it and/or
8 modify it under the terms of the GNU General Public License as
9 published by the Free Software Foundation; either version 2 of the
10 License, or (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <https://www.gnu.org/licenses/>.
19 */
20
21 #define DEBUG_DECLARE_ONLY
22
23 #include "usb_device.h"
24
25 namespace genesys {
26
27 IUsbDevice::~IUsbDevice() = default;
28
~UsbDevice()29 UsbDevice::~UsbDevice()
30 {
31 if (is_open()) {
32 DBG(DBG_error, "UsbDevice not closed; closing automatically");
33 close();
34 }
35 }
36
open(const char * dev_name)37 void UsbDevice::open(const char* dev_name)
38 {
39 DBG_HELPER(dbg);
40
41 if (is_open()) {
42 throw SaneException("device already open");
43 }
44 int device_num = 0;
45
46 dbg.status("open device");
47 TIE(sanei_usb_open(dev_name, &device_num));
48
49 name_ = dev_name;
50 device_num_ = device_num;
51 is_open_ = true;
52 }
53
clear_halt()54 void UsbDevice::clear_halt()
55 {
56 DBG_HELPER(dbg);
57 assert_is_open();
58 TIE(sanei_usb_clear_halt(device_num_));
59 }
60
reset()61 void UsbDevice::reset()
62 {
63 DBG_HELPER(dbg);
64 assert_is_open();
65 TIE(sanei_usb_reset(device_num_));
66 }
67
close()68 void UsbDevice::close()
69 {
70 DBG_HELPER(dbg);
71 assert_is_open();
72
73 // we can't do much if closing fails, so we close the device on our side regardless of the
74 // function succeeds
75 int device_num = device_num_;
76
77 set_not_open();
78 sanei_usb_close(device_num);
79 }
80
get_vendor_id()81 std::uint16_t UsbDevice::get_vendor_id()
82 {
83 DBG_HELPER(dbg);
84 assert_is_open();
85 int vendor = 0;
86 int product = 0;
87 TIE(sanei_usb_get_vendor_product(device_num_, &vendor, &product));
88 return static_cast<std::uint16_t>(vendor);
89 }
90
get_product_id()91 std::uint16_t UsbDevice::get_product_id()
92 {
93 DBG_HELPER(dbg);
94 assert_is_open();
95 int vendor = 0;
96 int product = 0;
97 TIE(sanei_usb_get_vendor_product(device_num_, &vendor, &product));
98 return static_cast<std::uint16_t>(product);
99 }
100
get_bcd_device()101 std::uint16_t UsbDevice::get_bcd_device()
102 {
103 DBG_HELPER(dbg);
104 assert_is_open();
105 sanei_usb_dev_descriptor desc;
106 TIE(sanei_usb_get_descriptor(device_num_, &desc));
107 return desc.bcd_dev;
108 }
109
control_msg(int rtype,int reg,int value,int index,int length,std::uint8_t * data)110 void UsbDevice::control_msg(int rtype, int reg, int value, int index, int length,
111 std::uint8_t* data)
112 {
113 DBG_HELPER(dbg);
114 assert_is_open();
115 TIE(sanei_usb_control_msg(device_num_, rtype, reg, value, index, length, data));
116 }
117
bulk_read(std::uint8_t * buffer,std::size_t * size)118 void UsbDevice::bulk_read(std::uint8_t* buffer, std::size_t* size)
119 {
120 DBG_HELPER(dbg);
121 assert_is_open();
122 TIE(sanei_usb_read_bulk(device_num_, buffer, size));
123 }
124
bulk_write(const std::uint8_t * buffer,std::size_t * size)125 void UsbDevice::bulk_write(const std::uint8_t* buffer, std::size_t* size)
126 {
127 DBG_HELPER(dbg);
128 assert_is_open();
129 TIE(sanei_usb_write_bulk(device_num_, buffer, size));
130 }
131
assert_is_open() const132 void UsbDevice::assert_is_open() const
133 {
134 if (!is_open()) {
135 throw SaneException("device not open");
136 }
137 }
138
set_not_open()139 void UsbDevice::set_not_open()
140 {
141 device_num_ = 0;
142 is_open_ = false;
143 name_ = "";
144 }
145
146 } // namespace genesys
147