Browse Source

Tries to emulate Taranis HID descriptor. Didn't work for problematic programs, either.

Thomas Buck 7 years ago
parent
commit
ded6ec74c5
No account linked to committer's email address
1 changed files with 107 additions and 50 deletions
  1. 107
    50
      src/foohid.c

+ 107
- 50
src/foohid.c View File

@@ -12,6 +12,7 @@
12 12
 #include <signal.h>
13 13
 #include <string.h>
14 14
 #include <unistd.h>
15
+#include <stdlib.h>
15 16
 
16 17
 #include <IOKit/IOKitLib.h>
17 18
 
@@ -33,16 +34,25 @@
33 34
 #define FOOHID_DESTROY 1
34 35
 #define FOOHID_SEND 2
35 36
 #define FOOHID_LIST 3
36
-#define VIRTUAL_DEVICE_NAME "Virtual Serial Transmitter"
37
-#define VIRTUAL_DEVICE_SERIAL "SN 123456"
37
+
38
+#define VIRTUAL_DEVICE_NAME "FrSky Joystick"
39
+#define VIRTUAL_DEVICE_SERIAL "00000000001B"
40
+#define VIRTUAL_VID 0x0483
41
+#define VIRTUAL_PID 0x5710
38 42
 
39 43
 struct gamepad_report_t {
40
-    int16_t leftX;
41
-    int16_t leftY;
42
-    int16_t rightX;
43
-    int16_t rightY;
44
-    int16_t aux1;
45
-    int16_t aux2;
44
+    //bit 0 - button 1, bit 1 - button 2, ..., mapped to channels 9-16, on if channel > 0
45
+    uint8_t buttons1;
46
+    uint8_t buttons2; // mapped to channels 17-24, on if channel > 0
47
+    uint8_t buttons3; // mapped to channels 25-32, on if channel > 0
48
+    int8_t X;  //analog value, mapped to channel 1
49
+    int8_t Y;  //analog value, mapped to channel 2
50
+    int8_t Z;  //analog value, mapped to channel 3
51
+    int8_t Rx; //analog value, mapped to channel 4
52
+    int8_t Ry; //analog value, mapped to channel 5
53
+    int8_t Rz; //analog value, mapped to channel 6
54
+    int8_t S1; //analog value, mapped to channel 7
55
+    int8_t S2; //analog value, mapped to channel 8
46 56
 };
47 57
 
48 58
 static int running = 1;
@@ -53,33 +63,89 @@ static io_connect_t connect;
53 63
 static uint64_t input[input_count];
54 64
 static struct gamepad_report_t gamepad;
55 65
 
56
-/*
57
- * This is my USB HID Descriptor for this emulated Gamepad.
58
- * For more informations refer to:
59
- * http://eleccelerator.com/tutorial-about-usb-hid-report-descriptors/
60
- * http://www.usb.org/developers/hidpage#HID%20Descriptor%20Tool
61
- */
62
-static char report_descriptor[36] = {
63
-    0x05, 0x01,                    // USAGE_PAGE (Generic Desktop)
64
-    0x09, 0x05,                    // USAGE (Game Pad)
65
-    0xa1, 0x01,                    // COLLECTION (Application)
66
-    0xa1, 0x00,                    //   COLLECTION (Physical)
66
+// From Taranis:
67
+// https://github.com/opentx/opentx/blob/03b65b06b6cec2d2b64dfb0f436eda155274841d/radio/src/targets/common/arm/stm32/usbd_hid_joystick.c
68
+static const uint8_t report_descriptor[] = {
67 69
     0x05, 0x01,                    //     USAGE_PAGE (Generic Desktop)
68
-    0x09, 0x30,                    //     USAGE (X)
69
-    0x09, 0x31,                    //     USAGE (Y)
70
-    0x09, 0x32,                    //     USAGE (Z)
71
-    0x09, 0x33,                    //     USAGE (Rx)
72
-    0x09, 0x34,                    //     USAGE (Ry)
73
-    0x09, 0x35,                    //     USAGE (Rz)
74
-    0x16, 0x01, 0xfe,              //     LOGICAL_MINIMUM (-511)
75
-    0x26, 0xff, 0x01,              //     LOGICAL_MAXIMUM (511)
76
-    0x75, 0x10,                    //     REPORT_SIZE (16)
77
-    0x95, 0x06,                    //     REPORT_COUNT (6)
78
-    0x81, 0x02,                    //     INPUT (Data,Var,Abs)
79
-    0xc0,                          //     END_COLLECTION
80
-    0xc0                           // END_COLLECTION
70
+    0x09, 0x05,                    //     USAGE (Game Pad)
71
+    0xa1, 0x01,                    //     COLLECTION (Application)
72
+    0xa1, 0x00,                    //       COLLECTION (Physical)
73
+    0x05, 0x09,                    //         USAGE_PAGE (Button)
74
+    0x19, 0x01,                    //         USAGE_MINIMUM (Button 1)
75
+    0x29, 0x18,                    //         USAGE_MAXIMUM (Button 24)
76
+    0x15, 0x00,                    //         LOGICAL_MINIMUM (0)
77
+    0x25, 0x01,                    //         LOGICAL_MAXIMUM (1)
78
+    0x95, 0x18,                    //         REPORT_COUNT (24)
79
+    0x75, 0x01,                    //         REPORT_SIZE (1)
80
+    0x81, 0x02,                    //         INPUT (Data,Var,Abs)
81
+    0x05, 0x01,                    //         USAGE_PAGE (Generic Desktop)
82
+    0x09, 0x30,                    //         USAGE (X)
83
+    0x09, 0x31,                    //         USAGE (Y)
84
+    0x09, 0x32,                    //         USAGE (Z)
85
+    0x09, 0x33,                    //         USAGE (Rx)
86
+    0x09, 0x34,                    //         USAGE (Ry)
87
+    0x09, 0x35,                    //         USAGE (Rz)
88
+    0x09, 0x36,                    //         USAGE (Slider)
89
+    0x09, 0x36,                    //         USAGE (Slider)
90
+    0x15, 0x81,                    //         LOGICAL_MINIMUM (-127)
91
+    0x25, 0x7f,                    //         LOGICAL_MAXIMUM (127)
92
+    0x75, 0x08,                    //         REPORT_SIZE (8)
93
+    0x95, 0x08,                    //         REPORT_COUNT (8)
94
+    0x81, 0x02,                    //         INPUT (Data,Var,Abs)
95
+    0xc0,                          //       END_COLLECTION
96
+    0xc0                           //     END_COLLECTION
81 97
 };
82 98
 
99
+static int foohidPrintDevices() {
100
+    uint32_t output_count = 2;
101
+    uint64_t output[2] = { 0, 0 };
102
+
103
+	uint16_t buf_len = 4096;
104
+	char *buf = malloc(buf_len);
105
+	if (!buf) {
106
+        printf("memory error\n");
107
+		return 1;
108
+	}
109
+
110
+    uint64_t input[2];
111
+	while (1) {
112
+        input[0] = (uint64_t) buf;
113
+        input[1] = (uint64_t) buf_len;
114
+        kern_return_t ret = IOConnectCallScalarMethod(connect, FOOHID_LIST, input, 2, output, &output_count);
115
+        if (ret != KERN_SUCCESS) {
116
+            free(buf);
117
+            printf("unable to list hid devices\n");
118
+            return 1;
119
+        }
120
+
121
+        // all is fine
122
+        if (output[0] == 0) {
123
+            printf("--\n");
124
+            printf("fooHID devices: (%llu)\n", output[1]);
125
+            char *ptr = buf;
126
+            for(uint64_t i = 0; i < output[1]; i++) {
127
+                printf("%s\n", ptr);
128
+                ptr += strlen(ptr) + 1;
129
+            }
130
+            printf("--\n");
131
+            free(buf);
132
+            return ret;
133
+        }
134
+
135
+        // realloc memory
136
+        buf_len = output[0];
137
+        char *tmp = realloc(buf, buf_len);
138
+        if (!tmp) {
139
+            free(buf);
140
+            printf("unable to allocate memory\n");
141
+            return 1;
142
+        }
143
+        buf = tmp;
144
+	}
145
+
146
+    return 0;
147
+}
148
+
83 149
 static int foohidInit() {
84 150
     printf("Searching for foohid Kernel extension...\n");
85 151
 
@@ -105,6 +171,7 @@ static int foohidInit() {
105 171
         return 1;
106 172
     }
107 173
 
174
+    //foohidPrintDevices();
108 175
     printf("Creating virtual HID device...\n");
109 176
 
110 177
     input[0] = (uint64_t)strdup(VIRTUAL_DEVICE_NAME);
@@ -116,8 +183,8 @@ static int foohidInit() {
116 183
     input[4] = (uint64_t)strdup(VIRTUAL_DEVICE_SERIAL);
117 184
     input[5] = strlen((char*)input[4]);
118 185
 
119
-    input[6] = (uint64_t)2; // vendor ID
120
-    input[7] = (uint64_t)3; // device ID
186
+    input[6] = (uint64_t)VIRTUAL_VID;
187
+    input[7] = (uint64_t)VIRTUAL_PID;
121 188
 
122 189
     ret = IOConnectCallScalarMethod(connect, FOOHID_CREATE, input, input_count, NULL, 0);
123 190
     if (ret != KERN_SUCCESS) {
@@ -144,22 +211,12 @@ static void foohidSend(uint16_t *data) {
144 211
         }
145 212
     }
146 213
 
147
-    gamepad.leftX = data[3] - 511;
148
-    gamepad.leftY = data[2] - 511;
149
-    gamepad.rightX = data[0] - 511;
150
-    gamepad.rightY = data[1] - 511;
151
-    gamepad.aux1 = data[4] - 511;
152
-    gamepad.aux2 = data[5] - 511;
153
-
154
-    /*
155
-    printf("Sending data packet:\n");
156
-    printf("Left X: %d\n", gamepad.leftX);
157
-    printf("Left Y: %d\n", gamepad.leftY);
158
-    printf("Right X: %d\n", gamepad.rightX);
159
-    printf("Right Y: %d\n", gamepad.rightY);
160
-    printf("Aux 1: %d\n", gamepad.aux1);
161
-    printf("Aux 2: %d\n", gamepad.aux2);
162
-    */
214
+    gamepad.X = (data[3] - 511) / 4;
215
+    gamepad.Y = (data[2] - 511) / 4;
216
+    gamepad.Z = (data[0] - 511) / 4;
217
+    gamepad.Rx = (data[1] - 511) / 4;
218
+    gamepad.Ry = (data[4] - 511) / 4;
219
+    gamepad.Rz = (data[5] - 511) / 4;
163 220
 
164 221
     input[2] = (uint64_t)&gamepad;
165 222
     input[3] = sizeof(struct gamepad_report_t);

Loading…
Cancel
Save