peripherals  1.4.2
RoadNarrows Robotics Hardware Peripherals Package
HIDXbox360.cxx
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////////////
2 //
3 // Package: RoadNarrows Robotics Peripherals
4 //
5 // Library: libhid
6 //
7 // File: HIDXbox360.cxx
8 //
9 /*! \file
10  *
11  * $LastChangedDate: 2014-03-05 16:20:41 -0700 (Wed, 05 Mar 2014) $
12  * $Rev: 3591 $
13  *
14  * \brief Xbox360 Controller C implementation.
15  *
16  * \author Rob Shiely (rob.knight@roadnarrows.com)
17  * \author Daniel Packard (daniel@roadnarrows.com)
18  * \author Robin Knight (robin.knight@roadnarrows.com)
19  *
20  * \copyright
21  * \h_copy 2012-2017. RoadNarrows LLC.\n
22  * http://www.roadnarrows.com\n
23  * All Rights Reserved
24  */
25 // Permission is hereby granted, without written agreement and without
26 // license or royalty fees, to use, copy, modify, and distribute this
27 // software and its documentation for any purpose, provided that
28 // (1) The above copyright notice and the following two paragraphs
29 // appear in all copies of the source code and (2) redistributions
30 // including binaries reproduces these notices in the supporting
31 // documentation. Substantial modifications to this software may be
32 // copyrighted by their authors and need not follow the licensing terms
33 // described here, provided that the new terms are clearly indicated in
34 // all files where they apply.
35 //
36 // IN NO EVENT SHALL THE AUTHOR, ROADNARROWS LLC, OR ANY MEMBERS/EMPLOYEES
37 // OF ROADNARROW LLC OR DISTRIBUTORS OF THIS SOFTWARE BE LIABLE TO ANY
38 // PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
39 // DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION,
40 // EVEN IF THE AUTHORS OR ANY OF THE ABOVE PARTIES HAVE BEEN ADVISED OF
41 // THE POSSIBILITY OF SUCH DAMAGE.
42 //
43 // THE AUTHOR AND ROADNARROWS LLC SPECIFICALLY DISCLAIM ANY WARRANTIES,
44 // INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
45 // FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN
46 // "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO
47 // PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
48 //
49 ////////////////////////////////////////////////////////////////////////////////
50 
51 
52 #include <sys/types.h>
53 #include <sys/stat.h>
54 #include <sys/time.h>
55 #include <stdio.h>
56 #include <unistd.h>
57 #include <stdlib.h>
58 #include <string.h>
59 #include <pthread.h>
60 
61 #include <limits>
62 #include <string>
63 #include <map>
64 
65 #include <libusb-1.0/libusb.h>
66 
67 #include "rnr/rnrconfig.h"
68 #include "rnr/log.h"
69 #include "rnr/usbext.h"
70 #include "rnr/hid/HIDXbox360.h"
71 
72 using namespace std;
73 using namespace rnr;
74 
75 
76 // -----------------------------------------------------------------------------
77 // Public Interface
78 // -----------------------------------------------------------------------------
79 
80 HIDXbox360::HIDXbox360(int usbDebugLevel) : HIDInput(HIDClassXbox360)
81 {
82  int i;
83 
84  //
85  // HID state
86  //
88  m_nBatteryStatus = 0;
89  m_nStatus = 0;
90  m_nOffset = 0;
91 
93 
94  zeroState();
95 
97  m_nLeftRumble = 0;
98  m_nRightRumble = 0;
99 
101  {
102  m_featMap[i] = i;
103  }
104 
105  // set error thresholds defaults and clear error counts
107  clearErrorCnts();
108 
109  //
110  // USB data
111  //
112  m_usbContext = NULL;
113  m_usbHandle = NULL;
114 
115  for(i=0; i<UsbPktIdNumOf; ++i)
116  {
117  m_usbPkt[i].m_usbTransfer = NULL;
118  m_usbPkt[i].m_bHasSubmitted = false;
119  m_usbPkt[i].m_bCancel = false;
120  }
121 
122  pthread_mutex_init(&m_mutexUpdate, NULL);
123  pthread_cond_init(&m_condUpdate, NULL);
125 
126  // initialize the libusb library, setting context
127  if( m_nError = libusb_init(&m_usbContext) != LIBUSB_SUCCESS )
128  {
129  LOGERROR("libusb_init() failed: %s.", libusb_error_name(m_nError));
130  m_usbContext = NULL;
131  m_bFatal = true;
132  }
133 
134  // set debug level
135  else
136  {
137  libusb_set_debug(m_usbContext, usbDebugLevel);
138  }
139 }
140 
142 {
143  if( m_bIsConnected )
144  {
145  close();
146  }
147 
148  pthread_cond_destroy(&m_condUpdate);
149  pthread_mutex_destroy(&m_mutexUpdate);
150 
151  // exit libusb
152  if( m_usbContext != NULL )
153  {
154  libusb_exit(m_usbContext);
155  m_usbContext = NULL;
156  }
157 }
158 
160 {
161  // in fatal condition and/or libusb not initialzed
162  if( m_bFatal || (m_usbContext == NULL) )
163  {
164  LOGERROR("libusb not initialized.");
165  }
166 
167  // Xbox USB device alread open
168  else if( m_usbHandle != NULL )
169  {
170  LOGERROR("Xbox360 controller 0x%04x already open.", m_nProdId);
171  m_nError = LIBUSB_ERROR_IO;
172  }
173 
174  // failed to open Xbox
175  else if( (m_nError = openXbox()) < 0 )
176  {
177  LOGERROR("open() failed: %s.", libusb_error_name(m_nError));
178  }
179 
180  // failed to allocate and initialize USB transfer packets
181  else if( (m_nError = initTransferPkts()) < 0 )
182  {
183  LOGERROR("initTransferPkts() failed: %s.", libusb_error_name(m_nError));
184  close();
185  }
186 
187  // failed to start async read transfer
188  else if( (m_nError = submitReadTransfer()) < 0 )
189  {
190  LOGERROR("submitReadTransfer() failed: %s.", libusb_error_name(m_nError));
191  close();
192  }
193 
194  // success
195  else
196  {
197  clearErrorCnts();
198  zeroState();
199 
201  m_nLeftRumble = 0;
202  m_nRightRumble = 0;
203 
204  setConnectionState(true);
205 
206  flushInput();
207 
208  switch( m_nProdId )
209  {
211  m_strProdName = "Xbox360 Wired Controller";
212  setLinkState(true);
213  break;
215  case XBOX360_WIRELESS_WIN_PROD_ID:
216  m_strProdName = "Xbox360 Wireless Controller";
217  break;
218  default:
219  m_strProdName = "Xbox360 Controller";
220  break;
221  }
222 
223  LOGDIAG3("Opened %s (product id=0x%04x).",
224  m_strProdName.c_str(), m_nProdId);
225  }
226 
227  return m_nError;
228 }
229 
231 {
232  // in fatal condition and/or libusb not initialzed
233  if( m_bFatal || (m_usbContext == NULL) )
234  {
235  LOGERROR("libusb not initialized.");
236  return m_nError;
237  }
238 
239  //
240  // Close
241  //
242  if( m_usbHandle != NULL )
243  {
244  // put Xbox in a good state
245  if( (m_state[Xbox360FeatIdLeftRumble] != 0) ||
247  {
248  //setRumble(0, 0);
249  //usleep(10000);
250  }
251 
252  // stop update thread
253  stop();
254 
255  // cancel any pending transfers
256  cancelTransfers();
257 
258  // free all transfer packet memory
260 
261  libusb_reset_device(m_usbHandle);
262 
263  // release claimed interfaces
264  for(int i=0; i<XBOX360_NUM_OF_INTERFACES; ++i)
265  {
266  if( (m_nError = libusb_release_interface(m_usbHandle, i)) < 0 )
267  {
268  LOGWARN("libusb_release_interface() failed: %s.",
269  libusb_error_name(m_nError));
270  }
271  }
272 
273  // close USB opened device
274  libusb_close(m_usbHandle);
275 
276  LOGDIAG3("Closed Xbox360 controller (product id=0x%04x).", m_nProdId);
277  }
278 
279  // zap state
280  zeroState();
281  m_usbHandle = NULL;
282  setConnectionState(false);
283  setLinkState(false);
285  m_strProdName.clear();
286  m_strSerialNum.clear();
287  m_nStatus = 0;
288 
289  return LIBUSB_SUCCESS;
290 }
291 
292 int HIDXbox360::run(float hz)
293 {
294  if( hz <= 0.0 )
295  {
296  hz = 1.0;
297  }
298 
299  float t = 1.0/hz;
300 
301  m_tsThread.tv_sec = (long)t;
302  m_tsThread.tv_nsec = (long)(t - m_tsThread.tv_sec);
303 
305  {
306  LOGERROR("Update thread already running.");
307  return -1;
308  }
309 
310  else if( createUpdateThread() < 0 )
311  {
312  LOGERROR("Failed to create update thread.");
313  return -1;
314  }
315 
316  else
317  {
318  return 0;
319  }
320 }
321 
323 {
325  unlock();
327 
328  return 0;
329 }
330 
331 int HIDXbox360::setFeatureVal(int iMnem, int nVal)
332 {
333  FeatMap_T::iterator pos;
334 
335  if( (pos = m_featMap.find(iMnem)) == m_featMap.end() )
336  {
337  return LIBUSB_ERROR_INVALID_PARAM;
338  }
339 
340  switch( pos->second )
341  {
344  case Xbox360FeatIdRightRumble:
346  case Xbox360FeatIdLEDPat:
347  return setLED(nVal);
348  default:
349  return LIBUSB_ERROR_INVALID_PARAM;
350  }
351 }
352 
354  HIDFeatType &eFeatType,
355  int &nDir,
356  int &nMin,
357  int &nMax,
358  int &nStep)
359 {
360  FeatMap_T::iterator pos;
361 
362  if( (pos = m_featMap.find(iMnem)) == m_featMap.end() )
363  {
364  return LIBUSB_ERROR_INVALID_PARAM;
365  }
366 
367  switch( pos->second )
368  {
373  eFeatType = HIDFeatTypeRange;
374  nDir = HID_FEAT_INPUT;
375  nMin = numeric_limits<int16_t>::min();
376  nMax = numeric_limits<int16_t>::max();
377  nStep = 1;
378  break;
381  eFeatType = HIDFeatTypeRange;
382  nDir = HID_FEAT_INPUT;
383  nMin = 0;
384  nMax = numeric_limits<int8_t>::max();
385  nStep = 1;
386  break;
389  eFeatType = HIDFeatTypeRange;
390  nDir = HID_FEAT_OUTPUT;
391  nMin = 0;
392  nMax = numeric_limits<int8_t>::max();
393  nStep = 1;
394  break;
395  case Xbox360FeatIdLEDPat:
396  eFeatType = HIDFeatTypeEnum;
400  nStep = 1;
401  break;
402  default:
403  eFeatType = HIDFeatTypeBiState;
404  nDir = HID_FEAT_INPUT;
405  nMin = HID_BTTN_UP;
406  nMax = HID_BTTN_DOWN;
407  nStep = 1;
408  break;
409  }
410 
411  return LIBUSB_SUCCESS;
412 }
413 
415 {
416  // N.B. ping is unreliable - simply return link state
417  return m_bIsLinked;
418 }
419 
421 {
422  byte_t *p;
423  size_t n;
424  int rc;
425 
426  //
427  // Request already pending.
428  //
429  if( m_usbPkt[UsbPktIdGoad].m_bHasSubmitted )
430  {
431  return;
432  }
433 
434  //
435  // Transfer is being canceled.
436  //
437  else if( m_usbPkt[UsbPktIdGoad].m_bCancel )
438  {
439  return;
440  }
441 
443 
444  //
445  // Use LED to prompt an Xbox360 response.
446  //
447  switch( m_nProdId )
448  {
450  case XBOX360_WIRELESS_WIN_PROD_ID:
452 
453  memset(p, 0, n);
454 
455  // header
457  p[1] = XBOX360_WL_LED_PAT_1;
458  p[2] = XBOX360_WL_LED_PAT_2;
460 
461  m_usbPkt[UsbPktIdGoad].m_usbTransfer->length = (int)n;
462  break;
463 
465  default:
467 
469  p[XBOX360_MSG_LEN_POS] = (byte_t)n;
471 
472  m_usbPkt[UsbPktIdGoad].m_usbTransfer->length = (int)n;
473  break;
474  }
475 
477 
478  rc = libusb_submit_transfer(m_usbPkt[UsbPktIdGoad].m_usbTransfer);
479 
480  switch( rc )
481  {
482  case LIBUSB_SUCCESS:
483  break;
484  default:
486  LOGERROR("Goad libusb_submit_transfer() failed: %s.",
487  libusb_error_name(rc));
488  break;
489  }
490 }
491 
492 int HIDXbox360::setRumble(int nLeftMot, int nRightMot)
493 {
494  byte_t *p;
495  size_t n;
496  int nMaxTries = 3;
497  int nTries;
498  int rc;
499 
500  // targets
503 
504  //
505  // No link.
506  //
507  if( !m_bIsLinked )
508  {
509  return LIBUSB_SUCCESS;
510  }
511 
512  //
513  // Transfer is being canceled.
514  //
515  else if( m_usbPkt[UsbPktIdRumble].m_bCancel )
516  {
517  return LIBUSB_SUCCESS;
518  }
519 
520  LOGDIAG4("Set rumble moters %d, %d.", m_nLeftRumble, m_nRightRumble);
521 
522  //
523  // Previous event to rumble change is pending.
524  //
525  for(nTries=0, rc=LIBUSB_ERROR_BUSY;
526  (nTries<nMaxTries) && (rc==LIBUSB_ERROR_BUSY);
527  ++nTries)
528  {
529  if( m_usbPkt[UsbPktIdRumble].m_bHasSubmitted )
530  {
531  usleep(10);
532  }
533  else
534  {
535  rc = LIBUSB_SUCCESS;
536  }
537  }
538 
539  //
540  // Last request failed. It may have been lost. Fail this request, but
541  // reset to re-enable.
542  //
543  if( rc != LIBUSB_SUCCESS )
544  {
545  LOGERROR("Rumble libusb_submit_transfer() failed in %d tries: %s.",
546  nTries, libusb_error_name(rc));
548  m_nErrorSend++;
549  m_nErrorTotal++;
550  m_nError = rc;
551  return rc;
552  }
553 
554  //
555  // Write new rumble request.
556  //
558 
559  switch( m_nProdId )
560  {
561  //
562  // From xboxdrv-linux-0.8.5, rumble command =
563  // 0x00, 0x01, 0x0f, 0xc0, 0x00, left, right, 0x00, 0x00, 0x00, 0x00, 0x00
564  //
566  case XBOX360_WIRELESS_WIN_PROD_ID:
568 
569  memset(p, 0, n);
570 
571  // header
576 
577 
578  // message
580  p[5] = (byte_t)m_nLeftRumble;
581  p[6] = (byte_t)m_nRightRumble;
582 
583  m_usbPkt[UsbPktIdRumble].m_usbTransfer->length = (int)n;
584  break;
585 
587  default:
589 
590  memset(p, 0, n);
591 
592  // message
594  p[XBOX360_MSG_LEN_POS] = (byte_t)n;
595  p[XBOX360_RUMBLE_LEFT_POS] = (byte_t)nLeftMot;
596  p[XBOX360_RUMBLE_RIGHT_POS] = (byte_t)nRightMot;
597 
598  m_usbPkt[UsbPktIdRumble].m_usbTransfer->length = (int)n;
599  break;
600  }
601 
603 
604  rc = libusb_submit_transfer(m_usbPkt[UsbPktIdRumble].m_usbTransfer);
605 
606  switch( rc )
607  {
608  case LIBUSB_SUCCESS:
609  break;
610  default:
611  LOGERROR("Rumble libusb_submit_transfer() failed: %s.",
612  libusb_error_name(rc));
614  m_nErrorSend++;
615  m_nErrorTotal++;
616  m_nError = rc;
617  break;
618  }
619 
620  return rc;
621 }
622 
623 int HIDXbox360::setLED(int nPattern)
624 {
625  byte_t *p;
626  size_t n;
627  int nMaxTries = 3;
628  int nTries;
629  int rc;
630 
631  // target
632  m_nLEDPattern = nPattern & XBOX360_LED_PAT_MASK;
633 
634  //
635  // No link.
636  //
637  if( !m_bIsLinked )
638  {
639  return LIBUSB_SUCCESS;
640  }
641 
642  //
643  // Transfer is being canceled.
644  //
645  else if( m_usbPkt[UsbPktIdLED].m_bCancel )
646  {
647  return LIBUSB_SUCCESS;
648  }
649 
650  LOGDIAG4("Set LED pattern %d.", m_nLEDPattern);
651 
652  //
653  // Previous event to LED state change is pending.
654  //
655  for(nTries=0, rc=LIBUSB_ERROR_BUSY;
656  (nTries<nMaxTries) && (rc==LIBUSB_ERROR_BUSY);
657  ++nTries)
658  {
659  if( m_usbPkt[UsbPktIdLED].m_bHasSubmitted )
660  {
661  usleep(10);
662  }
663  else
664  {
665  rc = LIBUSB_SUCCESS;
666  }
667  }
668 
669 
670  //
671  // Last request failed. It may have been lost. Fail this request, but
672  // reset to re-enable.
673  //
674  if( rc != LIBUSB_SUCCESS )
675  {
676  LOGERROR("LED libusb_submit_transfer() failed in %d tries: %s.",
677  nTries, libusb_error_name(rc));
679  m_nErrorSend++;
680  m_nErrorTotal++;
681  m_nError = rc;
682  return rc;
683  }
684 
685 
686  //
687  // Write new LED pattern request.
688  //
690 
691  switch( m_nProdId )
692  {
694  case XBOX360_WIRELESS_WIN_PROD_ID:
696 
697  memset(p, 0, n);
698 
699  // header
701  p[1] = XBOX360_WL_LED_PAT_1;
702  p[2] = XBOX360_WL_LED_PAT_2;
704 
705  m_usbPkt[UsbPktIdLED].m_usbTransfer->length = (int)n;
706  break;
707 
709  default:
711 
713  p[XBOX360_MSG_LEN_POS] = (byte_t)n;
714  p[XBOX360_LED_PAT_POS] = (byte_t)m_nLEDPattern & XBOX360_LED_PAT_MASK;
715 
716  m_usbPkt[UsbPktIdLED].m_usbTransfer->length = (int)n;
717  break;
718  }
719 
721 
722  rc = libusb_submit_transfer(m_usbPkt[UsbPktIdLED].m_usbTransfer);
723 
724  switch( rc )
725  {
726  case LIBUSB_SUCCESS:
727  break;
728  default:
729  LOGERROR("LED libusb_submit_transfer() failed: %s.",
730  libusb_error_name(rc));
732  m_nErrorSend++;
733  m_nErrorTotal++;
734  m_nError = rc;
735  break;
736  }
737 
738  return rc;
739 }
740 
741 void HIDXbox360::calibrateJoySticks(int nLeftDeadZone, int nRightDeadZone)
742 {
743  float fMax = (float)numeric_limits<int16_t>::max();
744 
745  m_nLeftJoyDeadZone = nLeftDeadZone;
746  m_fLeftJoyM = fMax / (float)(fMax - m_nLeftJoyDeadZone);
748 
749  m_nRightJoyDeadZone = nRightDeadZone;
750  m_fRightJoyM = (float)fMax / (float)(fMax - m_nRightJoyDeadZone);
752 }
753 
754 
755 // -----------------------------------------------------------------------------
756 // Protected Interface
757 // -----------------------------------------------------------------------------
758 
759 void HIDXbox360::setLinkState(bool bNewState)
760 {
761  bool bOldState = m_bIsLinked;
762 
763  HIDInput::setLinkState(bNewState);
764 
765  //
766  // Transition from not linked to linked.
767  //
768  if( !bOldState && bNewState )
769  {
770  // reset LED pattern since the xbox may have gone to a 'not linked' pattern
772  }
773 
774  //
775  // Transition from linked to not linked.
776  //
777  else if( bOldState && !bNewState )
778  {
779  zeroState();
780  }
781 }
782 
784 {
785  // Xbox product id's in priority search order
786  static ushort_t xbox_prod_id[] =
787  {
791  XBOX360_WIRELESS_WIN_PROD_ID
792  };
793 
794  size_t i;
795  int rc;
796 
797  //
798  // Find an Xbox360 controller and claim its interfaces.
799  //
800  for(i=0; i<arraysize(xbox_prod_id); ++i)
801  {
802  // open by vendor id, product id
803  m_usbHandle = libusb_open_device_with_vid_pid(m_usbContext,
805  xbox_prod_id[i]);
806 
807  if( m_usbHandle != NULL )
808  {
809  m_nProdId = xbox_prod_id[i];
810 
811  if( (rc = claimXboxInterfaces()) < 0 )
812  {
813  close();
814  }
815  else
816  {
817  break;
818  }
819  }
820  }
821 
822  //
823  // Opened successfully
824  //
825  if( m_usbHandle != NULL )
826  {
827  // set specific Xbox360 product values
828  switch( m_nProdId )
829  {
831  case XBOX360_WIRELESS_WIN_PROD_ID:
833  break;
836  break;
838  default:
840  break;
841  }
842 
843  // reset the device to default state
844  libusb_reset_device(m_usbHandle);
845 
846  return LIBUSB_SUCCESS;
847  }
848 
849  //
850  // Failure
851  //
852  else
853  {
855  m_nError = LIBUSB_ERROR_NO_DEVICE;
856  }
857 
858  return m_nError;
859 }
860 
862 {
863  int i;
864  int status;
865  int interfaces = 0;
866 
867  interfaces = XBOX360_NUM_OF_INTERFACES;
868 
869  //
870  // RAS: Set all other interface values here
871  //
872 
873  //
874  // Detach any kernel drivers already attached to Xbox.
875  //
876  for(i=0; i<interfaces; ++i)
877  {
878  status = libusb_kernel_driver_active(m_usbHandle, i);
879 
880  // attached, so detach
881  if( status > 0 )
882  {
883  m_nError = libusb_detach_kernel_driver(m_usbHandle, i);
884  if( m_nError < 0 )
885  {
886  LOGERROR("libusb_detach_kernel_driver() failed: %s.",
887  libusb_error_name(m_nError));
888  return m_nError;
889  }
890  }
891  else if( status < 0 )
892  {
893  m_nError = status;
894  LOGERROR("libusb_kernel_driver_active() failed: %s.",
895  libusb_error_name(m_nError));
896  return m_nError;
897  }
898  }
899 
900  //
901  // Set active configuration for Xbox, performing light-weight reset if
902  // necessary.
903  //
904  if( (m_nProdId == XBOX360_WIRED_PROD_ID) ||
906  {
907  m_nError = libusb_set_configuration(m_usbHandle, 1);
908  if( m_nError < 0 )
909  {
910  LOGERROR("libusb_set_configuration() failed: %s.",
911  libusb_error_name(m_nError));
912  return m_nError;
913  }
914  }
915 
916  //
917  // Claim the Xbox interfaces.
918  //
919  for(i=0; i<interfaces; ++i)
920  {
921  m_nError = libusb_claim_interface(m_usbHandle, i);
922  if( m_nError < 0 )
923  {
924  LOGERROR("libusb_claim_interface() failed: %s.",
925  libusb_error_name(m_nError));
926  return m_nError;
927  }
928  }
929 
930  return LIBUSB_SUCCESS;
931 }
932 
934 {
935  for(int i=0; i<UsbPktIdNumOf; ++i)
936  {
937  // allocate a libusb transfer
938  m_usbPkt[i].m_usbTransfer = libusb_alloc_transfer(0);
939 
940  if( m_usbPkt[i].m_usbTransfer == NULL )
941  {
942  LOGERROR("libusb_alloc_transfer() failed.");
943  m_nError = LIBUSB_ERROR_OTHER;
944  return m_nError;
945  }
946 
947  //
948  // Populate transfer fields.
949  //
950  switch( i )
951  {
952  case UsbPktIdInput:
953  libusb_fill_interrupt_transfer(m_usbPkt[i].m_usbTransfer,
954  m_usbHandle,
956  m_usbPkt[i].m_bufData,
957  (int)sizeof(m_usbPkt[i].m_bufData),
959  this,
960  100); // timeout ms
961  break;
962  case UsbPktIdRumble:
963  libusb_fill_interrupt_transfer(m_usbPkt[i].m_usbTransfer,
964  m_usbHandle,
966  m_usbPkt[i].m_bufData,
967  (int)sizeof(m_usbPkt[i].m_bufData),
969  this,
970  0); // timeout ms
971  break;
972  case UsbPktIdLED:
973  libusb_fill_interrupt_transfer(m_usbPkt[i].m_usbTransfer,
974  m_usbHandle,
976  m_usbPkt[i].m_bufData,
977  (int)sizeof(m_usbPkt[i].m_bufData),
979  this,
980  0); // timeout ms
981  break;
982  case UsbPktIdGoad:
983  libusb_fill_interrupt_transfer(m_usbPkt[i].m_usbTransfer,
984  m_usbHandle,
986  m_usbPkt[i].m_bufData,
987  (int)sizeof(m_usbPkt[i].m_bufData),
989  this,
990  0); // timeout ms
991  break;
992  }
993 
994  m_usbPkt[i].m_bHasSubmitted = false;
995  m_usbPkt[i].m_bCancel = false;
996  }
997 }
998 
1000 {
1001  for(int i=0; i<UsbPktIdNumOf; ++i)
1002  {
1003  if( m_usbPkt[i].m_usbTransfer == NULL )
1004  {
1005  continue;
1006  }
1007  else if( m_usbPkt[i].m_bHasSubmitted )
1008  {
1009  LOGWARN("USB transfer packet %d has been submitted - cannot free.", i);
1010  }
1011  else
1012  {
1013  libusb_free_transfer(m_usbPkt[i].m_usbTransfer);
1014  m_usbPkt[i].m_usbTransfer = NULL;
1015  }
1016  }
1017 }
1018 
1020 {
1021  int rc;
1022 
1024 
1025  if( m_usbPkt[UsbPktIdInput].m_bCancel )
1026  {
1027  return LIBUSB_SUCCESS;
1028  }
1029 
1030  // set up transfer
1031  rc = libusb_submit_transfer(m_usbPkt[UsbPktIdInput].m_usbTransfer);
1032 
1033  if( rc == LIBUSB_SUCCESS )
1034  {
1036  }
1037  else
1038  {
1039  LOGERROR("Input libusb_submit_transfer() failed: %s.",
1040  libusb_error_name(rc));
1041  m_nError = rc;
1042  }
1043 
1044  return rc;
1045 }
1046 
1047 void HIDXbox360::transferCallbackInput(struct libusb_transfer *transfer)
1048 {
1049  HIDXbox360 *pThis = (HIDXbox360*)transfer->user_data;
1050  bool bResubmit = true;
1051  bool bReceived = false;
1052 
1053  //
1054  // USB transfer status.
1055  //
1056  switch( transfer->status )
1057  {
1058  //
1059  // Read transfer completed. Parse, validate, and set state according to the
1060  // received packet.
1061  //
1062  case LIBUSB_TRANSFER_COMPLETED:
1063  switch( pThis->m_nProdId )
1064  {
1066  case XBOX360_WIRELESS_WIN_PROD_ID:
1067  bReceived = pThis->parseWireless(transfer->buffer,
1068  transfer->actual_length);
1069  break;
1070  case XBOX360_WIRED_PROD_ID:
1071  default:
1072  bReceived = pThis->parseWired(transfer->buffer,
1073  transfer->actual_length);
1074  break;
1075  }
1076  break;
1077 
1078  //
1079  // USB transfer error.
1080  //
1081  case LIBUSB_TRANSFER_ERROR:
1082  LOGERROR("Transfer error.");
1083  pThis->m_nErrorRcv++;
1084  pThis->m_nErrorTotal++;
1085  break;
1086 
1087  //
1088  // No USB device. Probably unplugged.
1089  //
1090  case LIBUSB_TRANSFER_NO_DEVICE:
1091  LOGERROR("Disconnected!");
1092  pThis->m_nErrorRcv++;
1093  pThis->m_nErrorTotal++;
1094  pThis->setConnectionState(false);
1095  pThis->setLinkState(false);
1096  bResubmit = false;
1097  break;
1098 
1099  //
1100  // USB transfer timed out. This will happen when there are no new Xbox
1101  // events to report or when there is no link for the wireless Xbox.
1102  // Critical to differentiate these two conditions.
1103  //
1104  case LIBUSB_TRANSFER_TIMED_OUT:
1105  //LOGERROR("Receive Timeout!");
1106  if( pThis->isWireless() && pThis->m_bIsLinked )
1107  {
1108  pThis->m_nErrorRcvTimeout++;
1109  if( (pThis->m_nErrorRcvTimeout % 15) == 0 ) // too quiet - goad xbox
1110  {
1111  // RDK can't get this to work
1112  //pThis->goad();
1113  }
1114  }
1115  break;
1116 
1117  //
1118  // USB transfer is being canceled. Typical when closing the interface.
1119  //
1120  case LIBUSB_TRANSFER_CANCELLED:
1121  LOGDIAG3("Tranfer cancelled.");
1122  bResubmit = false;
1123  break;
1124 
1125  //
1126  // USB transfer stalled.
1127  //
1128  case LIBUSB_TRANSFER_STALL:
1129  LOGERROR("Transfer stalled.");
1130  pThis->m_nErrorRcv++;
1131  pThis->m_nErrorTotal++;
1132  break;
1133 
1134  //
1135  // USB transfer overflow. Typically the OS cannot handle the events soon
1136  // enough.
1137  //
1138  case LIBUSB_TRANSFER_OVERFLOW:
1139  LOGERROR("Overflow: Amount transferred: %d", transfer->actual_length);
1140  pThis->m_nErrorRcv++;
1141  pThis->m_nErrorTotal++;
1142  break;
1143 
1144  //
1145  // Should never be here.
1146  //
1147  default:
1148  LOGERROR("HIDXbox360 Controller: Unknown error, USB status: %d",
1149  transfer->status);
1150  pThis->m_nErrorRcv++;
1151  pThis->m_nErrorTotal++;
1152  break;
1153  }
1154 
1155  //
1156  // Received an input packet.
1157  //
1158  if( bReceived )
1159  {
1160  pThis->m_nErrorRcv = 0;
1161  pThis->m_nErrorRcvTimeout = 0;
1162  }
1163 
1164  //
1165  // No input packet received. Check error thresholds, which could result in
1166  // taking down the link.
1167  //
1168  else
1169  {
1170  pThis->checkErrorThresholds();
1171  }
1172 
1173  //
1174  // Resubmit new read transfer request.
1175  //
1176  if( bResubmit )
1177  {
1178  pThis->submitReadTransfer();
1179  }
1180 
1181  //
1182  // Don't resubmit new read transfer request.
1183  //
1184  else
1185  {
1186  pThis->m_usbPkt[UsbPktIdInput].m_bHasSubmitted = false;
1187  }
1188 }
1189 
1190 void HIDXbox360::transferCallbackRumble(struct libusb_transfer *transfer)
1191 {
1192  HIDXbox360 *pThis = (HIDXbox360*)transfer->user_data;
1193 
1194  pThis->m_usbPkt[UsbPktIdRumble].m_bHasSubmitted = false;
1195 
1196  //
1197  // USB transfer status.
1198  //
1199  switch( transfer->status )
1200  {
1201  //
1202  // Write transfer completed. The buffer just contains the data sent in the
1203  // write tranfer buffer. Not a true reply, but accept as successful.
1204  //
1205  case LIBUSB_TRANSFER_COMPLETED:
1208  pThis->m_nErrorSend = 0;
1209  //pThis->debugPrintTransferBuf("DBG: rumble cb", transfer);
1210  break;
1211 
1212  //
1213  // No USB device. Probably unplugged.
1214  //
1215  case LIBUSB_TRANSFER_NO_DEVICE:
1216  LOGERROR("Disconnected!");
1217  pThis->m_nErrorSend++;
1218  pThis->m_nErrorTotal++;
1219  pThis->setConnectionState(false);
1220  pThis->setLinkState(false);
1221  break;
1222 
1223  //
1224  // USB transfer is being canceled. Typical when closing the interface.
1225  //
1226  case LIBUSB_TRANSFER_CANCELLED:
1227  LOGDIAG3("Tranfer cancelled.");
1228  break;
1229 
1230  //
1231  // USB transfer timed out. Write did not succeed in this case.
1232  //
1233  case LIBUSB_TRANSFER_TIMED_OUT:
1234  LOGERROR("USB write rumble motors timed out.");
1235  pThis->m_nErrorRcvTimeout++;
1236  break;
1237 
1238  //
1239  // USB transfer errors.
1240  //
1241  case LIBUSB_TRANSFER_ERROR:
1242  case LIBUSB_TRANSFER_STALL:
1243  case LIBUSB_TRANSFER_OVERFLOW:
1244  default:
1245  LOGERROR("USB write rumble motors failed (length=%d): USB status=%d",
1246  transfer->length, transfer->status);
1247  pThis->m_nErrorRcv++;
1248  pThis->m_nErrorTotal++;
1249  break;
1250  }
1251 }
1252 
1253 void HIDXbox360::transferCallbackLED(struct libusb_transfer *transfer)
1254 {
1255  HIDXbox360 *pThis = (HIDXbox360*)transfer->user_data;
1256 
1257  pThis->m_usbPkt[UsbPktIdLED].m_bHasSubmitted = false;
1258 
1259  //
1260  // USB transfer status.
1261  //
1262  switch( transfer->status )
1263  {
1264  //
1265  // Write transfer completed. The buffer just contains the data sent in the
1266  // write tranfer buffer. Not a true reply, but accept as successful.
1267  //
1268  case LIBUSB_TRANSFER_COMPLETED:
1269  pThis->m_state[Xbox360FeatIdLEDPat] = pThis->m_nLEDPattern;
1270  pThis->m_nErrorSend = 0;
1271  //pThis->debugPrintTransferBuf("DBG: led cb", transfer);
1272  break;
1273 
1274  //
1275  // No USB device. Probably unplugged.
1276  //
1277  case LIBUSB_TRANSFER_NO_DEVICE:
1278  LOGERROR("Disconnected!");
1279  pThis->m_nErrorSend++;
1280  pThis->m_nErrorTotal++;
1281  pThis->setConnectionState(false);
1282  pThis->setLinkState(false);
1283  break;
1284 
1285  //
1286  // USB transfer is being canceled. Typical when closing the interface.
1287  //
1288  case LIBUSB_TRANSFER_CANCELLED:
1289  LOGDIAG3("Tranfer cancelled.");
1290  break;
1291 
1292  //
1293  // USB transfer timed out. Write did not succeed in this case.
1294  //
1295  case LIBUSB_TRANSFER_TIMED_OUT:
1296  LOGERROR("USB write LED pattern timed out.");
1297  pThis->m_nErrorRcvTimeout++;
1298  break;
1299 
1300  //
1301  // USB transfer errors.
1302  //
1303  case LIBUSB_TRANSFER_ERROR:
1304  case LIBUSB_TRANSFER_STALL:
1305  case LIBUSB_TRANSFER_OVERFLOW:
1306  default:
1307  LOGERROR("USB write LED pattern (length=%d): USB status=%d.",
1308  transfer->length, transfer->status);
1309  pThis->m_nErrorRcv++;
1310  pThis->m_nErrorTotal++;
1311  break;
1312  }
1313 }
1314 
1315 void HIDXbox360::transferCallbackGoad(struct libusb_transfer *transfer)
1316 {
1317  HIDXbox360 *pThis = (HIDXbox360*)transfer->user_data;
1318 
1319  pThis->m_usbPkt[UsbPktIdGoad].m_bHasSubmitted = false;
1320 
1321  //
1322  // USB transfer status. Not too concern about the status.
1323  //
1324  switch( transfer->status )
1325  {
1326  case LIBUSB_TRANSFER_COMPLETED:
1327  //pThis->debugPrintTransferBuf("DBG: goad cb", transfer);
1328  break;
1329  case LIBUSB_TRANSFER_NO_DEVICE:
1330  case LIBUSB_TRANSFER_TIMED_OUT:
1331  case LIBUSB_TRANSFER_CANCELLED:
1332  case LIBUSB_TRANSFER_ERROR:
1333  case LIBUSB_TRANSFER_STALL:
1334  case LIBUSB_TRANSFER_OVERFLOW:
1335  default:
1336  break;
1337  }
1338 }
1339 
1341 {
1342  int nMaxTries = 5;
1343  int nTries;
1344  int nTrans;
1345  int i;
1346 
1347  for(i=0; i<UsbPktIdNumOf; ++i)
1348  {
1349  m_usbPkt[i].m_bCancel = true;
1350  }
1351 
1352  for(nTries=0; nTries<nMaxTries; ++nTries)
1353  {
1354  update();
1355 
1356  for(i=0, nTrans=0; i<UsbPktIdNumOf; ++i)
1357  {
1358  if( !m_usbPkt[i].m_bHasSubmitted )
1359  {
1360  ++nTrans;
1361  }
1362  }
1363 
1364  if( nTrans == UsbPktIdNumOf )
1365  {
1366  return;
1367  }
1368  }
1369 }
1370 
1372 {
1373  static int nMaxTries = 5;
1374 
1375  for(int i=0; i<nMaxTries; ++i)
1376  {
1377  update();
1378  }
1379 }
1380 
1381 bool HIDXbox360::parseWireless(byte_t buf[], ssize_t n)
1382 {
1383  bool bGoodPkt = true; // recevied good (bad) packet
1384  bool bNewState = true; // new link state
1385 
1386  //
1387  // Link Status Change Packet. Not reliable.
1388  //
1389  if( (n == XBOX360_WL_LINK_PKT_LEN) &&
1391  {
1393  switch( m_nStatus )
1394  {
1396  LOGDIAG3("Wireless status: Contoller linked.");
1397  break;
1399  LOGDIAG3("Wireless status: Headset linked.");
1400  break;
1402  LOGDIAG3("Wireless status: Contoller and headset linked.");
1403  break;
1405  LOGERROR("Wireless link: No link.");
1406  bNewState = false;
1407  break;
1408  default:
1409  break;
1410  }
1411  }
1412 
1413  //
1414  // Packet is too short.
1415  //
1416  else if( n < XBOX360_WL_NORM_PKT_LEN )
1417  {
1418  LOGERROR("Short packet.");
1419  bGoodPkt = false;
1420  bNewState = m_bIsLinked;
1421  //debugPrintTransferBuf("DBG: short pkt", buf, n);
1422  }
1423 
1424  //
1425  // Unknown packet type.
1426  //
1427  // Note: These could be valid packets, simply undocumented.
1428  //
1430  {
1431  LOGERROR("Unknown packet type = 0x%02x.", buf[XBOX360_WL_PKT_TYPE_POS]);
1432  bGoodPkt = false;
1433  bNewState = m_bIsLinked;
1434  //debugPrintTransferBuf("DBG: unknown pkt type", buf, n);
1435  }
1436 
1437  //
1438  // Button state update message.
1439  //
1440  else if( (buf[1] == XBOX360_WL_BTTN_PAT_1) &&
1441  (buf[2] == XBOX360_WL_BTTN_PAT_2) &&
1442  (buf[3] == XBOX360_WL_BTTN_PAT_3) &&
1444  {
1445  LOGDIAG4("Button state update packet.");
1447  }
1448 
1449  //
1450  // Announcement message.
1451  //
1452  // It is sent when controller transitions from no-link to linked. Not so
1453  // often sent by dongle though.
1454  //
1455  else if( (buf[1] == XBOX360_WL_ANN_PAT_1) &&
1456  (buf[2] == XBOX360_WL_ANN_PAT_2) &&
1457  (buf[3] == XBOX360_WL_ANN_PAT_3) )
1458  {
1459  char bufsn[16];
1460  const char *sep = "";
1461 
1462  m_strSerialNum.clear();
1463 
1464  for(int i=0; i<XBOX360_WL_ANN_SN_LEN; ++i)
1465  {
1466  sprintf(bufsn, "%s%02x", sep, (uint_t)buf[XBOX360_WL_ANN_SN_POS+i]&0xff);
1467  m_strSerialNum += bufsn;
1468  sep = ":";
1469  }
1470 
1472 
1473  LOGDIAG3("Announcement packet: S/N %s, battery status: %d",
1474  m_strSerialNum.c_str(), m_nBatteryStatus);
1475  }
1476 
1477  //
1478  // Battery status message.
1479  //
1480  else if( (buf[1] == XBOX360_WL_BATT_PAT_1) &&
1481  (buf[2] == XBOX360_WL_BATT_PAT_2) &&
1482  (buf[3] == XBOX360_WL_BATT_PAT_3) )
1483  {
1485  LOGDIAG3("Battery status packet: battery status: %d", m_nBatteryStatus);
1486  }
1487 
1488  //
1489  // Null message.
1490  //
1491  else if( (buf[1] == XBOX360_WL_NULL_PAT_1) &&
1492  (buf[2] == XBOX360_WL_NULL_PAT_2) )
1493  {
1494  LOGDIAG4("00 messsage: val=0x%02x.", buf[3]);
1495  if( buf[3] != XBOX360_WL_NULL_PAT_3_ACK )
1496  {
1497  bNewState = m_bIsLinked;
1498  }
1499  //debugPrintTransferBuf("00 msg:", buf, 4);
1500  }
1501 
1502  //
1503  // F8 message. Ignore.
1504  //
1505  else if( (buf[1] == XBOX360_WL_F8_PAT_1) &&
1506  (buf[3] == XBOX360_WL_F8_PAT_3) )
1507  {
1508  LOGDIAG4("F8 messsage: val=0x%02x.", buf[2]);
1509  bNewState = m_bIsLinked;
1510  //debugPrintTransferBuf("F8 msg:", buf, 4);
1511  }
1512 
1513  //
1514  // Don't know, but assume valid. Ignore.
1515  //
1516  else
1517  {
1518  LOGDIAG4("%02x messsage: val=0x%02x.", buf[1]);
1519  bNewState = m_bIsLinked;
1520  //debugPrintTransferBuf("unknown msg:", buf, 4);
1521  }
1522 
1523  if( bGoodPkt )
1524  {
1525  m_nErrorRcv = 0;
1526  m_nErrorRcvTimeout = 0;
1527  }
1528 
1529  else
1530  {
1531  ++m_nErrorRcv;
1532  ++m_nErrorTotal;
1533  }
1534 
1535  if( bNewState != m_bIsLinked )
1536  {
1537  setLinkState(bNewState);
1538  }
1539 
1540  return bGoodPkt;
1541 }
1542 
1543 bool HIDXbox360::parseWired(byte_t buf[], ssize_t n)
1544 {
1545  bool bGoodPkt;
1546 
1547  switch( buf[XBOX360_MSG_TYPE_POS] )
1548  {
1549  case XBOX360_BTTN_MSG_TYPE:
1551  {
1552  updateButtonState(buf, n);
1553  //LOGDIAG3("updated button state.");
1554  bGoodPkt = true;
1555  }
1556  break;
1557  case XBOX360_LED_MSG_TYPE:
1559  {
1560  updateLEDState(buf, n);
1561  //LOGDIAG3("updated led state.");
1562  bGoodPkt = true;
1563  }
1564  break;
1565  default:
1566  break;
1567  }
1568 
1569  if( !bGoodPkt )
1570  {
1571  //debugPrintTransferBuf("DBG: wired input", buf, n);
1572  }
1573 
1574  return bGoodPkt;
1575 }
1576 
1577 void HIDXbox360::updateButtonState(byte_t msg[], ssize_t n)
1578 {
1579  int val;
1580 
1581  // 19 or 20 byte message
1582  if( msg[XBOX360_MSG_LEN_POS] < XBOX360_BTTN_MSG_MIN_LEN )
1583  {
1584  return;
1585  }
1586 
1587  // --
1588  // Update state
1589  // --
1590 
1591  //
1592  // D Pad
1593  //
1602 
1603  //
1604  // Start/Back buttons
1605  //
1610 
1611  //
1612  // Stick clicks
1613  //
1620 
1621  //
1622  // Bump buttons
1623  //
1628 
1629  //
1630  // Center LED button
1631  //
1634 
1635  //
1636  // Function buttons
1637  //
1646 
1647  //
1648  // Triggers
1649  //
1654 
1655  //
1656  // Left Joystick
1657  //
1660 
1661  if( val > m_nLeftJoyDeadZone )
1662  {
1664  }
1665  else if( val < -m_nLeftJoyDeadZone )
1666  {
1668  }
1669  else
1670  {
1672  }
1673 
1676 
1677  if( val > m_nLeftJoyDeadZone )
1678  {
1680  }
1681  else if( val < -m_nLeftJoyDeadZone )
1682  {
1684  }
1685  else
1686  {
1688  }
1689 
1690  //
1691  // Right Joystick
1692  //
1695 
1696  if( val > m_nRightJoyDeadZone )
1697  {
1699  }
1700  else if( val < -m_nRightJoyDeadZone )
1701  {
1703  }
1704  else
1705  {
1707  }
1708 
1711 
1712  if( val > m_nRightJoyDeadZone )
1713  {
1715  }
1716  else if( val < -m_nRightJoyDeadZone )
1717  {
1719  }
1720  else
1721  {
1723  }
1724 }
1725 
1726 void HIDXbox360::updateRumbleState(byte_t msg[], ssize_t n)
1727 {
1728  switch( m_nProdId )
1729  {
1731  case XBOX360_WIRELESS_WIN_PROD_ID:
1732  m_state[Xbox360FeatIdLeftRumble] = msg[5];
1734  break;
1735 
1736  case XBOX360_WIRED_PROD_ID:
1737  default:
1738  if( n >= XBOX360_RUMBLE_MSG_LEN )
1739  {
1744  }
1745  break;
1746  }
1747 }
1748 
1749 void HIDXbox360::updateLEDState(byte_t buf[], ssize_t n)
1750 {
1751  switch( m_nProdId )
1752  {
1754  case XBOX360_WIRELESS_WIN_PROD_ID:
1755  if( n >= XBOX360_MSG_OFFSET_WL )
1756  {
1759  }
1760  break;
1761 
1762  case XBOX360_WIRED_PROD_ID:
1763  default:
1764  if( n >= XBOX360_LED_MSG_LEN )
1765  {
1768  }
1769  break;
1770  }
1771 }
1772 
1773 int HIDXbox360::convertToInt(byte_t lsb, byte_t msb)
1774 {
1775  int output;
1776 
1777  output = (int)( (((uint_t)msb) << 8) | (uint_t)lsb);
1778 
1779  if( output & 0x8000 )
1780  {
1781  output -= 0xffff;
1782  }
1783 
1784  return output;
1785 }
1786 
1788 {
1789  if( !m_bIsLinked )
1790  {
1791  return m_bIsLinked;
1792  }
1793 
1794  //
1795  // Receive timeout threshold.
1796  //
1798  {
1799  LOGERROR("Consecutive received timeout error count %d "
1800  "exceeds threshold %d.", m_nErrorRcvTimeout, m_nErrorRcvTimeoutTh);
1801  ++m_nErrorRcv;
1802  ++m_nErrorTotal;
1803  setLinkState(false);
1804  }
1805 
1806  //
1807  // Receive error threshold.
1808  //
1809  if( (m_nErrorRcvTh > 0) && (m_nErrorRcv > m_nErrorRcvTh) )
1810  {
1811  LOGERROR("Consecutive received error count %d exceeds threshold %d.",
1813  setLinkState(false);
1814  }
1815 
1816  //
1817  // Total receive error threshold.
1818  //
1819  if( (m_nErrorTotalTh > 0) && (m_nErrorTotal > m_nErrorTotalTh) )
1820  {
1821  LOGERROR("Total received error count %d exceeds threshold %d.",
1823  setLinkState(false);
1824  }
1825 
1826  return m_bIsLinked;
1827 }
1828 
1830 {
1831  int rc;
1832 
1834 
1835  rc = pthread_create(&m_threadId, NULL, HIDXbox360::updateThread, (void*)this);
1836 
1837  if( rc < 0 )
1838  {
1839  LOGSYSERROR("pthread_create()");
1840  }
1841 
1842  return rc;
1843 }
1844 
1846 {
1849  usleep(1000);
1850  pthread_cancel(m_threadId);
1851  pthread_join(m_threadId, NULL);
1852  return 0;
1853 }
1854 
1856 {
1857  pthread_cond_signal(&m_condUpdate);
1858 }
1859 
1861 {
1862  lock();
1863  pthread_cond_timedwait(&m_condUpdate, &m_mutexUpdate, &m_tsThread);
1864  unlock();
1865 }
1866 
1867 int HIDXbox360::update(uint_t uMSec)
1868 {
1869  struct timeval tvWait;
1870 
1871  // no connected
1872  if( !m_bIsConnected )
1873  {
1874  m_nError = LIBUSB_ERROR_NO_DEVICE;
1875  return m_nError;
1876  }
1877 
1878  tvWait.tv_sec = 0;
1879  tvWait.tv_usec = uMSec * 1000;
1880 
1881  lock();
1882 
1883  //
1884  // N.B. Cannot make libusb_handle_events_*() call from a callback since the
1885  // callback was called within this call. Causes deadlock.
1886  //
1887  m_nError = libusb_handle_events_timeout_completed(m_usbContext,
1888  &tvWait, NULL);
1889 
1890  unlock();
1891 
1892  return m_nError;
1893 }
1894 
1895 void *HIDXbox360::updateThread(void *pArg)
1896 {
1897  HIDXbox360 *pThis = (HIDXbox360 *)pArg;
1898  int oldstate;
1899  int rc;
1900 
1901  pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &oldstate);
1902  pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldstate);
1903 
1904  LOGDIAG3("Update thread created.");
1905 
1906  while( (pThis->m_eThreadState == ThreadStateRunning) && pThis->isConnected() )
1907  {
1908  pThis->blockWait();
1909 
1910  switch( pThis->m_eThreadState )
1911  {
1912  case ThreadStateRunning:
1913  pThis->update(0);
1914  break;
1915  case ThreadStateExit:
1916  default:
1917  break;
1918  }
1919  }
1920 
1922 
1923  LOGDIAG3("Update thread exited.");
1924 
1925  return NULL;
1926 }
1927 
1929 {
1930  fprintf(stderr,
1931 " %s (Product Id 0x%04x)"
1932 "\n"
1933 " DPad Bump Bk Cx St A B X Y Trigger LeftJoyStick RightJoytStick"
1934 " LED Rumble Link Status Batt ERTO ER ES ETOT"
1935 "\n", m_strProdName.c_str(), m_nProdId);
1936 //"1 1 1 1 0 0 1 1 1 1 1 1 1 255 255 1 -32333 -32333 1 -32333 -32333
1937 // 0xhh false 127 10 100
1938 }
1939 
1941 {
1942  fprintf(stderr,
1943  "%1d %1d %1d %1d %1d %1d %1d %1d %1d %1d %1d %1d %1d %3d %3d "
1944  "%1d %6d %6d %1d %6d %6d %2d %3d %3d %5s 0x%02x %4d %5d %3d %3d %5d\r",
1949 
1952 
1956 
1961 
1964 
1971 
1975 
1976  (m_bIsLinked? "true": "false"),
1977  m_nStatus,
1980  m_nErrorRcv,
1981  m_nErrorSend,
1982  m_nErrorTotal);
1983 
1984  fflush(stderr);
1985 }
1986 
1987 void HIDXbox360::debugPrintTransferBuf(const std::string &strPreface,
1988  byte_t buf[],
1989  ssize_t n,
1990  const std::string &strEoR)
1991 {
1992  struct timeval tvNow;
1993  double t;
1994 
1995  gettimeofday(&tvNow, NULL);
1996 
1997  t = (double)tvNow.tv_sec + (double)tvNow.tv_usec / 1000000.0;
1998 
1999  fprintf(stderr, "%.3lf ", t);
2000 
2001  if( !strPreface.empty() )
2002  {
2003  fprintf(stderr, "%s: ", strPreface.c_str());
2004  }
2005 
2006  fprintf(stderr, "buf_len=%zd: ", n);
2007 
2008  for(int i=0; i<n; ++i)
2009  {
2010  fprintf(stderr, "%02x ", buf[i]);
2011  }
2012 
2013  fprintf(stderr, "%s", strEoR.c_str());
2014  fflush(stderr);
2015 }
static void transferCallbackGoad(struct libusb_transfer *transfer)
Write packet to force a response packet from the Xbox360.
#define XBOX360_WL_BTTN_PAT_3
header pattern at byte 3
Definition: HIDXbox360.h:361
virtual int close()
Close connection to an opened USB Xbox360 controller.
Definition: HIDXbox360.cxx:230
#define HID_FEAT_INPUT
input to host feature
Definition: HID.h:55
B button [0,1].
Definition: HIDXbox360.h:631
#define XBOX360_BTTN_A_BUTTON_POS
byte position
Definition: HIDXbox360.h:483
struct libusb_transfer * m_usbTransfer
allocated transfer packet
Definition: HIDXbox360.h:693
int createUpdateThread()
Create USB update thread.
void flushInput()
Flush any pending input transfer buffers.
#define XBOX360_WL_PKT_TYPE_NORM
normal link message
Definition: HIDXbox360.h:284
#define XBOX360_BTTN_PAD_RIGHT_POS
byte position
Definition: HIDXbox360.h:451
#define XBOX360_LEFT_DEAD_ZONE
Definition: HIDXbox360.h:601
UsbPkt_T m_usbPkt[UsbPktIdNumOf]
USB transfer packets.
Definition: HIDXbox360.h:977
#define MICROSOFT_VENDOR_ID
Definition: HIDXbox360.h:216
~HIDXbox360()
Destructor.
Definition: HIDXbox360.cxx:141
#define XBOX360_BTTN_CENTER_X_POS
byte position
Definition: HIDXbox360.h:479
virtual int open()
Open connection to an USB Xbox360 controller.
Definition: HIDXbox360.cxx:159
#define XBOX360_WL_NULL_PAT_2
header pattern at byte 2
Definition: HIDXbox360.h:346
#define XBOX360_WL_BATT_PAT_2
header pattern at byte 2
Definition: HIDXbox360.h:329
#define XBOX360_BTTN_RIGHT_X_POS_H
byte position
Definition: HIDXbox360.h:520
#define XBOX360_MSG_TYPE_POS
message type byte position
Definition: HIDXbox360.h:422
#define XBOX360_WL_LED_PAT_POS
LED position is in PACKET header.
Definition: HIDXbox360.h:566
#define XBOX360_BTTN_PAD_LEFT_POS
byte position
Definition: HIDXbox360.h:448
void freeTransferPkts()
Free all USB transfer packets.
Definition: HIDXbox360.cxx:999
rumble (write) transfer packet
Definition: HIDXbox360.h:682
void debugPrintState()
Simple debug print state.
back button [0,1]
Definition: HIDXbox360.h:624
#define XBOX360_WL_ANN_BATT_POS
battery status field position
Definition: HIDXbox360.h:319
void clearErrorCnts()
Clear error counts.
Definition: HIDXbox360.h:1133
#define XBOX360_BTTN_MSG_LEN
wired button msg length
Definition: HIDXbox360.h:437
void unlock()
Unlock the update thread.
Definition: HIDXbox360.h:1220
#define XBOX360_WL_LINK_STATUS_CTLR_HEADSET
linked w/ ctlr & headset
Definition: HIDXbox360.h:306
#define XBOX360_WL_ANN_SN_POS
serial number field position
Definition: HIDXbox360.h:317
#define XBOX360_BTTN_MSG_TYPE
button update msg type
Definition: HIDXbox360.h:436
#define XBOX360_WL_RUMBLE_PAT_3
header pattern at byte 3
Definition: HIDXbox360.h:371
#define XBOX360_WL_BTTN_PAT_2
header pattern at byte 2
Definition: HIDXbox360.h:360
#define XBOX360_BTTN_B_BUTTON_MASK
bit mask
Definition: HIDXbox360.h:488
void signalUpdateThread()
Signal update thread of change of state.
#define XBOX360_BTTN_RIGHT_X_POS_L
byte position
Definition: HIDXbox360.h:519
void debugPrintTransferBuf(const std::string &strPreface, struct libusb_transfer *transfer)
Debug print USB transfer buffer contents.
Definition: HIDXbox360.h:1256
#define XBOX360_BTTN_CENTER_X_MASK
bit mask
Definition: HIDXbox360.h:480
#define XBOX360_TETHERED_PROD_ID
Definition: HIDXbox360.h:222
int m_nError
last error number (HID specific)
Definition: HID.h:299
std::string m_strProdName
product name
Definition: HIDXbox360.h:945
#define XBOX360_WL_RUMBLE_PAT_2
header pattern at byte 2
Definition: HIDXbox360.h:370
#define XBOX360_LED_MSG_TYPE
LED message type.
Definition: HIDXbox360.h:559
#define XBOX360_RUMBLE_LEFT_POS
byte position
Definition: HIDXbox360.h:539
void zeroState()
Zero controller shadowed state.
Definition: HIDXbox360.h:1155
#define XBOX360_MSG_OFFSET_WL
wireless message start byte offset
Definition: HIDXbox360.h:265
#define XBOX360_BTTN_LEFT_STICK_CLICK_POS
byte position
Definition: HIDXbox360.h:463
float m_fRightJoyB
right joystick y intercept
Definition: HIDXbox360.h:957
byte_t m_bufData[UsbTransferBufSize]
transfer data buffer
Definition: HIDXbox360.h:694
#define HID_BTTN_UP
button/key state is up or unpressed
Definition: HID.h:52
#define XBOX360_WL_NULL_PAT_1
header pattern at byte 1
Definition: HIDXbox360.h:345
Xbox360 Controller C interface.
#define XBOX360_LED_PAT_MASK
bit mask
Definition: HIDXbox360.h:569
bool m_bCancel
do [not] cancel submissions
Definition: HIDXbox360.h:696
#define XBOX360_BTTN_LEFT_X_POS_L
byte position
Definition: HIDXbox360.h:510
#define XBOX360_BTTN_A_BUTTON_MASK
bit mask
Definition: HIDXbox360.h:484
int initTransferPkts()
Allocate and initialize all USB transfer packets.
Definition: HIDXbox360.cxx:933
#define XBOX360_BTTN_LEFT_Y_POS_H
byte position
Definition: HIDXbox360.h:515
int m_nProdId
Xbox USB product id.
Definition: HIDXbox360.h:944
void lock()
Lock update thread.
Definition: HIDXbox360.h:1207
#define XBOX360_RUMBLE_RIGHT_MASK
bit mask
Definition: HIDXbox360.h:545
int m_nErrorSend
consec send error count
Definition: HIDXbox360.h:970
int m_nRightRumble
target right rumble intensity
Definition: HIDXbox360.h:963
#define XBOX360_BTTN_LEFT_TRIGGER_POS
byte position
Definition: HIDXbox360.h:499
virtual bool ping()
Ping device if it is connected and is responding.
Definition: HIDXbox360.cxx:414
right trigger [0-255]
Definition: HIDXbox360.h:635
#define XBOX360_BTTN_LEFT_Y_POS_L
byte position
Definition: HIDXbox360.h:514
#define XBOX360_LED_PAT_POS
LED messge byte position.
Definition: HIDXbox360.h:561
pthread_mutex_t m_mutexUpdate
mutex
Definition: HIDXbox360.h:982
#define XBOX360_WL_PKT_TYPE_CHG
link status changed message
Definition: HIDXbox360.h:285
static void transferCallbackRumble(struct libusb_transfer *transfer)
Write rumble motor values transfer function callback.
#define XBOX360_RUMBLE_MSG_LEN
rumble read/write message length
Definition: HIDXbox360.h:534
float m_fLeftJoyB
left joystick y intercept
Definition: HIDXbox360.h:954
float m_fRightJoyM
right joystick slope
Definition: HIDXbox360.h:956
#define XBOX360_NO_PROD_ID
Definition: HIDXbox360.h:229
#define XBOX360_RUMBLE_LEFT_MASK
bit mask
Definition: HIDXbox360.h:540
#define XBOX360_WL_LED_PAT_2
header pattern at byte 2
Definition: HIDXbox360.h:380
float m_fLeftJoyM
left joystick slope
Definition: HIDXbox360.h:953
normal input (read) transfer packet
Definition: HIDXbox360.h:681
#define XBOX360_BTTN_Y_BUTTON_POS
byte position
Definition: HIDXbox360.h:495
center x (big button) [0,1]
Definition: HIDXbox360.h:629
#define XBOX360_BTTN_Y_BUTTON_MASK
bit mask
Definition: HIDXbox360.h:496
#define XBOX360_WL_NORM_PKT_LEN
normal packet length
Definition: HIDXbox360.h:278
#define XBOX360_BTTN_RIGHT_TRIGGER_POS
byte position
Definition: HIDXbox360.h:503
#define XBOX360_NUM_OF_INTERFACES
Definition: HIDXbox360.h:238
FeatMap_T m_featMap
feature-userid association map
Definition: HID.h:301
int openXbox()
Open Xbox360 connection.
Definition: HIDXbox360.cxx:783
int convertToInt(byte_t lsb, byte_t msb)
Convert two bytes to signed integer.
void setErrorThresholds(int nErrorRcvTimeoutTh=NErrorRcvTimeoutThDft, int nErrorRcvTh=NErrorRcvThDft, int nErrorTotalTh=NErrorTotalThDft)
Set error count thresholds.
Definition: HIDXbox360.h:912
void goad()
Goad the Xbox360 to send a message.
Definition: HIDXbox360.cxx:420
void debugPrintHdr()
Simple debug print header.
#define XBOX360_WL_ANN_PAT_2
header pattern at byte 2
Definition: HIDXbox360.h:315
#define XBOX360_WL_LINK_PKT_LEN
link status change packet length
Definition: HIDXbox360.h:277
#define XBOX360_BTTN_B_BUTTON_POS
byte position
Definition: HIDXbox360.h:487
LED (write) transfer packet.
Definition: HIDXbox360.h:683
bool checkErrorThresholds()
Check errors against thresholds.
int m_nRightJoyDeadZone
right joystick deadzone
Definition: HIDXbox360.h:955
#define XBOX360_WL_LINK_STATUS_NO_LINK
no link
Definition: HIDXbox360.h:303
int m_nOffset
start offset in message
Definition: HIDXbox360.h:949
virtual int stop()
Stop and destroy USB update thread.
Definition: HIDXbox360.cxx:322
Y button [0,1].
Definition: HIDXbox360.h:633
int setRumble(int nLeftMot, int nRightMot)
Set the rumble instensity.
Definition: HIDXbox360.cxx:492
#define XBOX360_BTTN_PAD_DOWN_MASK
bit mask
Definition: HIDXbox360.h:446
#define HID_BTTN_DOWN
button/key state is down or pressed
Definition: HID.h:53
bool m_bHasSubmitted
has [not] been submitted
Definition: HIDXbox360.h:695
A button [0,1].
Definition: HIDXbox360.h:630
bool isWireless()
Check if Xbox360 hardware is wireless.
Definition: HIDXbox360.h:926
void updateLEDState(byte_t buf[], ssize_t n)
Update the LED pattern state.
virtual void setConnectionState(bool bNewState)
Set connection state.
Definition: HID.h:308
#define XBOX360_WL_LED_PAT_1
header pattern at byte 1
Definition: HIDXbox360.h:379
#define XBOX360_BTTN_PAD_UP_MASK
bit mask
Definition: HIDXbox360.h:443
right joystick click(right thumb) [0,1]
Definition: HIDXbox360.h:626
left joystick click(left thumb) [0,1]
Definition: HIDXbox360.h:625
#define XBOX360_WL_LINK_STATUS_HEADSET
linked w/ headset
Definition: HIDXbox360.h:304
virtual int getFeatureProp(int iMnem, HIDFeatType &eFeatType, int &nDir, int &nMin, int &nMax, int &nStep)
Get the feature properties.
Definition: HIDXbox360.cxx:353
right hi-freq rumble motor [0-255]
Definition: HIDXbox360.h:641
#define XBOX360_BTTN_START_MASK
bit mask
Definition: HIDXbox360.h:456
int m_state[Xbox360FeatIdNumOf]
current state
Definition: HIDXbox360.h:960
int cancelUpdateThread()
Cancel (destroy) USB update thread.
right joystick x value [-32768-32767]
Definition: HIDXbox360.h:638
#define XBOX360_BTTN_X_BUTTON_MASK
bit mask
Definition: HIDXbox360.h:492
std::string m_strSerialNum
serial number
Definition: HIDXbox360.h:946
int m_nErrorRcv
consecutive rcv error count
Definition: HIDXbox360.h:966
right joystick x value [-32768-32767]
Definition: HIDXbox360.h:639
void updateButtonState(byte_t msg[], ssize_t n)
Update the controller input button state.
static void transferCallbackInput(struct libusb_transfer *transfer)
Input transfer function callback.
void blockWait()
Blocked timed wait.
left joystick x value [-32768-32767]
Definition: HIDXbox360.h:636
#define XBOX360_WL_LED_PAT_3
header pattern at byte 3
Definition: HIDXbox360.h:381
Xbox360 controller HID input class.
Definition: HIDXbox360.h:651
int submitReadTransfer()
Submit read Xbox input asynchronous transfer.
int m_nStatus
raw status byte
Definition: HIDXbox360.h:948
static void * updateThread(void *pArg)
The update thread.
virtual bool isConnected()
Query if HID is connected.
Definition: HID.h:167
virtual int update(uint_t uMSec=T_UPDATE_DFT)
Read device and update HID state.
LED pattern feature.
Definition: HIDXbox360.h:642
#define XBOX360_WL_RUMBLE_PAT_1
header pattern at byte 1
Definition: HIDXbox360.h:369
#define XBOX360_WL_ANN_PAT_3
header pattern at byte 3
Definition: HIDXbox360.h:316
range between [min,max] property type
Definition: HID.h:90
ThreadState m_eThreadState
update thread state
Definition: HIDXbox360.h:980
#define XBOX360_RIGHT_DEAD_ZONE
Definition: HIDXbox360.h:604
#define XBOX360_WRITE_ENDPOINT
Definition: HIDXbox360.h:235
bool m_bIsLinked
HID is [not] linked and communicating.
Definition: HID.h:298
Input Human Interface Device Abstract Base Class.
Definition: HID.h:100
#define XBOX360_BTTN_RIGHT_Y_POS_H
byte position
Definition: HIDXbox360.h:524
int m_nBatteryStatus
batter status
Definition: HIDXbox360.h:947
static void transferCallbackLED(struct libusb_transfer *transfer)
Write LED pattern transfer function callback.
left joystick y value [-32768-32767]
Definition: HIDXbox360.h:637
#define XBOX360_BTTN_LEFT_X_POS_H
byte position
Definition: HIDXbox360.h:511
int setLED(int nPattern)
Set the LED pattern.
Definition: HIDXbox360.cxx:623
#define XBOX360_WL_PKT_TYPE_POS
byte position
Definition: HIDXbox360.h:283
void cancelTransfers()
Cancel all pending USB transfers.
#define XBOX360_BTTN_X_BUTTON_POS
byte position
Definition: HIDXbox360.h:491
virtual int setFeatureVal(int iMnem, int nVal)
Set the value associated with the mapped user mnemonic.
Definition: HIDXbox360.cxx:331
#define XBOX360_BTTN_LEFT_STICK_CLICK_MASK
bit mask
Definition: HIDXbox360.h:464
left bump (left shoulder) [0,1]
Definition: HIDXbox360.h:627
bool parseWired(byte_t buf[], ssize_t n)
Parse wired Xbox360 input events.
#define XBOX360_MSG_OFFSET_W
wired message start byte offset
Definition: HIDXbox360.h:264
#define XBOX360_BTTN_PAD_LEFT_MASK
bit mask
Definition: HIDXbox360.h:449
#define XBOX360_MSG_OFFSET_DFT
default message start byte offset
Definition: HIDXbox360.h:263
#define XBOX360_WL_F8_PAT_3
header pattern at byte 3
Definition: HIDXbox360.h:394
#define XBOX360_BTTN_RIGHT_BUMP_MASK
bit mask
Definition: HIDXbox360.h:476
binary state property type
Definition: HID.h:89
#define XBOX360_WL_PKT_HDR_LEN
wireless packet header length
Definition: HIDXbox360.h:266
#define XBOX360_BTTN_BACK_POS
byte position
Definition: HIDXbox360.h:459
dpad right [0,1]
Definition: HIDXbox360.h:622
#define XBOX360_BTTN_LEFT_BUMP_MASK
bit mask
Definition: HIDXbox360.h:472
#define HID_FEAT_OUTPUT
output to device feature
Definition: HID.h:56
void calibrateJoySticks(int nLeftDeadZone, int nRightDeadZone)
Set joysticks calibration.
Definition: HIDXbox360.cxx:741
start button [0,1]
Definition: HIDXbox360.h:623
#define XBOX360_RUMBLE_RIGHT_POS
byte position
Definition: HIDXbox360.h:544
USB extensions and capatabilities.
#define XBOX360_BTTN_BACK_MASK
bit mask
Definition: HIDXbox360.h:460
int updown(int nBit)
Convert bit value to button up/down state.
Definition: HIDXbox360.h:1167
#define XBOX360_BTTN_RIGHT_BUMP_POS
byte position
Definition: HIDXbox360.h:475
int m_nErrorRcvTimeoutTh
consec rcv timeout error th
Definition: HIDXbox360.h:969
int m_nErrorRcvTh
consec rcv error threshold
Definition: HIDXbox360.h:967
#define XBOX360_MSG_LEN_POS
message length byte position
Definition: HIDXbox360.h:423
#define XBOX360_RUMBLE_MSG_TYPE
rumble message type
Definition: HIDXbox360.h:533
#define XBOX360_WIRELESS_PROD_ID
Definition: HIDXbox360.h:225
#define XBOX360_WL_BATT_PAT_1
header pattern at byte 1
Definition: HIDXbox360.h:328
void updateRumbleState(byte_t msg[], ssize_t n)
Update the rumble motors state.
#define XBOX360_WL_BATT_BATT_POS
battery status field position
Definition: HIDXbox360.h:331
#define XBOX360_WL_NULL_PAT_3_ACK
header pattern at byte 3
Definition: HIDXbox360.h:351
struct timespec m_tsThread
update thread period
Definition: HIDXbox360.h:981
number of transfer packet ids
Definition: HIDXbox360.h:685
#define XBOX360_LED_PAT_ALL_BLINK
all 4 LEDs blink continuously
Definition: HIDXbox360.h:585
virtual int run(float hz=30.0)
Create and run USB update in thread.
Definition: HIDXbox360.cxx:292
bool parseWireless(byte_t buf[], ssize_t n)
Parse wireless Xbox360 input events.
left low-freq rumble motor [0-255]
Definition: HIDXbox360.h:640
pthread_t m_threadId
update pthread identifier
Definition: HIDXbox360.h:984
HIDFeatType
Feature property types.
Definition: HID.h:85
right bump (right shoulder) [0,1]
Definition: HIDXbox360.h:628
#define XBOX360_BTTN_PAD_RIGHT_MASK
bit mask
Definition: HIDXbox360.h:452
dpad left [0,1]
Definition: HIDXbox360.h:621
#define XBOX360_WL_LED_MSG_LEN
LED message length.
Definition: HIDXbox360.h:565
#define XBOX360_WL_BTTN_PAT_1
header pattern at byte 1
Definition: HIDXbox360.h:359
int m_nErrorTotalTh
total error threshold
Definition: HIDXbox360.h:972
#define XBOX360_BTTN_RIGHT_Y_POS_L
byte position
Definition: HIDXbox360.h:523
#define XBOX360_LED_PAT_ALL_OFF
all 4 LEDs off
Definition: HIDXbox360.h:570
#define XBOX360_BTTN_LEFT_BUMP_POS
byte position
Definition: HIDXbox360.h:471
#define XBOX360_BTTN_PAD_DOWN_POS
byte position
Definition: HIDXbox360.h:445
#define XBOX360_WL_ANN_PAT_1
header pattern at byte 1
Definition: HIDXbox360.h:314
#define XBOX360_BTTN_RIGHT_STICK_CLICK_POS
byte position
Definition: HIDXbox360.h:467
discrete enumeration feature property type
Definition: HID.h:91
#define XBOX360_READ_ENDPOINT
Definition: HIDXbox360.h:232
bool m_bFatal
HID is [not] in a fatal condition.
Definition: HID.h:300
#define XBOX360_WL_F8_PAT_1
header pattern at byte 1
Definition: HIDXbox360.h:390
#define XBOX360_LED_MSG_LEN
LED message length.
Definition: HIDXbox360.h:560
int m_nLEDPattern
target LED pattern
Definition: HIDXbox360.h:961
bool m_bIsConnected
HID is [not] physically connected.
Definition: HID.h:297
#define XBOX360_WL_ANN_SN_LEN
serial number field length
Definition: HIDXbox360.h:318
virtual void setLinkState(bool bNewState)
Set new link state.
Definition: HID.h:326
pthread_cond_t m_condUpdate
condition
Definition: HIDXbox360.h:983
dpad up [0,1]
Definition: HIDXbox360.h:619
int m_nLeftRumble
target left rumble intensity
Definition: HIDXbox360.h:962
number of features (keep last)
Definition: HIDXbox360.h:644
struct libusb_device_handle * m_usbHandle
USB open handle.
Definition: HIDXbox360.h:976
int m_nLeftJoyDeadZone
left joystick deadzone
Definition: HIDXbox360.h:952
RoadNarrows Robotics standard namespace.
Definition: HID.h:65
X button [0,1].
Definition: HIDXbox360.h:632
struct libusb_context * m_usbContext
libusb session context
Definition: HIDXbox360.h:975
#define XBOX360_WIRED_PROD_ID
Definition: HIDXbox360.h:219
dpad down [0,1]
Definition: HIDXbox360.h:620
Goad (write) transfer packet.
Definition: HIDXbox360.h:684
left trigger [0-255]
Definition: HIDXbox360.h:634
#define XBOX360_BTTN_RIGHT_STICK_CLICK_MASK
bit mask
Definition: HIDXbox360.h:468
int claimXboxInterfaces()
Claim all Xbox USB interfaces.
Definition: HIDXbox360.cxx:861
#define XBOX360_WL_BATT_PAT_3
header pattern at byte 3
Definition: HIDXbox360.h:330
virtual void setLinkState(bool bNewState)
Set new link state.
Definition: HIDXbox360.cxx:759
#define XBOX360_WL_LINK_STATUS_POS
byte position
Definition: HIDXbox360.h:302
Microsoft Xbox360 game console family.
Definition: HID.h:76
#define XBOX360_BTTN_START_POS
byte position
Definition: HIDXbox360.h:455
int m_nErrorTotal
total error count
Definition: HIDXbox360.h:971
#define XBOX360_WL_LINK_STATUS_CTLR
linked w/ controller
Definition: HIDXbox360.h:305
#define XBOX360_BTTN_PAD_UP_POS
byte position
Definition: HIDXbox360.h:442
int m_nErrorRcvTimeout
consec rcv timeout error cnt
Definition: HIDXbox360.h:968