1// -*- C++;indent-tabs-mode: t; tab-width: 4; c-basic-offset: 4; -*- 2#ifndef __USBPP_HEADER__ 3#define __USBPP_HEADER__ 4 5#include <string> 6#include <list> 7 8#include <usb.h> 9 10/* 11 * The following usb.h function is not wrapped yet: 12 * char *usb_strerror(void); 13 */ 14 15 16/** 17 * \brief Classes to access Universal Serial Bus devices 18 * 19 * The USB Namespace provides a number of classes to work 20 * with Universal Serial Bus (USB) devices attached to the 21 * system. 22 * 23 * \author Brad Hards 24 */ 25namespace USB { 26 27 class Device; 28 29 /** 30 * \brief Class representing a device endpoint 31 * 32 * This class represents a device endpoint. You need this class to 33 * perform bulk reads and writes. 34 * 35 */ 36 class Endpoint { 37 /** 38 * Busses is a friend because it fills in the descriptor type 39 * information on initialisation and rescan. 40 */ 41 friend class Busses; 42 public: 43 Endpoint() {}; 44 45#ifdef USE_UNTESTED_LIBUSBPP_METHODS 46 /** 47 * \brief Bulk write 48 * 49 * This method performs a bulk transfer to the endpoint. 50 * 51 * \param message is the message to be sent. 52 * \param timeout is the USB transaction timeout in milliseconds 53 * 54 * \returns the number of bytes sent, or a negative value on 55 * failure 56 */ 57 int bulkWrite(QByteArray message, int timeout = 100); 58 59 /** 60 * \brief Bulk read 61 * 62 * This method performs a bulk transfer from the endpoint. 63 * 64 * \param length is the maximum data transfer required. 65 * \param message is the message that was received. 66 * \param timeout is the USB transaction timeout in milliseconds 67 * 68 * \returns the number of bytes received, or a negative value on 69 * failure 70 */ 71 int bulkRead(int length, unsigned char *message, int timeout = 100); 72 73 /** 74 * \brief Reset endpoint 75 * 76 * This method resets the endpoint. 77 */ 78 int reset(void); 79 80 /** 81 * \brief Clear halt 82 * 83 * This method clears a halt (stall) on the endpoint. 84 */ 85 int clearHalt(void); 86 87#endif /* USE_UNTESTED_LIBUSBPP_METHODS */ 88 89 /** 90 * \brief Endpoint descriptor information output 91 * 92 * This method dumps out the various characteristics 93 * of the endpoint to standard output. 94 * 95 * It is mostly useful for debugging. 96 */ 97 void dumpDescriptor(void); 98 99 private: 100 void setDescriptor(struct usb_endpoint_descriptor); 101 void setParent(Device *parent); 102 u_int8_t m_Length; 103 u_int8_t m_DescriptorType; 104 u_int8_t m_EndpointAddress; 105 u_int8_t m_Attributes; 106 u_int16_t m_MaxPacketSize; 107 u_int8_t m_Interval; 108 u_int8_t m_Refresh; 109 u_int8_t m_SynchAddress; 110 Device *m_parent; 111 }; 112 113 class AltSetting : public std::list<Endpoint *> { 114 /** 115 * Busses is a friend because it fills in the descriptor type 116 * information on initialisation and rescan. 117 */ 118 friend class Busses; 119 public: 120 AltSetting() {}; 121 u_int8_t numEndpoints(void); 122 123 /** 124 * \brief AltSetting descriptor information output 125 * 126 * This method dumps out the various characteristics 127 * of the alternate setting to standard output. 128 * 129 * It is mostly useful for debugging. 130 */ 131 void dumpDescriptor(void); 132 133 Endpoint *firstEndpoint(void); 134 Endpoint *nextEndpoint(void); 135 Endpoint *lastEndpoint(void); 136 137 private: 138 std::list<Endpoint *>::const_iterator iter; 139 140 void setDescriptor(struct usb_interface_descriptor); 141 /* we don't use a normal usb_interface_descriptor */ 142 /* because that would bring in the endpoint list */ 143 u_int8_t m_Length; 144 u_int8_t m_DescriptorType; 145 u_int8_t m_InterfaceNumber; 146 u_int8_t m_AlternateSetting; 147 u_int8_t m_NumEndpoints; 148 u_int8_t m_InterfaceClass; 149 u_int8_t m_InterfaceSubClass; 150 u_int8_t m_InterfaceProtocol; 151 u_int8_t m_Interface; 152 }; 153 154 /** 155 * \brief Class representing an interface of a Device 156 * 157 * The Interface class represents a USB interface 158 * for a device attached to a Universal Serial Bus. 159 * 160 * Interfaces are the main element of the USB class 161 * structure. 162 * 163 * \author Brad Hards 164 */ 165 class Interface : public std::list<AltSetting *> { 166 /** 167 * Busses is a friend because it fills in the descriptor type 168 * information on initialisation and rescan. 169 */ 170 friend class Busses; 171 public: 172 Interface() {}; 173 174#ifdef LIBUSB_HAS_GET_DRIVER_NP 175 /** 176 * \brief get the current driver for an interface 177 * 178 * \param driver a string containing the name of the current 179 * driver for the interface. You can typically pass in an empty 180 * string for this. 181 * 182 * \return length of string, or 0 on error. 183 */ 184 int driverName(std::string &driver); 185#endif 186 187#ifdef USE_UNTESTED_LIBUSBPP_METHODS 188 /** 189 * \brief Claim this interface 190 * 191 * This method claims the interface. You have to claim the 192 * interface before performing any operations on the interface (or 193 * on endpoints that are part of the interface). 194 * 195 * \return 0 on success or negative number on error. 196 */ 197 int claim(void); 198 199 /** 200 * \brief Release this interface 201 * 202 * This method releases the interface. You should release the 203 * interface after all operations on it (and any lower level 204 * endpoints) are completed. 205 * 206 * \return 0 on success or negative number on error. 207 */ 208 int release(void); 209 210 /** 211 * \brief Set interface alternate setting 212 * 213 * This method sets the interface to a particular AltSetting. 214 * 215 * \param altSettingNumber the AltSetting that the interface 216 * should be changed to. 217 * 218 * \return 0 on success, or a negative number in case of error. 219 */ 220 int setAltSetting(int altSettingNumber); 221#endif /* USE_UNTESTED_LIBUSBPP_METHODS */ 222 223 /** 224 * \brief Number of Alternative Settings that this interface has 225 * 226 * This is a simple accessor method that specifies the number 227 * alternative settings that this device interface has. 228 */ 229 u_int8_t numAltSettings(void); 230 231 /** 232 * \brief First AltSetting for the Interface 233 * 234 * This method returns a pointer to the first AltSetting 235 * for the Interface. 236 * 237 * See nextAltSetting() for an example of how it might be 238 * used. 239 * 240 * \see nextAltSetting(), lastAltSetting(), numAltSettings() 241 */ 242 AltSetting *firstAltSetting(void); 243 244 /** 245 * \brief Next AltSetting for the Interface 246 * 247 * This method returns a pointer to the next AltSetting 248 * for the Interface. 249 * 250 * If you want to iterate through each AltSetting on 251 * a device, you can use something like the following: 252 * \code 253 * USB::Configuration *this_Configuration; 254 * this_Configuration = device->firstConfiguration(); 255 * for (i=0; i < device->numConfigurations(); i++) { 256 * this_Configuration->dumpDescriptor(); 257 * USB::Interface *this_Interface; 258 * this_Interface = this_Configuration->firstInterface(); 259 * for (j=0; j < this_Configuration->numInterfaces(); j++) { 260 * USB::AltSetting *this_AltSetting; 261 * this_AltSetting = this_Interface->firstAltSetting(); 262 * for (k=0; k < this_Interface->numAltSettings(); k++) { 263 * // do something with this_AltSetting 264 * this_AltSetting = this_Interface->nextAltSetting(); 265 * } 266 * this_Interface = this_Configuration->nextInterface(); 267 * } 268 * this_Configuration = device->nextConfiguration(); 269 * } 270 * \endcode 271 * 272 * \see firstAltSetting(), lastAltSetting(), numAltSettings() 273 */ 274 AltSetting *nextAltSetting(void); 275 276 /** 277 * \brief Last AltSetting for the Interface 278 * 279 * This method returns a pointer to the last AltSetting 280 * for the Interface. 281 * 282 * \see firstAltSetting(), nextAltSetting(), numAltSettings() 283 */ 284 285 AltSetting *lastAltSetting(void); 286 287 private: 288 std::list<AltSetting *>::const_iterator iter; 289 290 void setNumAltSettings(u_int8_t); 291 void setParent(Device *parent); 292 u_int8_t m_numAltSettings; 293 Device *m_parent; 294 295 /* index representing the interface, in this configuration */ 296 int m_interfaceNumber; 297 void setInterfaceNumber(int interfaceNumber); 298 }; 299 300 /** 301 * \brief Class representing a configuration of a Device 302 * 303 * The Configuration class represents a single configuration 304 * of a device attached to a Universal Serial Bus. 305 * 306 * \author Brad Hards 307 */ 308 class Configuration : public std::list<Interface *> { 309 /** 310 * Busses is a friend because it fills in the descriptor type 311 * information on initialisation and rescan. 312 */ 313 friend class Busses; 314 public: 315 Configuration() {}; 316 317 /** 318 * \brief Configuration descriptor information output 319 * 320 * This method dumps out the various characteristics 321 * of the configuration to standard output. 322 * 323 * It is mostly useful for debugging. 324 */ 325 void dumpDescriptor(void); 326 327 /** 328 * \brief Number of Interfaces that this device has 329 * 330 * This is a simple accessor method that specifies the number 331 * Interfaces that this device configuration has. 332 */ 333 u_int8_t numInterfaces(void); 334 335 /** 336 * \brief First Interface for the Configuration 337 * 338 * This method returns a pointer to the first Interface 339 * for the Configuration. 340 * 341 * See nextInterface() for an example of how it might be 342 * used. 343 * 344 * \see nextInterface(), lastInterface(), numInterfaces() 345 */ 346 Interface *firstInterface(void); 347 348 /** 349 * \brief Next Interface for the Configuration 350 * 351 * This method returns a pointer to the next Interface 352 * for the Configuration. 353 * 354 * If you want to iterate through each Interface on 355 * a device, you can use something like the following: 356 * \code 357 * USB::Configuration *this_Configuration; 358 * this_Configuration = device->firstConfiguration(); 359 * for (i=0; i < device->numConfigurations(); i++) { 360 * this_Interface = this_Configuration->firstInterface(); 361 * for (j=0; j < this_Configuration->numInterfaces(); j++) { 362 * // do something with this_Interface 363 * this_Interface = this_Configuration->nextInterface(); 364 * } 365 * this_Configuration->nextConfiguration(); 366 * } 367 * \endcode 368 * 369 * \see firstInterface(), lastInterface(), numInterfaces() 370 */ 371 Interface *nextInterface(void); 372 373 /** 374 * \brief Last Interface for the Configuration 375 * 376 * This method returns a pointer to the last Interface 377 * for the Configuration. 378 * 379 * \see firstInterface(), nextInterface(), numInterfaces() 380 */ 381 Interface *lastInterface(void); 382 383 private: 384 std::list<Interface *>::const_iterator iter; 385 386 void setDescriptor(struct usb_config_descriptor); 387 /* we don't use a normal usb_config_descriptor */ 388 /* because that would bring in the interface list */ 389 u_int8_t m_Length; 390 u_int8_t m_DescriptorType; 391 u_int16_t m_TotalLength; 392 u_int8_t m_NumInterfaces; 393 u_int8_t m_ConfigurationValue; 394 u_int8_t m_Configuration; 395 u_int8_t m_Attributes; 396 u_int8_t m_MaxPower; 397 }; 398 399 /** 400 * \brief Class representing a Device on the Bus 401 * 402 * The Device class represents a single device 403 * attached to a Universal Serial Bus. 404 * 405 * \author Brad Hards 406 */ 407 class Device : public std::list<Configuration *> { 408 /** 409 * Busses is a friend because it fills in the descriptor type 410 * information on initialisation and rescan. 411 */ 412 friend class Busses; 413 /** 414 * Interface is a friend because it needs the handle() function to 415 * perform claim(), release(). 416 */ 417 friend class Interface; 418 /** 419 * Endpoint is a friend because it needs the handle() function to 420 * perform reads, writes, and other transactions. 421 */ 422 friend class Endpoint; 423 424 public: 425 Device() {}; 426 ~Device(); 427 428 /** 429 * \brief OS representation of filename for this device 430 * 431 * libusb++ provides a uniform way of accessing USB 432 * devices irrespective of the underlying Operation System 433 * representation. If you want to map the libusb++ representation 434 * to the Operating System representation, you can do this 435 * with filename(). 436 * 437 * On Linux, the filename is usually something like 002, which 438 * represents the second device (usually the first real device, 439 * after the root hub pseudo-device) on the bus. 440 * 441 * \see Bus::directoryName() 442 */ 443 std::string fileName(void); 444 445 /** 446 * \brief The vendor ID number, as provided by the device. 447 * 448 * This method returns a number containing the vendor 449 * (manufacturer) identification number. These are allocated 450 * by the USB Implementers Forum, and you can construct a 451 * lookup based on the number to get the manufacturer's name, 452 * even if the device does not contain a vendor string. 453 * 454 * \see Vendor() 455 */ 456 u_int16_t idVendor(void); 457 458 /** 459 * \brief The product ID number, as provided by the device. 460 * 461 * This method returns a number containing the product 462 * identification number. These are allocated 463 * by the manufacturer, and should be different on each device. 464 * 465 * \see Product() 466 */ 467 u_int16_t idProduct(void); 468 469 /** 470 * \brief The product's revision ID, as provided by the device. 471 * 472 * This method returns a number containing the product's revision. 473 * This revision level is nominally binary coded decimal, but 474 * hexadecimal revision levels are not uncommon. The binary coded 475 * decimal version nominally has a major version in the high byte, 476 * and a minor version in the low byte. 477 */ 478 u_int16_t idRevision(void); 479 480 /** 481 * \brief The device's USB class, as provided by the device. 482 * 483 * This method returns a number containing the device's class. 484 * These are defined by the USB Implementer's Forum. 485 * 486 * A code of Zero is special (and common) - it means that the 487 * class is found in the Interface descriptor, rather than in the 488 * Device descriptor. 489 * 490 * A code of 0xFF is also special (and far too common) - it means 491 * that the manufacturer didn't conform to one of the defined 492 * class specifications, and chose to implement a vendor specified 493 * protocol. 494 * 495 */ 496 u_int8_t devClass(void); 497 498 /** 499 * \brief The device's USB subclass, as provided by the device. 500 * 501 * This method returns a number containing the device's subclass. 502 * These subclasses are defined by the USB Implementer's Forum, 503 * and only have meaning in the context of a specified class. 504 */ 505 u_int8_t devSubClass(void); 506 507 /** 508 * \brief The device's USB protocol, as provided by the device. 509 * 510 * This method returns a number containing the device's protocol. 511 * These protocols are defined by the USB Implementer's Forum, and 512 * only have meaning in the context of a specified class and 513 * subclass. 514 */ 515 u_int8_t devProtocol(void); 516 517 518 /** 519 * \brief The vendor name string, as provided by the device. 520 * 521 * This method returns a string containing the name of the 522 * device's vendor (manufacturer), as encoded into the device. 523 * 524 * Note that not all devices contain a vendor name, and also 525 * that under some operating systems you may not be able to 526 * read the vendor name without elevated privledges (typically 527 * root privledges). 528 * 529 * \see idVendor() 530 **/ 531 std::string Vendor(void); 532 533 /** 534 * \brief The product name string, as provided by the device. 535 * 536 * This method returns a string containing the name of the 537 * device's product name, as encoded into the device. 538 * 539 * Note that not all devices contain a product name, and also 540 * that under some operating systems you may not be able to 541 * read the vendor name without elevated privledges (typically 542 * root privledges). 543 * 544 * \see idProduct() 545 **/ 546 std::string Product(void); 547 548 /** 549 * \brief The serial number string, as provided by the device. 550 * 551 * This method returns a string containing a serial number for 552 * the device, as encoded into the device. 553 * 554 * Note that few devices contain a serial number string, and also 555 * that under some operating systems you may not be able to 556 * read the serial number without elevated privledges (typically 557 * root privledges). The USB specification requires that serial 558 * numbers are unique if they are provided, but adherence to this 559 * requirement by manufacturers is not universal. 560 **/ 561 std::string SerialNumber(void); 562 563 /** 564 * \brief Number of Configurations that this device has 565 * 566 * This is a simple accessor method that specifies the number 567 * configurations that this device has. 568 */ 569 u_int8_t numConfigurations(void); 570 571 /** 572 * \brief fetch an arbitrary string from the device 573 * 574 * \param string the string from the device. You can typically 575 * pass in an empty string for this. 576 * \param index the index of the string required 577 * \param lang the language ID to use. Defaults to using the 578 * first language ID. 579 * 580 * \return length of string, or 0 on error. 581 */ 582 int string(std::string &buf, int index, u_int16_t lang=0); 583 584 /** 585 * \brief First Configuration for the Device 586 * 587 * This method returns a pointer to the first Configuration 588 * for the Device. 589 * 590 * See nextConfiguration() for an example of how it might be 591 * used. 592 */ 593 Configuration *firstConfiguration(void); 594 595 /** 596 * \brief Next Configuration for the Device 597 * 598 * This method returns a pointer to the next Configuration 599 * for the Device. 600 * 601 * If you want to iterate through each Configuration on 602 * a device, you can use something like the following: 603 * \code 604 * USB::Configuration *this_Configuration; 605 * this_Configuration = device->firstConfiguration(); 606 * for (i=0; i < device->numConfigurations(); i++) { 607 * // do something with this_Configuration 608 * this_Configuration->nextConfiguration(); 609 * } 610 * \endcode 611 */ 612 Configuration *nextConfiguration(void); 613 614 /** 615 * \brief Last Configuration for the Device 616 * 617 * This method returns a pointer to the last Configuration 618 * for the Device. 619 * 620 */ 621 Configuration *lastConfiguration(void); 622 623 /** 624 * \brief USB control transfer 625 * 626 * This method performs a standard control transfer to the default 627 * endpoint. See the USB specification for more details on this. 628 * 629 * \param requestType corresponds to the bmRequestType field 630 * in the transfer 631 * \param request corresponds to the bRequest field in the 632 * transfer 633 * \param value corresponds to the wValue field in the transfer 634 * \param index corresponds to the wIndex field in the transfer 635 * \param length corresponds to the wLength field in the transfer 636 * \param payload corresponds to the data phase of a control 637 * transfer 638 * \param timeout is the timeout period for the control transfer, 639 * in milliseconds 640 * 641 * \return number of bytes sent or received, or a negative number 642 * in case of error. 643 */ 644 int controlTransfer(u_int8_t requestType, u_int8_t request, 645 u_int16_t value, u_int16_t index, u_int16_t length, 646 unsigned char *payload, 647 int timeout = 100); 648 649#ifdef USE_UNTESTED_LIBUSBPP_METHODS 650 /** 651 * \brief USB device reset 652 * 653 * This method performs a device reset - see USB Specification 654 * 9.1 for how this changes the device state to the Default state. 655 * 656 * \return 0 on success, or a negative number in case of error. 657 */ 658 int reset(void); 659 660 /** 661 * \brief Set device configuration 662 * 663 * This method sets the device to a particular Configuration. 664 * 665 * \param configurationNumber the configuration that the device 666 * should be changed to. 667 * 668 * \return 0 on success, or a negative number in case of error. 669 */ 670 int setConfiguration(int configurationNumber); 671#endif /* USE_UNTESTED_LIBUSBPP_METHODS */ 672 673 private: 674 std::list<Configuration *>::const_iterator iter; 675 676 struct usb_dev_handle *handle(); 677 void setFileName(std::string); 678 void setDescriptor(struct usb_device_descriptor); 679 void setVendor(std::string); 680 void setProduct(std::string); 681 void setSerialNumber(std::string); 682 void setDevHandle(struct usb_dev_handle *); 683 std::string m_fileName; 684 std::string m_Vendor; 685 std::string m_Product; 686 std::string m_SerialNumber; 687 struct usb_device *m_dev; 688 struct usb_dev_handle *m_handle; 689 struct usb_device_descriptor m_descriptor; 690 }; 691 692 /** 693 * \brief Class representing a single bus on the machine 694 * 695 * This class is essentially a list of Device class instances 696 */ 697 class Bus : public std::list<Device *> { 698 /** 699 * Busses is a friend because it fills in the directory name 700 * information on initialisation and rescan. 701 */ 702 friend class Busses; 703 public: 704 Bus() {}; 705 /** 706 * \brief OS representation of directory name for this Bus 707 * 708 * libusb++ provides a uniform way of accessing USB 709 * busses irrespective of the underlying Operation System 710 * representation. If you want to map the libusb++ representation 711 * to the Operating System representation, you can do this 712 * with directory name(). 713 * 714 * On Linux, the directoryname is usually something like 003, which 715 * represents the third bus on the host. 716 * 717 * \see Directory::filename() 718 */ 719 std::string directoryName(void); 720 private: 721 std::list<Device *>::const_iterator iter; 722 723 void setDirectoryName(std::string); 724 std::string m_directoryName; 725 }; 726 727 /** 728 * \brief A vendor/product ID pair 729 * 730 * DeviceID provides a list of (vendor, product) identification 731 * pairs. It is intended for use in a list of device numbers to 732 * search for, but there is no reason why it couldn't be used for a 733 * general purpose (vendor,product) tuple if you had some reason for 734 * this. 735 * 736 * The description for Busses::match() provides an example of how 737 * this class might be used. 738 * 739 * \see DeviceIDList, Busses::match() 740 */ 741 class DeviceID { 742 public: 743 DeviceID() {}; 744 /** 745 * \brief Standard constructor 746 * 747 * This constructor takes (vendor, product) tuple, which are 748 * stored away. 749 * 750 * \param vendor the 16 bit vendor number for the device 751 * \param product the 16 bit product number for the device 752 */ 753 DeviceID(u_int16_t vendor, u_int16_t product); 754 755 /** 756 * \brief vendor number for the device 757 * 758 * This method returns the 16 bit vendor number. 759 */ 760 u_int16_t vendor(void); 761 762 /** 763 * \brief product number for the device 764 * 765 * This method returns the 16 bit product number. 766 */ 767 u_int16_t product(void); 768 769 private: 770 u_int16_t m_vendor; 771 u_int16_t m_product; 772 }; 773 774 /** 775 * \brief A list of vendor/product pairs 776 * 777 * DeviceIDList provides a list of DeviceID classes, which is 778 * essentially a list of (vendor, product) identification pairs. 779 * 780 * \see DeviceID 781 */ 782 typedef std::list<DeviceID> DeviceIDList; 783 784 /** 785 * \brief Class representing all the busses on the machine 786 * 787 * This class is essentially a list of Bus class instances 788 */ 789 class Busses : public std::list<Bus *> { 790 public: 791 Busses(); 792 793 /** 794 * \brief Update method 795 * 796 * This method can be called to rescan the various devices 797 * attached to the various busses. You should use it to 798 * update if things change. Unfortunately there is no 799 * way to automatically detect this change in a portable way, 800 * so worst case is that you need to call this using some 801 * kind of timer in the background. 802 */ 803 void rescan(void); 804 805 /** 806 * \brief find all devices with matching device class designator 807 * 808 * This method searches every device on every bus, and returns a 809 * list of pointers to the devices that have a matching device 810 * class code 811 */ 812 std::list<Device *> match(u_int8_t Class); 813 814 /** 815 * \brief find all devices with matching device IDs 816 * 817 * This method searches every device on every bus, and returns a 818 * list of pointers to the devices that have a matching device 819 * ID. That is, if the (vendor, product) tuple of a device matches 820 * one of the tuples on the list, then the device will be added to 821 * the list of matches. 822 * 823 * An example of usage is shown below: 824 * \code 825 * USB::Busses buslist; 826 * USB::Device *device; 827 * std::list<USB::Device> miceFound; 828 * USB::DeviceIDList mouseList; 829 * 830 * mouseList.append(USB::DeviceID(VENDOR_LOGITECH, 0xC00E)); // Wheel Mouse Optical 831 * mouseList.append(USB::DeviceID(VENDOR_LOGITECH, 0xC012)); // MouseMan Dual Optical 832 * mouseList.append(USB::DeviceID(VENDOR_LOGITECH, 0xC506)); // MX700 Optical Mouse 833 * 834 * miceFound = buslist.match(mouseList); 835 * 836 * for ( device = miceFound.first(); device; device = miceFound.next() ) { 837 * // do something with each mouse that matched 838 * } 839 * FIXME: This is incorrect now 840 * \endcode 841 */ 842 std::list<Device *> match(DeviceIDList); 843 844 private: 845 std::list<Bus *>::const_iterator iter; 846 }; 847 848 class Error { 849 public: 850 private: 851 }; 852 853} 854#endif /* __USBPP_HEADER__ */ 855 856