Skip to content

Commit a977cad

Browse files
Wolfieee WolfCalcProgrammer1
authored andcommitted
Add AMBXController for Philips amBX Gaming lights
1 parent 381069a commit a977cad

File tree

5 files changed

+552
-0
lines changed

5 files changed

+552
-0
lines changed
Lines changed: 195 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,195 @@
1+
/*---------------------------------------------------------*\
2+
| AMBXController.cpp |
3+
| |
4+
| Driver for Philips amBX Gaming lights |
5+
| |
6+
| This file is part of the OpenRGB project |
7+
| SPDX-License-Identifier: GPL-2.0-only |
8+
\*---------------------------------------------------------*/
9+
10+
#include "AMBXController.h"
11+
#include "LogManager.h"
12+
#include "StringUtils.h"
13+
#include <cstring>
14+
#include <thread>
15+
#include <chrono>
16+
17+
AMBXController::AMBXController(const char* path)
18+
{
19+
initialized = false;
20+
usb_context = nullptr;
21+
dev_handle = nullptr;
22+
23+
location = "USB: ";
24+
location += path;
25+
26+
// Initialize libusb in this instance
27+
if(libusb_init(&usb_context) < 0)
28+
{
29+
return;
30+
}
31+
32+
// Get the device list
33+
libusb_device** device_list;
34+
ssize_t device_count = libusb_get_device_list(usb_context, &device_list);
35+
36+
if(device_count < 0)
37+
{
38+
return;
39+
}
40+
41+
for(ssize_t i = 0; i < device_count; i++)
42+
{
43+
libusb_device* device = device_list[i];
44+
struct libusb_device_descriptor desc;
45+
46+
if(libusb_get_device_descriptor(device, &desc) != LIBUSB_SUCCESS)
47+
{
48+
continue;
49+
}
50+
51+
if(desc.idVendor == AMBX_VID && desc.idProduct == AMBX_PID)
52+
{
53+
uint8_t bus = libusb_get_bus_number(device);
54+
uint8_t address = libusb_get_device_address(device);
55+
56+
char current_path[32];
57+
snprintf(current_path, sizeof(current_path), "%d-%d", bus, address);
58+
59+
if(strcmp(path, current_path) == 0)
60+
{
61+
// Try to open this device
62+
if(libusb_open(device, &dev_handle) != LIBUSB_SUCCESS)
63+
{
64+
continue;
65+
}
66+
67+
// Try to detach the kernel driver if attached
68+
if(libusb_kernel_driver_active(dev_handle, 0))
69+
{
70+
libusb_detach_kernel_driver(dev_handle, 0);
71+
}
72+
73+
// Set auto-detach for Windows compatibility
74+
libusb_set_auto_detach_kernel_driver(dev_handle, 1);
75+
76+
// Claim the interface
77+
if(libusb_claim_interface(dev_handle, 0) != LIBUSB_SUCCESS)
78+
{
79+
libusb_close(dev_handle);
80+
dev_handle = nullptr;
81+
continue;
82+
}
83+
84+
// Get string descriptor for serial number if available
85+
if(desc.iSerialNumber != 0)
86+
{
87+
unsigned char serial_str[256];
88+
int serial_result = libusb_get_string_descriptor_ascii(dev_handle, desc.iSerialNumber,
89+
serial_str, sizeof(serial_str));
90+
if(serial_result > 0)
91+
{
92+
serial = std::string(reinterpret_cast<char*>(serial_str), serial_result);
93+
}
94+
}
95+
96+
// Successfully opened and claimed the device
97+
initialized = true;
98+
break;
99+
}
100+
}
101+
}
102+
103+
libusb_free_device_list(device_list, 1);
104+
}
105+
106+
AMBXController::~AMBXController()
107+
{
108+
if(initialized)
109+
{
110+
// Turn off all lights before closing
111+
unsigned int led_ids[5] =
112+
{
113+
AMBX_LIGHT_LEFT,
114+
AMBX_LIGHT_RIGHT,
115+
AMBX_LIGHT_WALL_LEFT,
116+
AMBX_LIGHT_WALL_CENTER,
117+
AMBX_LIGHT_WALL_RIGHT
118+
};
119+
120+
RGBColor colors[5] = { 0, 0, 0, 0, 0 };
121+
SetLEDColors(led_ids, colors, 5);
122+
}
123+
124+
if(dev_handle != nullptr)
125+
{
126+
// Release the interface
127+
libusb_release_interface(dev_handle, 0);
128+
129+
// Close the device
130+
libusb_close(dev_handle);
131+
dev_handle = nullptr;
132+
}
133+
134+
if(usb_context != nullptr)
135+
{
136+
libusb_exit(usb_context);
137+
usb_context = nullptr;
138+
}
139+
}
140+
141+
std::string AMBXController::GetDeviceLocation()
142+
{
143+
return location;
144+
}
145+
146+
std::string AMBXController::GetSerialString()
147+
{
148+
return serial;
149+
}
150+
151+
bool AMBXController::IsInitialized()
152+
{
153+
return initialized;
154+
}
155+
156+
void AMBXController::SendPacket(unsigned char* packet, unsigned int size)
157+
{
158+
if(!initialized || dev_handle == nullptr)
159+
{
160+
return;
161+
}
162+
163+
int actual_length = 0;
164+
libusb_interrupt_transfer(dev_handle, AMBX_ENDPOINT_OUT, packet, size, &actual_length, 100);
165+
}
166+
167+
void AMBXController::SetLEDColor(unsigned int led, RGBColor color)
168+
{
169+
if(!initialized)
170+
{
171+
return;
172+
}
173+
174+
unsigned char color_buf[6] =
175+
{
176+
AMBX_PACKET_HEADER,
177+
static_cast<unsigned char>(led),
178+
AMBX_SET_COLOR,
179+
RGBGetRValue(color),
180+
RGBGetGValue(color),
181+
RGBGetBValue(color)
182+
};
183+
184+
SendPacket(color_buf, 6);
185+
186+
std::this_thread::sleep_for(std::chrono::milliseconds(2));
187+
}
188+
189+
void AMBXController::SetLEDColors(unsigned int* leds, RGBColor* colors, unsigned int count)
190+
{
191+
for(unsigned int i = 0; i < count; i++)
192+
{
193+
SetLEDColor(leds[i], colors[i]);
194+
}
195+
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
/*---------------------------------------------------------*\
2+
| AMBXController.h |
3+
| |
4+
| Driver for Philips amBX Gaming lights |
5+
| |
6+
| This file is part of the OpenRGB project |
7+
| SPDX-License-Identifier: GPL-2.0-only |
8+
\*---------------------------------------------------------*/
9+
10+
#pragma once
11+
12+
#include "RGBController.h"
13+
#include <string>
14+
15+
#ifdef _WIN32
16+
#include "dependencies/libusb-1.0.27/include/libusb.h"
17+
#else
18+
#include <libusb.h>
19+
#endif
20+
21+
#define AMBX_VID 0x0471
22+
#define AMBX_PID 0x083F
23+
#define AMBX_ENDPOINT_OUT 0x02
24+
#define AMBX_PACKET_HEADER 0xA1
25+
#define AMBX_SET_COLOR 0x03
26+
27+
enum
28+
{
29+
AMBX_LIGHT_LEFT = 0x0B,
30+
AMBX_LIGHT_RIGHT = 0x1B,
31+
AMBX_LIGHT_WALL_LEFT = 0x2B,
32+
AMBX_LIGHT_WALL_CENTER = 0x3B,
33+
AMBX_LIGHT_WALL_RIGHT = 0x4B
34+
};
35+
36+
class AMBXController
37+
{
38+
public:
39+
AMBXController(const char* path);
40+
~AMBXController();
41+
42+
std::string GetDeviceLocation();
43+
std::string GetSerialString();
44+
45+
bool IsInitialized();
46+
void SetLEDColor(unsigned int led, RGBColor color);
47+
void SetLEDColors(unsigned int* leds, RGBColor* colors, unsigned int count);
48+
49+
private:
50+
libusb_context* usb_context;
51+
libusb_device_handle* dev_handle;
52+
std::string location;
53+
std::string serial;
54+
bool initialized;
55+
56+
void SendPacket(unsigned char* packet, unsigned int size);
57+
};
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
/*---------------------------------------------------------*\
2+
| AMBXControllerDetect.cpp |
3+
| |
4+
| Detector for Philips amBX Gaming lights |
5+
| |
6+
| This file is part of the OpenRGB project |
7+
| SPDX-License-Identifier: GPL-2.0-only |
8+
\*---------------------------------------------------------*/
9+
10+
#include "Detector.h"
11+
#include "AMBXController.h"
12+
#include "RGBController.h"
13+
#include "RGBController_AMBX.h"
14+
15+
#ifdef _WIN32
16+
#include "dependencies/libusb-1.0.27/include/libusb.h"
17+
#else
18+
#include <libusb.h>
19+
#endif
20+
21+
/******************************************************************************************\
22+
* *
23+
* DetectAMBXControllers *
24+
* *
25+
* Detect Philips amBX Gaming devices *
26+
* *
27+
\******************************************************************************************/
28+
29+
void DetectAMBXControllers()
30+
{
31+
libusb_context* ctx = NULL;
32+
33+
if(libusb_init(&ctx) < 0)
34+
{
35+
return;
36+
}
37+
38+
libusb_device** devs;
39+
ssize_t num_devs = libusb_get_device_list(ctx, &devs);
40+
41+
if(num_devs <= 0)
42+
{
43+
libusb_exit(ctx);
44+
return;
45+
}
46+
47+
for(ssize_t i = 0; i < num_devs; i++)
48+
{
49+
libusb_device* dev = devs[i];
50+
libusb_device_descriptor desc;
51+
52+
if(libusb_get_device_descriptor(dev, &desc) != 0)
53+
{
54+
continue;
55+
}
56+
57+
if(desc.idVendor == AMBX_VID && desc.idProduct == AMBX_PID)
58+
{
59+
uint8_t bus = libusb_get_bus_number(dev);
60+
uint8_t address = libusb_get_device_address(dev);
61+
char device_path[32];
62+
snprintf(device_path, sizeof(device_path), "%d-%d", bus, address);
63+
64+
// Use the AMBXController to handle opening and initializing
65+
AMBXController* controller = new AMBXController(device_path);
66+
67+
if(controller->IsInitialized())
68+
{
69+
RGBController_AMBX* rgb_controller = new RGBController_AMBX(controller);
70+
ResourceManager::get()->RegisterRGBController(rgb_controller);
71+
}
72+
else
73+
{
74+
delete controller;
75+
}
76+
}
77+
}
78+
79+
libusb_free_device_list(devs, 1);
80+
libusb_exit(ctx);
81+
}
82+
83+
REGISTER_DETECTOR("Philips amBX", DetectAMBXControllers);

0 commit comments

Comments
 (0)