Skip to content

Commit 2c087f9

Browse files
committed
Input: xpad - decipher xpadone packages with GIP defines
only renames, no functional changes - even though some of the packets we send are suspicious. However, I dont have the hardware to verify they are truly superflous.
1 parent 1b1391a commit 2c087f9

File tree

1 file changed

+69
-30
lines changed

1 file changed

+69
-30
lines changed

xpad.c

Lines changed: 69 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -521,13 +521,52 @@ struct xboxone_init_packet {
521521
.len = ARRAY_SIZE(_data), \
522522
}
523523

524+
/*
525+
* starting with xbox one, the game input protocol is used
526+
* magic numbers are taken from
527+
* - https://github.com/xpadneo/gip-dissector/blob/main/src/gip-dissector.lua
528+
* - https://github.com/medusalix/xone/blob/master/bus/protocol.c
529+
*/
530+
#define GIP_CMD_ACK 0x01
531+
#define GIP_CMD_IDENTIFY 0x04
532+
#define GIP_CMD_POWER 0x05
533+
#define GIP_CMD_AUTHENTICATE 0x06
534+
#define GIP_CMD_VIRTUAL_KEY 0x07
535+
#define GIP_CMD_RUMBLE 0x09
536+
#define GIP_CMD_LED 0x0a
537+
#define GIP_CMD_FIRMWARE 0x0c
538+
#define GIP_CMD_INPUT 0x20
539+
540+
#define GIP_SEQ0 0x00
541+
542+
#define GIP_OPT_ACK 0x10
543+
#define GIP_OPT_INTERNAL 0x20
544+
545+
/*
546+
* length of the command payload encoded with
547+
* https://en.wikipedia.org/wiki/LEB128
548+
* which is a no-op for N < 128
549+
*/
550+
#define GIP_PL_LEN(N) (N)
551+
552+
/*
553+
* payload specific defines
554+
*/
555+
#define GIP_PWR_ON 0x00
556+
#define GIP_LED_ON 0x01
557+
558+
#define GIP_MOTOR_R BIT(0)
559+
#define GIP_MOTOR_L BIT(1)
560+
#define GIP_MOTOR_RT BIT(2)
561+
#define GIP_MOTOR_LT BIT(3)
562+
#define GIP_MOTOR_ALL (GIP_MOTOR_R | GIP_MOTOR_L | GIP_MOTOR_RT | GIP_MOTOR_LT)
524563

525564
/*
526565
* This packet is required for all Xbox One pads with 2015
527566
* or later firmware installed (or present from the factory).
528567
*/
529-
static const u8 xboxone_fw2015_init[] = {
530-
0x05, 0x20, 0x00, 0x01, 0x00
568+
static const u8 xboxone_power_on[] = {
569+
GIP_CMD_POWER, GIP_OPT_INTERNAL, GIP_SEQ0, GIP_PL_LEN(1), GIP_PWR_ON
531570
};
532571

533572
/*
@@ -537,7 +576,7 @@ static const u8 xboxone_fw2015_init[] = {
537576
* Bluetooth mode.
538577
*/
539578
static const u8 xboxone_s_init[] = {
540-
0x05, 0x20, 0x00, 0x0f, 0x06
579+
GIP_CMD_POWER, GIP_OPT_INTERNAL, GIP_SEQ0, 0x0f, 0x06
541580
};
542581

543582
/*
@@ -554,36 +593,36 @@ static const u8 extra_input_packet_init[] = {
554593
* (0x0e6f:0x0165) to finish initialization and for Hori pads
555594
* (0x0f0d:0x0067) to make the analog sticks work.
556595
*/
557-
static const u8 xboxone_hori_init[] = {
558-
0x01, 0x20, 0x00, 0x09, 0x00, 0x04, 0x20, 0x3a,
559-
0x00, 0x00, 0x00, 0x80, 0x00
596+
static const u8 xboxone_hori_ack_id[] = {
597+
GIP_CMD_ACK, GIP_OPT_INTERNAL, GIP_SEQ0, GIP_PL_LEN(9),
598+
0x00, GIP_CMD_IDENTIFY, GIP_OPT_INTERNAL, 0x3a, 0x00, 0x00, 0x00, 0x80, 0x00
560599
};
561600

562601
/*
563602
* This packet is required for most (all?) of the PDP pads to start
564603
* sending input reports. These pads include: (0x0e6f:0x02ab),
565604
* (0x0e6f:0x02a4), (0x0e6f:0x02a6).
566605
*/
567-
static const u8 xboxone_pdp_init1[] = {
568-
0x0a, 0x20, 0x00, 0x03, 0x00, 0x01, 0x14
606+
static const u8 xboxone_pdp_led_on[] = {
607+
GIP_CMD_LED, GIP_OPT_INTERNAL, GIP_SEQ0, GIP_PL_LEN(3), 0x00, GIP_LED_ON, 0x14
569608
};
570609

571610
/*
572611
* This packet is required for most (all?) of the PDP pads to start
573612
* sending input reports. These pads include: (0x0e6f:0x02ab),
574613
* (0x0e6f:0x02a4), (0x0e6f:0x02a6).
575614
*/
576-
static const u8 xboxone_pdp_init2[] = {
577-
0x06, 0x20, 0x00, 0x02, 0x01, 0x00
615+
static const u8 xboxone_pdp_auth[] = {
616+
GIP_CMD_AUTHENTICATE, GIP_OPT_INTERNAL, GIP_SEQ0, GIP_PL_LEN(2), 0x01, 0x00
578617
};
579618

580619
/*
581620
* A specific rumble packet is required for some PowerA pads to start
582621
* sending input reports. One of those pads is (0x24c6:0x543a).
583622
*/
584623
static const u8 xboxone_rumblebegin_init[] = {
585-
0x09, 0x00, 0x00, 0x09, 0x00, 0x0F, 0x00, 0x00,
586-
0x1D, 0x1D, 0xFF, 0x00, 0x00
624+
GIP_CMD_RUMBLE, 0x00, GIP_SEQ0, GIP_PL_LEN(9),
625+
0x00, GIP_MOTOR_ALL, 0x00, 0x00, 0x1D, 0x1D, 0xFF, 0x00, 0x00
587626
};
588627

589628
/*
@@ -593,8 +632,8 @@ static const u8 xboxone_rumblebegin_init[] = {
593632
* spin up to enough speed to actually vibrate the gamepad.
594633
*/
595634
static const u8 xboxone_rumbleend_init[] = {
596-
0x09, 0x00, 0x00, 0x09, 0x00, 0x0F, 0x00, 0x00,
597-
0x00, 0x00, 0x00, 0x00, 0x00
635+
GIP_CMD_RUMBLE, 0x00, GIP_SEQ0, GIP_PL_LEN(9),
636+
0x00, GIP_MOTOR_ALL, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
598637
};
599638

600639
/*
@@ -604,14 +643,14 @@ static const u8 xboxone_rumbleend_init[] = {
604643
* packet is going to be sent.
605644
*/
606645
static const struct xboxone_init_packet xboxone_init_packets[] = {
607-
XBOXONE_INIT_PKT(0x0e6f, 0x0165, xboxone_hori_init),
608-
XBOXONE_INIT_PKT(0x0f0d, 0x0067, xboxone_hori_init),
609-
XBOXONE_INIT_PKT(0x0000, 0x0000, xboxone_fw2015_init),
646+
XBOXONE_INIT_PKT(0x0e6f, 0x0165, xboxone_hori_ack_id),
647+
XBOXONE_INIT_PKT(0x0f0d, 0x0067, xboxone_hori_ack_id),
648+
XBOXONE_INIT_PKT(0x0000, 0x0000, xboxone_power_on),
610649
XBOXONE_INIT_PKT(0x045e, 0x02ea, xboxone_s_init),
611650
XBOXONE_INIT_PKT(0x045e, 0x0b00, xboxone_s_init),
612651
XBOXONE_INIT_PKT(0x045e, 0x0b00, extra_input_packet_init),
613-
XBOXONE_INIT_PKT(0x0e6f, 0x0000, xboxone_pdp_init1),
614-
XBOXONE_INIT_PKT(0x0e6f, 0x0000, xboxone_pdp_init2),
652+
XBOXONE_INIT_PKT(0x0e6f, 0x0000, xboxone_pdp_led_on),
653+
XBOXONE_INIT_PKT(0x0e6f, 0x0000, xboxone_pdp_auth),
615654
XBOXONE_INIT_PKT(0x24c6, 0x541a, xboxone_rumblebegin_init),
616655
XBOXONE_INIT_PKT(0x24c6, 0x542a, xboxone_rumblebegin_init),
617656
XBOXONE_INIT_PKT(0x24c6, 0x543a, xboxone_rumblebegin_init),
@@ -928,19 +967,19 @@ static void xpadone_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char
928967
bool do_sync = false;
929968

930969
/* the xbox button has its own special report */
931-
if (data[0] == 0X07) {
970+
if (data[0] == GIP_CMD_VIRTUAL_KEY) {
932971
/*
933972
* The Xbox One S controller requires these reports to be
934973
* acked otherwise it continues sending them forever and
935974
* won't report further mode button events.
936975
*/
937-
if (data[1] == 0x30)
976+
if (data[1] == (GIP_OPT_ACK | GIP_OPT_INTERNAL))
938977
xpadone_ack_mode_report(xpad, data[2]);
939978

940979
input_report_key(dev, BTN_MODE, data[4] & BIT(0));
941980

942981
do_sync = true;
943-
} else if (data[0] == 0X0C) {
982+
} else if (data[0] == GIP_CMD_FIRMWARE) {
944983
/* Some packet formats force us to use this separate to poll paddle inputs */
945984
if (xpad->packet_type == PKT_XBE2_FW_5_11) {
946985
/* Mute paddles if controller is in a custom profile slot
@@ -958,7 +997,7 @@ static void xpadone_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char
958997

959998
do_sync = true;
960999
}
961-
} else if (data[0] == 0X20) { /* The main valid packet type for inputs */
1000+
} else if (data[0] == GIP_CMD_INPUT) { /* The main valid packet type for inputs */
9621001
/* menu/view buttons */
9631002
input_report_key(dev, BTN_START, data[4] & BIT(2));
9641003
input_report_key(dev, BTN_SELECT, data[4] & BIT(3));
@@ -1470,8 +1509,8 @@ static void xpadone_ack_mode_report(struct usb_xpad *xpad, u8 seq_num)
14701509
struct xpad_output_packet *packet =
14711510
&xpad->out_packets[XPAD_OUT_CMD_IDX];
14721511
static const u8 mode_report_ack[] = {
1473-
0x01, 0x20, 0x00, 0x09, 0x00, 0x07, 0x20, 0x02,
1474-
0x00, 0x00, 0x00, 0x00, 0x00
1512+
GIP_CMD_ACK, GIP_OPT_INTERNAL, GIP_SEQ0, GIP_PL_LEN(9),
1513+
0x00, GIP_CMD_VIRTUAL_KEY, GIP_OPT_INTERNAL, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00
14751514
};
14761515

14771516
spin_lock_irqsave(&xpad->odata_lock, flags);
@@ -1549,14 +1588,14 @@ static int xpad_play_effect(struct input_dev *dev, void *data, struct ff_effect
15491588
break;
15501589

15511590
case XTYPE_XBOXONE:
1552-
packet->data[0] = 0x09; /* activate rumble */
1591+
packet->data[0] = GIP_CMD_RUMBLE; /* activate rumble */
15531592
packet->data[1] = 0x00;
15541593
packet->data[2] = xpad->odata_serial++;
1555-
packet->data[3] = 0x09;
1594+
packet->data[3] = GIP_PL_LEN(9);
15561595
packet->data[4] = 0x00;
1557-
packet->data[5] = 0x0F;
1558-
packet->data[6] = 0x00;
1559-
packet->data[7] = 0x00;
1596+
packet->data[5] = GIP_MOTOR_ALL;
1597+
packet->data[6] = 0x00; /* left trigger */
1598+
packet->data[7] = 0x00; /* right trigger */
15601599
packet->data[8] = strong / 512; /* left actuator */
15611600
packet->data[9] = weak / 512; /* right actuator */
15621601
packet->data[10] = 0xFF; /* on period */

0 commit comments

Comments
 (0)