hid_exchange.c

Go to the documentation of this file.
00001 #define HID_INTERNAL
00002 
00003 #include <hid.h>
00004 #include <hid_helpers.h>
00005 #include <os.h>
00006 #include <errno.h>
00007 #include <constants.h>
00008 #include <compiler.h>
00009 
00010 #include <debug.h>
00011 #include <assert.h>
00012 
00023 hid_return hid_get_input_report(HIDInterface* const hidif, int const path[],
00024     unsigned int const depth, char* const buffer, unsigned int const size)
00025 {
00026   ASSERT(hid_is_initialised());
00027   ASSERT(hid_is_opened(hidif));
00028   ASSERT(buffer);
00029 
00030   if (!buffer) return HID_RET_INVALID_PARAMETER;
00031 
00032   if (!hid_is_opened(hidif)) {
00033     WARNING("the device has not been opened.");
00034     return HID_RET_DEVICE_NOT_OPENED;
00035   }
00036 
00037   TRACE("looking up report ID...");
00038   hidif->hid_data->Type = ITEM_INPUT;
00039   hidif->hid_data->ReportID = 0;
00040 
00041   hid_find_object(hidif, path, depth);
00042 
00043   TRACE("retrieving report ID 0x%02x (length: %d) from USB device %s...", 
00044         hidif->hid_data->ReportID, size, hidif->id);
00045 
00046   int len = usb_control_msg(hidif->dev_handle,
00047       USB_ENDPOINT_IN + USB_TYPE_CLASS + USB_RECIP_INTERFACE,
00048       HID_REPORT_GET,
00049       hidif->hid_data->ReportID + (HID_RT_INPUT << 8),
00050       hidif->interface,
00051       buffer, size, USB_TIMEOUT);
00052 
00053   if (len < 0) {
00054     WARNING("failed to retrieve report from USB device %s:%s.", hidif->id, usb_strerror());
00055     return HID_RET_FAIL_GET_REPORT;
00056   }
00057 
00058   if (len != (signed)size) {
00059     WARNING("failed to retrieve complete report from USB device %s; "
00060         "requested: %d bytes, got: %d bytes.", hidif->id, size, len);
00061     return HID_RET_FAIL_GET_REPORT;
00062   }
00063 
00064   NOTICE("successfully retrieved report from USB device %s.", hidif->id);
00065   return HID_RET_SUCCESS;
00066 }
00067 
00079 hid_return hid_set_output_report(HIDInterface* const hidif, int const path[],
00080     unsigned int const depth, char const* const buffer, unsigned int const size)
00081 {
00082   ASSERT(hid_is_initialised());
00083   ASSERT(hid_is_opened(hidif));
00084   ASSERT(buffer);
00085 
00086   if (!buffer) return HID_RET_INVALID_PARAMETER;
00087 
00088   if (!hid_is_opened(hidif)) {
00089     WARNING("the device has not been opened.");
00090     return HID_RET_DEVICE_NOT_OPENED;
00091   }
00092 
00093   TRACE("looking up report ID...");
00094   hidif->hid_data->Type = ITEM_OUTPUT;
00095   hidif->hid_data->ReportID = 0;
00096 
00097   hid_find_object(hidif, path, depth);
00098 
00099   TRACE("sending report ID 0x%02x (length: %d) to USB device %s...", 
00100         hidif->hid_data->ReportID, size, hidif->id);
00101 
00102   int len = usb_control_msg(hidif->dev_handle,
00103       USB_ENDPOINT_OUT + USB_TYPE_CLASS + USB_RECIP_INTERFACE,
00104       HID_REPORT_SET,
00105       hidif->hid_data->ReportID + (HID_RT_OUTPUT << 8),
00106       hidif->interface,
00107       (char*)buffer, size, USB_TIMEOUT);
00108 
00109   if (len < 0) {
00110     WARNING("failed to send report to USB device %s:%s.", hidif->id,usb_strerror());
00111     return HID_RET_FAIL_SET_REPORT;
00112   }
00113 
00114   if (len != (signed)size) {
00115     WARNING("failed to send complete report to USB device %s; "
00116         "requested: %d bytes, sent: %d bytes.", hidif->id, 
00117         size, len);
00118     return HID_RET_FAIL_SET_REPORT;
00119   }
00120 
00121   NOTICE("successfully sent report to USB device %s.", hidif->id);
00122   return HID_RET_SUCCESS;
00123 }
00124 
00135 hid_return hid_get_feature_report(HIDInterface* const hidif, int const path[],
00136     unsigned int const depth, char* const buffer, unsigned int const size)
00137 {
00138   ASSERT(hid_is_initialised());
00139   ASSERT(hid_is_opened(hidif));
00140   ASSERT(buffer);
00141 
00142   if (!buffer) return HID_RET_INVALID_PARAMETER;
00143 
00144   if (!hid_is_opened(hidif)) {
00145     WARNING("the device has not been opened.");
00146     return HID_RET_DEVICE_NOT_OPENED;
00147   }
00148 
00149   TRACE("looking up report ID...");
00150   hidif->hid_data->Type = ITEM_FEATURE;
00151   hidif->hid_data->ReportID = 0;
00152 
00153   hid_find_object(hidif, path, depth);
00154 
00155   TRACE("retrieving report ID 0x%02x (length: %d) from USB device %s...", 
00156         hidif->hid_data->ReportID, size, hidif->id);
00157 
00158   int len = usb_control_msg(hidif->dev_handle,
00159       USB_ENDPOINT_IN + USB_TYPE_CLASS + USB_RECIP_INTERFACE,
00160       HID_REPORT_GET,
00161       hidif->hid_data->ReportID + (HID_RT_FEATURE << 8),
00162       hidif->interface,
00163       buffer, size, USB_TIMEOUT);
00164 
00165   if (len < 0) {
00166     WARNING("failed to retrieve report from USB device %s:%s.", hidif->id, usb_strerror());
00167     return HID_RET_FAIL_GET_REPORT;
00168   }
00169 
00170   if (len != (signed)size) {
00171     WARNING("failed to retrieve complete report from USB device %s; "
00172         "requested: %d bytes, got: %d bytes.", hidif->id, size, len);
00173     return HID_RET_FAIL_GET_REPORT;
00174   }
00175 
00176   NOTICE("successfully retrieved report from USB device %s.", hidif->id);
00177   return HID_RET_SUCCESS;
00178 }
00179 
00191 hid_return hid_set_feature_report(HIDInterface* const hidif, int const path[],
00192     unsigned int const depth, char const* const buffer, unsigned int const size)
00193 {
00194   ASSERT(hid_is_initialised());
00195   ASSERT(hid_is_opened(hidif));
00196   ASSERT(buffer);
00197 
00198   if (!buffer) return HID_RET_INVALID_PARAMETER;
00199 
00200   if (!hid_is_opened(hidif)) {
00201     WARNING("the device has not been opened.");
00202     return HID_RET_DEVICE_NOT_OPENED;
00203   }
00204 
00205   TRACE("looking up report ID...");
00206   hidif->hid_data->Type = ITEM_FEATURE;
00207   hidif->hid_data->ReportID = 0;
00208 
00209   hid_find_object(hidif, path, depth);
00210 
00211   TRACE("sending report ID 0x%02x (length: %d) to USB device %s...", 
00212         hidif->hid_data->ReportID, size, hidif->id);
00213 
00214   int len = usb_control_msg(hidif->dev_handle,
00215       USB_ENDPOINT_OUT + USB_TYPE_CLASS + USB_RECIP_INTERFACE,
00216       HID_REPORT_SET,
00217       hidif->hid_data->ReportID + (HID_RT_FEATURE << 8),
00218       hidif->interface,
00219       (char*)buffer, size, USB_TIMEOUT);
00220 
00221   if (len < 0) {
00222     WARNING("failed to send report to USB device %s:%s.", hidif->id,usb_strerror());
00223     return HID_RET_FAIL_SET_REPORT;
00224   }
00225 
00226   if (len != (signed)size) {
00227     WARNING("failed to send complete report to USB device %s; "
00228         "requested: %d bytes, sent: %d bytes.", hidif->id, 
00229         size, len);
00230     return HID_RET_FAIL_SET_REPORT;
00231   }
00232 
00233   NOTICE("successfully sent report to USB device %s.", hidif->id);
00234   return HID_RET_SUCCESS;
00235 }
00236 
00246 hid_return hid_get_item_value(HIDInterface* const hidif, int const path[],
00247     unsigned int const depth, double *const value)
00248 {
00249   ASSERT(hid_is_initialised());
00250   ASSERT(hid_is_opened(hidif));
00251 
00252   unsigned int size;
00253   unsigned char buffer[32]; 
00255   if (!hid_is_opened(hidif)) {
00256     WARNING("the device has not been opened.");
00257     return HID_RET_DEVICE_NOT_OPENED;
00258   }
00259 
00260   TRACE("retrieving report from USB device %s...", hidif->id);
00261   hidif->hid_data->Type = ITEM_FEATURE;
00262   hidif->hid_data->ReportID = 0;
00263 
00264   /* TODO: i think this and the buffer stuff should be passed in */
00265   hid_find_object(hidif, path, depth);
00266   hid_get_report_size(hidif, hidif->hid_data->ReportID,
00267       hidif->hid_data->Type, &size);
00268 
00269   ASSERT(size <= 32); /* remove when buffer situation is fixed. */
00270 
00271   int len = usb_control_msg(hidif->dev_handle,
00272       USB_ENDPOINT_IN + USB_TYPE_CLASS + USB_RECIP_INTERFACE,
00273       HID_REPORT_GET,
00274       hidif->hid_data->ReportID + (HID_RT_FEATURE << 8),
00275       hidif->interface,
00276       (char*)buffer, size, USB_TIMEOUT);
00277 
00278   if (len < 0) {
00279     WARNING("failed to retrieve report from USB device %s:%s.", hidif->id,usb_strerror());
00280     return HID_RET_FAIL_GET_REPORT;
00281   }
00282 
00283   if ((unsigned)len != size) {
00284     WARNING("failed to retrieve complete report from USB device %s; "
00285         "requested: %d bytes, got: %d bytes.", hidif->id, 
00286         size, len);
00287     return HID_RET_FAIL_GET_REPORT;
00288   }
00289 
00290   if (hid_extract_value(hidif, buffer, value) != HID_RET_SUCCESS) {
00291     return HID_RET_FAIL_GET_REPORT;
00292   }
00293 
00294   NOTICE("successfully retrieved report from USB device %s.", hidif->id);
00295   return HID_RET_SUCCESS;
00296 }
00297 
00299 hid_return hid_get_item_string(HIDInterface* const hidif UNUSED,
00300     int const path[] UNUSED, unsigned int const depth UNUSED,
00301     char *const value UNUSED, unsigned int const maxlen UNUSED)
00302 {
00303   bool const not_yet_implemented = false;
00304   ASSERT(not_yet_implemented);
00305   return HID_RET_SUCCESS;
00306 }
00307 
00308 
00310 hid_return hid_set_item_value(HIDInterface* const hidif UNUSED,
00311     int const path[] UNUSED, unsigned int const depth UNUSED,
00312     double const value UNUSED)
00313 {
00314   bool const not_yet_implemented = false;
00315   ASSERT(not_yet_implemented);
00316   return HID_RET_SUCCESS;
00317 }
00318 
00332 hid_return hid_interrupt_read(HIDInterface * const hidif,
00333      unsigned int const ep, char* const bytes, unsigned int const size, 
00334      unsigned int const timeout) 
00335 {
00336   ASSERT(hid_is_initialised());
00337   ASSERT(hid_is_opened(hidif));
00338   ASSERT(bytes);
00339 
00340   if (!bytes) return HID_RET_INVALID_PARAMETER;
00341 
00342   if (!hid_is_opened(hidif)) {
00343     WARNING("the device has not been opened.");
00344     return HID_RET_DEVICE_NOT_OPENED;
00345   }
00346 
00347   TRACE("retrieving interrupt report from device %s ...", hidif->id);
00348 
00349   int len = usb_interrupt_read(hidif->dev_handle,
00350                                ep,
00351                                bytes,
00352                                size,
00353                                timeout);
00354 
00355   if (len == -ETIMEDOUT) {
00356     WARNING("timeout on interrupt read from device %s", hidif->id);
00357     return HID_RET_TIMEOUT;
00358   }
00359 
00360   if (len < 0) {
00361     WARNING("failed to get interrupt read from device %s: %s", hidif->id, usb_strerror());
00362     return HID_RET_FAIL_INT_READ;
00363   }
00364 
00365   if (len != (signed)size) {
00366     WARNING("failed to get all of interrupt report from device %s; "
00367       "requested: %d bytes, sent: %d bytes.", hidif->id,
00368       size, len);
00369     return HID_RET_FAIL_INT_READ;
00370   }
00371 
00372   NOTICE("successfully got interrupt report from device %s", hidif->id);
00373   return HID_RET_SUCCESS;
00374 }
00375 
00386 hid_return hid_interrupt_write(HIDInterface * const hidif,
00387      unsigned int const ep, const char* const bytes, unsigned int const size, 
00388      unsigned int const timeout) 
00389 {
00390   ASSERT(hid_is_initialised());
00391   ASSERT(hid_is_opened(hidif));
00392   ASSERT(bytes);
00393 
00394   if (!bytes) return HID_RET_INVALID_PARAMETER;
00395 
00396   if (!hid_is_opened(hidif)) {
00397     WARNING("the device has not been opened.");
00398     return HID_RET_DEVICE_NOT_OPENED;
00399   }
00400 
00401   TRACE("writing interrupt report to device %s ...", hidif->id);
00402 
00403   int len = usb_interrupt_write(hidif->dev_handle,
00404                                ep,
00405                                (char *)bytes,
00406                                size,
00407                                timeout);
00408 
00409   if (len == -ETIMEDOUT) {
00410     WARNING("timeout on interrupt write to device %s", hidif->id);
00411     return HID_RET_TIMEOUT;
00412   }
00413 
00414   if (len < 0) {
00415     WARNING("failed to perform interrupt write to device %s: %s", hidif->id, usb_strerror());
00416     return HID_RET_FAIL_INT_READ;
00417   }
00418 
00419   if (len != (signed)size) {
00420     WARNING("failed to write all of interrupt report to device %s; "
00421       "requested: %d bytes, sent: %d bytes.", hidif->id,
00422       size, len);
00423     return HID_RET_FAIL_INT_READ;
00424   }
00425 
00426   NOTICE("successfully sent interrupt report to device %s", hidif->id);
00427   return HID_RET_SUCCESS;
00428 }
00429 
00439 hid_return hid_set_idle(HIDInterface * const hidif,
00440     unsigned duration, unsigned report_id) 
00441 {
00442   if(duration > 255) {
00443     WARNING("duration must be in the range [0,255]");
00444     return HID_RET_INVALID_PARAMETER;
00445   }
00446 
00447   if(report_id > 255) {
00448     WARNING("Report ID must be in the range [0,255]");
00449     return HID_RET_INVALID_PARAMETER;
00450   }
00451 
00452   int len = usb_control_msg(hidif->dev_handle,
00453       USB_TYPE_CLASS + USB_RECIP_INTERFACE,
00454       HID_SET_IDLE,
00455       report_id + ((duration & 0xff) << 8),
00456       hidif->interface,
00457       NULL, 0, USB_TIMEOUT);
00458 
00459   if (len != 0) {
00460     WARNING("failed to Set_Idle for USB device %s:%s.", hidif->id, usb_strerror());
00461     return HID_RET_FAIL_GET_REPORT;
00462   }
00463 
00464   return HID_RET_SUCCESS;
00465 }
00466 
00467 /* COPYRIGHT --
00468  *
00469  * This file is part of libhid, a user-space HID access library.
00470  * libhid is (c) 2003-2005
00471  *   Martin F. Krafft <libhid@pobox.madduck.net>
00472  *   Charles Lepple <clepple@ghz.cc>
00473  *   Arnaud Quette <arnaud.quette@free.fr> && <arnaud.quette@mgeups.com>
00474  * and distributed under the terms of the GNU General Public License.
00475  * See the file ./COPYING in the source distribution for more information.
00476  *
00477  * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
00478  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES
00479  * OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00480  */

Generated on Sun Mar 30 15:28:24 2008 for libhid by  doxygen 1.5.1