Okay so here is the code: (Combined in one file)
Have attached the zip file at the end of the post.
Required untouched functions from the
wheels.c.
I have removed the extra functions.
#include "writeToJoystickDriver.h"
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <linux/input.h>
#define TRANSFER_WAIT_TIMEOUT_MS 5000
#define CONFIGURE_WAIT_SEC 3
#define UDEV_WAIT_SEC 2
int get_nativemode_cmd_DFGT (cmdstruct *c)
{
c->cmds[0][0] = 0xf8;
c->cmds[0][1] = 0x0a;
c->cmds[0][2] = 0x00;
c->cmds[0][3] = 0x00;
c->cmds[0][4] = 0x00;
c->cmds[0][5] = 0x00;
c->cmds[0][6] = 0x00;
c->cmds[0][7] = 0x00;
c->cmds[1][0] = 0xf8;
c->cmds[1][1] = 0x09;
c->cmds[1][2] = 0x03;
c->cmds[1][3] = 0x01;
c->cmds[1][4] = 0x00;
c->cmds[1][5] = 0x00;
c->cmds[1][6] = 0x00;
c->cmds[1][7] = 0x00;
c->numCmds = 2;
return 0;
}
/* used by DFGT, G25, G27 */
int get_range_cmd(cmdstruct *c, int range)
{
c->cmds[0][0] = 0xf8;
c->cmds[0][1] = 0x81;
c->cmds[0][2] = range & 0x00ff;
c->cmds[0][3] = (range & 0xff00)>>8;
c->cmds[0][4] = 0x00;
c->cmds[0][5] = 0x00;
c->cmds[0][6] = 0x00;
c->cmds[0][7] = 0x00;
c->numCmds = 1;
return 0;
}
/* used by all wheels */
int get_autocenter_cmd(cmdstruct *c, int centerforce, int rampspeed)
{
c->cmds[0][0] = 0xfe;
c->cmds[0][1] = 0x0d;
c->cmds[0][2] = rampspeed & 0x0f;
c->cmds[0][3] = rampspeed & 0x0f;
c->cmds[0][4] = centerforce & 0xff;
c->cmds[0][5] = 0x00;
c->cmds[0][6] = 0x00;
c->cmds[0][7] = 0x00;
c->numCmds = 1;
return 0;
}
The major three functions of
wheelfunctions.c. These are the ones needed for setting autocenter, nativemode, and the wheel name and range. I have removed the extra ones here too.
void [COLOR="Red"][B]print_cmd[/B][/COLOR](char *result, unsigned char cmd[8]) {
sprintf(result, "%02X %02X %02X %02X %02X %02X %02X %02X", cmd[0], cmd[1], cmd[2], cmd[3], cmd[4], cmd[5], cmd[6], cmd[7]);
}
int [B][COLOR="Red"]send_command[/COLOR][/B](libusb_device_handle *handle, cmdstruct command ) {
if (command.numCmds == 0) {
printf( "send_command: Empty command provided! Not sending anything...\n");
return 0;
}
int stat;
stat = libusb_detach_kernel_driver(handle, 0);
if ((stat < 0 ))// || verbose_flag)
perror("Detach kernel driver");
stat = libusb_claim_interface( handle, 0 );
if ( (stat < 0))
{ //|| verbose_flag)
perror("Claiming USB interface");
}
int transferred = 0;
// send all command strings provided in command
int cmdCount;
for (cmdCount=0; cmdCount < command.numCmds; cmdCount++) {
if (1){//verbose_flag) {
char raw_string[255];
print_cmd(raw_string, command.cmds[cmdCount]);
printf("\tSending string: \"%s\"\n", raw_string);
}
stat = libusb_interrupt_transfer( handle, 1, command.cmds[cmdCount], sizeof( command.cmds[cmdCount] ), &transferred, TRANSFER_WAIT_TIMEOUT_MS );
/*if ( stat < 0) {
//|| verbose_flag)
perror("Sending USB command");
}*/
if ( stat < 0) perror("Sending USB command");
}
/* In case the command just sent caused the device to switch from restricted mode to native mode
* the following two commands will fail due to invalid device handle (because the device changed
* its pid on the USB bus).
* So it is not possible anymore to release the interface and re-attach kernel driver.
* I am not sure if this produces a memory leak within libusb, but i do not think there is another
* solution possible...
*/
stat = libusb_release_interface(handle, 0 );
if (stat != LIBUSB_ERROR_NO_DEVICE) { // silently ignore "No such device" error due to reasons explained above.
if ( (stat < 0)){// || verbose_flag) {
perror("Releasing USB interface.");
}
}
stat = libusb_attach_kernel_driver( handle, 0);
if (stat != LIBUSB_ERROR_NO_DEVICE) { // silently ignore "No such device" error due to reasons explained above.
if ( (stat < 0)){// || verbose_flag) {
perror("Reattaching kernel driver");
}
}
return 0;
}
int [COLOR="Red"][B]set_native_mode[/B][/COLOR](wheelstruct* w)
{
// first check if wheel has restriced/native mode at all
if (w->native_pid == w->restricted_pid) {
printf( "%s is always in native mode.\n", w->name);
return 0;
}
// check if wheel is already in native mode
libusb_device_handle *handle = libusb_open_device_with_vid_pid(NULL, VID_LOGITECH, w->native_pid);
if ( handle != NULL ) {
printf( "Found a %s already in native mode.\n", w->name);
return 0;
}
// try to get handle to device in restricted mode
handle = libusb_open_device_with_vid_pid(NULL, VID_LOGITECH, w->restricted_pid );
if ( handle == NULL ) {
printf( "Can not find %s in restricted mode (PID %x). This should not happen :-(\n", w->name, w->restricted_pid);
return -1;
}
// check if we know how to set native mode
if (!w->get_nativemode_cmd) {
printf( "Sorry, do not know how to set %s into native mode.\n", w->name);
return -1;
}
cmdstruct c;
memset(&c, 0, sizeof(c));
w->get_nativemode_cmd(&c);
send_command(handle, c);
// wait until wheel reconfigures to new PID...
sleep(CONFIGURE_WAIT_SEC);
// If above command was successfully we should now find the wheel in extended mode
handle = libusb_open_device_with_vid_pid(NULL, VID_LOGITECH, w->native_pid);
if ( handle != NULL ) {
printf ( "%s is now set to native mode.\n", w->name);
} else {
// this should not happen, just in case
printf ( "Unable to set %s to native mode.\n", w->name );
return -1;
}
libusb_close(handle);
return 0;
}
short unsigned int [B][COLOR="Red"]clamprange[/COLOR][/B](wheelstruct* w, short unsigned int range)
{
if (range < w->min_rotation) {
printf("Minimum range for %s is %d degrees.\n", w->name, w->min_rotation);
range = w->min_rotation;
}
if (range > w->max_rotation) {
range = w->max_rotation;
printf("Maximum range for %s is %d degrees.\n", w->name, w->max_rotation);
}
return range;
}
int [COLOR="Red"][B]set_range[/B][/COLOR](wheelstruct* w, short unsigned int range)
{
libusb_device_handle *handle = libusb_open_device_with_vid_pid(NULL, VID_LOGITECH, w->native_pid );
if ( handle == NULL ) {
printf ( "%s not found. Make sure it is set to native mode (use --native).\n", w->name);
return -1;
}
if (!w->get_range_cmd) {
printf( "Sorry, do not know how to set rotation range for %s.\n", w->name);
return -1;
}
cmdstruct c;
memset(&c, 0, sizeof(c));
w->get_range_cmd(&c, range);
send_command(handle, c);
printf ("Wheel rotation range of %s is now set to %d degrees.\n", w->name, range);
libusb_close(handle);
return 0;
}
int [B][COLOR="Red"]set_autocenter[/COLOR][/B](wheelstruct* w, int centerforce, int rampspeed)
{
libusb_device_handle *handle = libusb_open_device_with_vid_pid(NULL, VID_LOGITECH, w->native_pid );
if ( handle == NULL ) {
printf ( "%s not found. Make sure it is set to native mode (use --native).\n", w->name);
return -1;
}
if (!w->get_autocenter_cmd) {
printf( "Sorry, do not know how to set autocenter force for %s. Please try generic implementation using --alt_autocenter.\n", w->name);
return -1;
}
cmdstruct c;
memset(&c, 0, sizeof(c));
w->get_autocenter_cmd(&c, centerforce, rampspeed);
send_command(handle, c);
printf ("Autocenter for %s is now set to %d with rampspeed %d.\n", w->name, centerforce, rampspeed);
libusb_close(handle);
return 0;
}
and finally the
main(): The while loop is only for the process running forever.
int main () {
[B]while (1)[/B]
{
unsigned short int range = 0;
unsigned short int centerforce = 0;
char device_file_name[128];
char shortname[255];
memset(device_file_name, 0, sizeof(device_file_name));
range = 900;
centerforce = 0;
strncpy(shortname, "DFGT", 255);
libusb_init(NULL);
libusb_set_debug(0, 3);
wheelstruct* wheel = 0;
// do_validate_wheel
int numWheels = sizeof(wheels)/sizeof(wheelstruct);
int i = 0;
for (i=0; i < numWheels; i++) {
if (strncasecmp(wheels[i].shortname, shortname, 255) == 0) {
// found matching wheel
wheel = &(wheels[i]);
break;
}
}
if (!wheel) {
printf("Wheel \"%s\" not supported. Did you spell the shortname correctly?\n", shortname);
}
/[COLOR="Red"][B]/ do_native
set_native_mode(wheel);
// do_range
set_range(wheel, clamprange(wheel, range));
// do_autocenter
set_autocenter (wheel, centerforce, 0);[/B][/COLOR]
libusb_exit(NULL);
}
return 0;
}