Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add support of Xbox Wireless Adapter #1415

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
[submodule "app/src/main/jni/moonlight-core/moonlight-common-c"]
path = app/src/main/jni/moonlight-core/moonlight-common-c
url = https://github.com/moonlight-stream/moonlight-common-c.git
[submodule "app/src/main/jni/libusb"]
path = app/src/main/jni/libusb
url = https://github.com/libusb/libusb.git
1 change: 1 addition & 0 deletions app/proguard-rules.pro
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

# Our code
-keep class com.limelight.binding.input.evdev.* {*;}
-keep class com.limelight.binding.input.driver.* {*;}

# Moonlight common
-keep class com.limelight.nvstream.jni.* {*;}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ public class UsbDriverService extends Service implements UsbDriverListener {
private UsbDriverStateListener stateListener;
private int nextDeviceId;

private final ArrayList<XboxWirelessDongle> xboxWirelessDongles = new ArrayList<>();

@Override
public void reportControllerState(int controllerId, int buttonFlags, float leftStickX, float leftStickY,
float rightStickX, float rightStickY, float leftTrigger, float rightTrigger) {
Expand Down Expand Up @@ -182,6 +184,15 @@ private void handleUsbDeviceState(UsbDevice device) {
return;
}

if (XboxWirelessDongle.canClaimDevice(device)) {
var dongle = new XboxWirelessDongle(device, connection, this);
if(!dongle.start()) {
connection.close();
return;
}
xboxWirelessDongles.add(dongle);
return;
}

AbstractController controller;

Expand Down Expand Up @@ -278,7 +289,8 @@ public static boolean shouldClaimDevice(UsbDevice device, boolean claimAllAvaila
return ((!kernelSupportsXboxOne() || !isRecognizedInputDevice(device) || claimAllAvailable) && XboxOneController.canClaimDevice(device)) ||
((!isRecognizedInputDevice(device) || claimAllAvailable) && Xbox360Controller.canClaimDevice(device)) ||
// We must not call isRecognizedInputDevice() because wireless controllers don't share the same product ID as the dongle
((!kernelSupportsXbox360W() || claimAllAvailable) && Xbox360WirelessDongle.canClaimDevice(device));
((!kernelSupportsXbox360W() || claimAllAvailable) && Xbox360WirelessDongle.canClaimDevice(device) ||
XboxWirelessDongle.canClaimDevice(device));
}

@SuppressLint("UnspecifiedRegisterReceiverFlag")
Expand Down Expand Up @@ -319,6 +331,12 @@ private void stop() {
// Stop the attachment receiver
unregisterReceiver(receiver);

// Stop all dongles
while (xboxWirelessDongles.size() > 0) {
// Stop and remove the dongle
xboxWirelessDongles.remove(0).stop();
}

// Stop all controllers
while (controllers.size() > 0) {
// Stop and remove the controller
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package com.limelight.binding.input.driver;

public class XboxWirelessController extends AbstractController{
static {
System.loadLibrary("xow-driver");
}

private final long handle;

public XboxWirelessController(int deviceId, UsbDriverListener listener, int vendorId, int productId, long handle) {
super(deviceId, listener, vendorId, productId);
this.handle = handle;
registerNative(this.handle);
}

@Override
public boolean start() {
// do nothing since mt driver will handle it.
return true;
}

@Override
public void stop() {
// do nothing since mt driver will handle it.
}

@Override
public void rumble(short lowFreqMotor, short highFreqMotor) {
sendRumble(handle, lowFreqMotor, highFreqMotor);
}

@Override
public void rumbleTriggers(short leftTrigger, short rightTrigger) {
sendrumbleTriggers(handle, leftTrigger, rightTrigger);
}

public void updateInput(int buttons,short triggerLeft, short triggerRight,
short stickLeftX, short stickLeftY,
short stickRightX, short stickRightY) {
buttonFlags = buttons;
leftTrigger = triggerLeft / 1023.0f;
rightTrigger = triggerRight / 1023.0f;
leftStickX = stickLeftX / 32767.0f;
leftStickY = stickLeftY / -32767.0f;
rightStickX = stickRightX / 32767.0f;
rightStickY = stickRightY / -32767.0f;

reportInput();
}

native void registerNative(long handle);
native void sendRumble(long handle, short lowFreqMotor, short highFreqMotor);
native void sendrumbleTriggers(long handle, short leftTrigger, short rightTrigger);

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
package com.limelight.binding.input.driver;

import android.hardware.usb.UsbConstants;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbDeviceConnection;
import android.util.Pair;

import com.limelight.LimeLog;
import com.limelight.binding.input.driver.UsbDriverListener;

import java.util.HashMap;
import java.util.Map;

public class XboxWirelessDongle {
private UsbDriverListener listener;
protected final UsbDevice device;
protected final UsbDeviceConnection connection;

private long driverHandle;

private Map<Integer, AbstractController> controllers = new HashMap<>();

static {
System.loadLibrary("xow-driver");
}

public XboxWirelessDongle(UsbDevice device, UsbDeviceConnection connection, UsbDriverListener listener) {
this.device = device;
this.connection = connection;
this.listener = listener;
this.driverHandle = -1;
}

public boolean start() {
if(this.driverHandle != -1) {
return false; //we already started;
}
this.driverHandle = createDriver(connection.getFileDescriptor());
boolean ok = startDriver(this.driverHandle, "");
if(!ok) {
LimeLog.info("xbox wireless dongle driver failed to start");
destroyDriver(this.driverHandle);
this.driverHandle = -1;
return false;
}
return true;
}

public void stop() {
if(this.driverHandle == -1) {
return; //we already cleaned;
}
stopDriver(this.driverHandle);
destroyDriver(this.driverHandle);
for(var i: controllers.keySet()) {
this.listener.deviceRemoved(controllers.remove(i));
}
}

public static boolean canClaimDevice(UsbDevice device) {
if (device.getVendorId() != 0x045e) {
return false;
}
if (device.getProductId() != 0x02e6 && // Older one
device.getProductId() != 0x02fe // new one
) {
return false;
}

return true;
}

public void addNewController(int id, long handle, short vid, short pid){
var controller = new XboxWirelessController(id + 0x045e0000, listener, vid, pid, handle);
controllers.put(id, controller);
this.listener.deviceAdded(controller);
}

public void removeController(int id) {
var controller = controllers.get(id);
if(controller == null) {
return;
}
controllers.remove(id);
this.listener.deviceRemoved(controller);
}

private native long createDriver(int fd);
private native boolean startDriver(long handle, String fwPath);
private native void stopDriver(long handle);
private native void destroyDriver(long handle);
}
6 changes: 5 additions & 1 deletion app/src/main/jni/Android.mk
Original file line number Diff line number Diff line change
@@ -1 +1,5 @@
include $(call all-subdir-makefiles)
LOCAL_PATH := $(call my-dir)
SUB_PROJECTS := $(call all-subdir-makefiles)

include $(LOCAL_PATH)/libusb/android/jni/libusb.mk
include $(SUB_PROJECTS)
2 changes: 2 additions & 0 deletions app/src/main/jni/Application.mk
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,5 @@ APP_PLATFORM := android-21

# We support 16KB pages
APP_SUPPORT_FLEXIBLE_PAGE_SIZES := true

APP_STL := c++_shared
1 change: 1 addition & 0 deletions app/src/main/jni/libusb
Submodule libusb added at 467b6a
24 changes: 24 additions & 0 deletions app/src/main/jni/xow_driver/Android.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Android.mk for xbox wireless driver
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := xow-driver
LOCAL_SRC_FILES := \
xow_driver_jni.cpp \
dongle/firmware.cpp \
dongle/usb.cpp \
dongle/mt76.cpp \
dongle/dongle.cpp \
utils/log.cpp \
controller/controller.cpp \
controller/gip.cpp

LOCAL_C_INCLUDES := $(LOCAL_PATH) $(LIBUSB_ROOT_ABS)
LOCAL_SHARED_LIBRARIES += libusb1.0
LOCAL_LDLIBS := -llog

ifeq ($(NDK_DEBUG),1)
LOCAL_CFLAGS += -D_DEBUG
endif
include $(BUILD_SHARED_LIBRARY)


Loading