1 module hidapi.device;
2 
3 import hidapi.bindings;
4 import hidapi.error;
5 import hidapi.hid;
6 import std.exception : enforce;
7 import std.format : format;
8 
9 class Device : Hid
10 {
11     private hid_device* handle = null;
12     private uint timeout = 5;
13     private uint default_read_size = 64;
14     private int ret = 0;
15 
16     /**
17      * Opens the first matching device
18      *
19      * Params:
20      *      vendor_id =     Vendor ID
21      *      product_id =    Product ID
22      */
23     this(uint vendor_id, uint product_id)
24     {
25         handle = hid_open(cast(ushort) vendor_id, cast(ushort) product_id, null);
26         enforce!HidError(handle != null, "Failed to open the device");
27     }
28 
29     /**
30      * Opens the first matching device 
31      *
32      * Params:
33      *      vendor_id =     Vendor ID
34      *      product_id =    Product ID
35      *      serial_nuber =  Serial Number
36      */
37     this(uint vendor_id, uint product_id, string serial_number)
38     {
39         handle = hid_open(cast(ushort) vendor_id, cast(ushort) product_id, cast(immutable(dchar)*) serial_number.ptr);
40         enforce!HidError(handle != null, "Failed to open the device");
41     }
42 
43     /**
44      * Opens a specific device
45      *
46      * Params:
47      *      path =  Device path
48      */
49     this(string path)
50     {
51         handle = hid_open_path(cast(immutable(char)*) path.ptr);
52         enforce!HidError(handle != null, "Failed to open the device");
53     }
54 
55     /**
56      * Writes to the device 
57      *
58      * Params:
59      *      buf =   Buffer
60      *      size =  Buffer size
61      */
62     void write(ubyte[] buf, uint size)
63     {
64         hid_write(handle, buf.ptr, size);
65     }
66 
67     /**
68      * Reads from the device
69      *
70      * Returns: Buffer
71      */
72     ubyte[] read()
73     {
74         return read(default_read_size);
75     }
76 
77     /**
78      * Reads from the device
79      *
80      * Params:
81      *      size =  Size to read
82      *
83      * Returns: Buffer
84      */
85     ubyte[] read(uint size)
86     {
87         ubyte[] buf = new ubyte[default_read_size];
88         ret = hid_read_timeout(handle, buf.ptr, size, timeout);
89         enforce!HidError(ret != -1, "Error reading from the device");
90         return buf;
91     }
92 
93     /**
94      * Executes a command
95      *
96      * Sends a buffer to the device
97      * and reurns the reply.
98      *
99      * Params:
100      *      buf =   Buffer
101      *      size =  Buffer size
102      *
103      * Returns: Reply buffer
104      */
105     ubyte[] command(ubyte[] buf, uint size)
106     {
107         write(buf, size);
108         return read();
109     }
110 
111     /**
112      * Executes a command
113      *
114      * Sends a buffer to the device
115      * and reurns the reply.
116      *
117      * Params:
118      *      buf =   Buffer
119      *      size =  Buffer size
120      *      read_size = Size to read
121      *
122      * Returns: Reply buffer
123      */
124     ubyte[] command(ubyte[] buf, uint size, uint read_size)
125     {
126         write(buf, size);
127         return read(read_size);
128     }
129 
130     /**
131      * Enables/Disables non-blocking mode
132      *
133      * Params:
134      *      buf =   Buffer
135      */
136     void setNonBlockingMode(bool mode)
137     {
138         hid_set_nonblocking(handle, mode ? 1 : 0);
139         enforce!HidError(ret != -1, "Error setting non-blocking mode");
140     }
141 
142     /**
143      * Sends a feature report
144      *
145      * Params:
146      *      buf =   Buffer
147      *      size =  Buffer size
148      */
149     void sendFeatureReport(ubyte[] buf, uint size)
150     {
151         ret = hid_send_feature_report(handle, buf.ptr, size);
152         enforce!HidError(ret != -1, "Error sending feature report");
153     }
154 
155     /**
156      * Reads a feature report
157      *
158      * Params:
159      *      size =  Size to read
160      *
161      * Returns: Buffer
162      */
163     ubyte[] getFeatureReport(uint size)
164     {
165         ubyte[] buf = new ubyte[size];
166         ret = hid_get_feature_report(handle, buf.ptr, size);
167         enforce!HidError(ret != -1, "Error getting feature report");
168         return buf;
169     }
170 
171     /**
172      * Reads the manufacturer string
173      *
174      * Returns: Manufacturer string
175      */
176     string getManufacturer()
177     {
178         return getManufacturer(255);
179     }
180 
181     /**
182      * Reads the manufacturer string
183      *
184      * Params:
185      *      size =  Size to read
186      *
187      * Returns: Manufacturer string
188      */
189     string getManufacturer(uint size)
190     {
191         dchar[] buf = new dchar[size];
192         ret = hid_get_manufacturer_string(handle, buf.ptr, size);
193         enforce!HidError(ret != -1, "Error getting the manufacturer");
194         return cast(string) buf;
195     }
196 
197     /**
198      * Reads the product string
199      *
200      * Returns: Product string
201      */
202     string getProduct()
203     {
204         return getProduct(255);
205     }
206 
207     /**
208      * Reads the product string
209      *
210      * Params:
211      *      size =  Size to read
212      *
213      * Returns: Product string
214      */
215     string getProduct(uint size)
216     {
217         dchar[] buf = new dchar[size];
218         ret = hid_get_product_string(handle, buf.ptr, size);
219         enforce!HidError(ret != -1, "Error getting the product");
220         return cast(string) buf;
221     }
222 
223     /**
224      * Reads the serial number
225      *
226      * Returns: Serial number
227      */
228     string getSerialNumber()
229     {
230         return getSerialNumber(255);
231     }
232 
233     /**
234      * Reads the serial number
235      *
236      * Params:
237      *      size =  Size to read
238      *
239      * Returns: Serial number
240      */
241     string getSerialNumber(uint size)
242     {
243         dchar[] buf = new dchar[size];
244         ret = hid_get_serial_number_string(handle, buf.ptr, size);
245         enforce!HidError(ret != -1, "Error getting the serial number");
246         return cast(string) buf;
247     }
248 
249     /**
250      * Reads a indexed string
251      *
252      * Params:
253      *      index = String index
254      *
255      * Returns: Indexed string
256      */
257     string getIndexedString(uint index)
258     {
259         return getIndexedString(index, 255);
260     }
261 
262     /**
263      * Reads a indexed string
264      *
265      * Params:
266      *      index = String index
267      *      size =  Size to read
268      *
269      * Returns: Indexed string
270      */
271     string getIndexedString(uint index, uint size)
272     {
273         dchar[] buf = new dchar[size];
274         ret = hid_get_indexed_string(handle, index, buf.ptr, size);
275         enforce!HidError(ret != -1,
276                             format("Error getting the indexed string #%d", index));
277         return cast(string) buf;
278     }
279 
280     /**
281      * Gets the timeout
282      *
283      * Returns: Timeout
284      */
285     uint getTimeout()
286     {
287         return timeout;
288     }
289 
290     /**
291      * Sets the timeout 
292      *
293      * Params:
294      *      timeout =   Timeout
295      */
296     void setTimeout(uint timeout)
297     {
298         this.timeout = timeout;
299     }
300 
301     /**
302      * Gets the default read size
303      *
304      * Returns: Read size
305      */
306     uint getDefaultReadSize()
307     {
308         return default_read_size;
309     }
310 
311     /**
312      * Sets the deafult read size
313      *
314      * Params:
315      *      size =  Read size
316      */
317     void setDefaultReadSize(uint size)
318     {
319         default_read_size = size;
320     }
321 
322 }