summaryrefslogtreecommitdiff
path: root/include/uhd/iface.h
blob: cc253617b596ed3e0e286a8b399cf585ffd57868 (plain)
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
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
/** @file
 * @brief usbhid-dump - interface
 *
 * Copyright (C) 2010 Nikolai Kondrashov
 *
 * This file is part of usbhid-dump.
 *
 * Usbhid-dump is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * Usbhid-dump is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with usbhid-dump; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 * @author Nikolai Kondrashov <spbnick@gmail.com>
 *
 * @(#) $Id$
 */

#ifndef __UHD_IFACE_H__
#define __UHD_IFACE_H__

#include <stdbool.h>
#include <libusb-1.0/libusb.h>

#ifdef __cplusplus
extern "C" {
#endif

/** usbhid-dump interface */
typedef struct uhd_iface uhd_iface;

struct uhd_iface {
    uhd_iface              *next;
    libusb_device_handle   *handle;         /**< Device handle */
    uint8_t                 number;         /**< Interface number */
    uint8_t                 int_in_ep_addr; /**< Interrupt IN EP address */
    uint16_t                int_in_ep_maxp; /**< Interrupt IN EP maximum
                                                 packet size */
    bool                    detached;       /**< True if the interface was
                                                 detached from the kernel
                                                 driver, false otherwise */
    bool                    claimed;        /**< True if the interface was
                                                 claimed */
    /*
     * This is somewhat hackish and doesn't belong here, since theoretically
     * there could be more than one transfer submitted for an interface.
     * However, we don't do it yet. This flag is used to track transfer
     * cancellation during stream dumping.
     */
    bool                    submitted;      /**< True if an asynchronous
                                                 transfer has been submitted
                                                 for the interface */
};

/**
 * Check if an interface is valid.
 *
 * @param iface Interface.
 *
 * @return True if the interface is valid, false otherwise.
 */
extern bool uhd_iface_valid(const uhd_iface *iface);

/**
 * Create a new interface.
 *
 * @param handle            Device handle.
 * @param number            Interface number.
 * @param int_in_ep_addr    Interrupt in endpoint address.
 * @param int_in_ep_maxp    Interrupt in endpoint maximum packet size.
 *
 * @return New interface or NULL, if failed to allocate.
 */
extern uhd_iface *uhd_iface_new(libusb_device_handle   *handle,
                                uint8_t                 number,
                                uint8_t                 int_in_ep_addr,
                                uint16_t                int_in_ep_maxp);

/**
 * Free an interface.
 *
 * @param iface The interface to free, could be NULL.
 */
extern void uhd_iface_free(uhd_iface *iface);

/**
 * Detach an interface from its kernel driver (if any).
 *
 * @param iface The interface to detach.
 *
 * @return Libusb error code.
 */
extern enum libusb_error uhd_iface_detach(uhd_iface *iface);

/**
 * Attach an interface to its kernel driver (if detached before).
 *
 * @param iface The interface to attach.
 *
 * @return Libusb error code.
 */
extern enum libusb_error uhd_iface_attach(uhd_iface *iface);

/**
 * Claim an interface.
 *
 * @param iface The interface to claim.
 *
 * @return Libusb error code.
 */
extern enum libusb_error uhd_iface_claim(uhd_iface *iface);

/**
 * Set idle duration on an interface; ignore errors indicating missing
 * support.
 *
 * @param iface     The interface to set idle duration on.
 * @param duration  The duration in 4 ms steps starting from 4 ms.
 * @param timeout   The request timeout, ms.
 *
 * @return Libusb error code.
 */
extern enum libusb_error uhd_iface_set_idle(
                                       const uhd_iface    *iface,
                                       uint8_t             duration,
                                       unsigned int        timeout);

/**
 * Set HID protocol on an interface; ignore errors indicating missing
 * support.
 *
 * @param iface     The interface to set idle duration on.
 * @param report    True for "report" protocol, false for "boot" protocol.
 * @param timeout   The request timeout, ms.
 *
 * @return Libusb error code.
 */
extern enum libusb_error uhd_iface_set_protocol(
                                       const uhd_iface    *iface,
                                       bool                report,
                                       unsigned int        timeout);

/**
 * Clear halt condition on the input interrupt endpoint of an interface.
 *
 * @param iface The interface to clear halt condition on.
 *
 * @return Libusb error code.
 */
extern enum libusb_error uhd_iface_clear_halt(uhd_iface *iface);

/**
 * Release an interface (if claimed before).
 *
 * @param iface The interface to release.
 *
 * @return Libusb error code.
 */
extern enum libusb_error uhd_iface_release(uhd_iface *iface);

/**
 * Check if an interface list is valid.
 *
 * @param list  Interface list to check.
 *
 * @return True if the interface list is valid, false otherwise.
 */
extern bool uhd_iface_list_valid(const uhd_iface *list);

/**
 * Check if an interface list is empty.
 *
 * @param list  Interface list to check.
 *
 * @return True if the interface list is empty, false otherwise.
 */
static inline bool
uhd_iface_list_empty(const uhd_iface *list)
{
    return list == NULL;
}

/**
 * Calculate length of an interface list.
 *
 * @param list  The list to calculate length of.
 *
 * @return The list length.
 */
extern size_t uhd_iface_list_len(const uhd_iface *list);

/**
 * Free an interface list.
 *
 * @param list  The interface list to free.
 */
extern void uhd_iface_list_free(uhd_iface *list);

/**
 * Iterate over an interface list.
 *
 * @param _iface    Loop interface variable.
 * @param _list     Interface list to iterate over.
 */
#define UHD_IFACE_LIST_FOR_EACH(_iface, _list) \
    for (_iface = _list; _iface != NULL; _iface = _iface->next)

/**
 * Fetch a list of HID interfaces from a device.
 *
 * @param handle        The device handle to fetch interface list from.
 * @param plist         Location for the resulting list head; could be NULL.
 *
 * @return Libusb error code.
 */
enum libusb_error
uhd_iface_list_new_from_dev(libusb_device_handle   *handle,
                            uhd_iface             **plist);

/**
 * Filter an interface list by an optional interface number, resulting
 * either in an empty, a single-interface, or an unmodified list.
 *
 * @param plist     The original list head.
 * @param number    The interface number to match against, or a negative
 *                  integer meaning there is no restriction.
 *
 * @return The resulting list head
 */
extern uhd_iface *uhd_iface_list_fltr_by_num(uhd_iface *list,
                                             int        number);

#ifdef __cplusplus
} /* extern "C" */
#endif

#endif /* __UHD_IFACE_H__ */