Skip to content
This repository was archived by the owner on Mar 18, 2022. It is now read-only.

Commit bf0fdc2

Browse files
committed
Added NodeBridgeTest3
1 parent b5de151 commit bf0fdc2

5 files changed

Lines changed: 210 additions & 0 deletions

File tree

Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
#include <iostream>
2+
#include <sstream>
3+
#include <mutex>
4+
#include <atomic>
5+
#include <nan.h>
6+
#include <bitset>
7+
#include "GCAdapter.h"
8+
9+
using namespace std;
10+
11+
libusb_device_handle *device_handle = nullptr;
12+
libusb_context *context = nullptr;
13+
14+
uint8_t controller_payload[37];
15+
uint8_t controller_payload_swap[37];
16+
17+
uint8_t endpoint_out = 0;
18+
uint8_t endpoint_in = 0;
19+
20+
int controller_payload_size = 0;
21+
22+
NAN_METHOD(Setup) {
23+
auto return_value = Nan::New<v8::Number>(0);
24+
if(info.Length()>0) {
25+
Nan::ThrowError("Load() must not have arguments");
26+
return;
27+
}
28+
libusb_init(&context);
29+
libusb_device **list;
30+
ssize_t count = libusb_get_device_list(context, &list);
31+
bool case_test = false;
32+
for (int i = 0; i < count && !case_test; i++) {
33+
libusb_device *device = list[i];
34+
case_test = IsAccessible(device);
35+
if (case_test) {
36+
return_value = Nan::New<v8::Number>(AddAdapter(device));
37+
}
38+
}
39+
libusb_free_device_list(list, 1);
40+
info.GetReturnValue().Set(return_value);
41+
}
42+
bool IsAccessible(libusb_device *dev) {
43+
int return_value=0,kernel_value=0;
44+
libusb_device_descriptor descriptor;
45+
return_value = libusb_get_device_descriptor(dev, &descriptor);
46+
if (return_value < 0) {
47+
cout << "Error getting descriptor of USB device. Error code: " << return_value << endl;
48+
return false;
49+
}
50+
51+
if (descriptor.idVendor == GAMECUBE_VID && descriptor.idProduct == GAMECUBE_PID) {
52+
cout << "Found GameCube Adapter" << endl;
53+
}
54+
else {
55+
return false;
56+
}
57+
return_value = libusb_open(dev, &device_handle);
58+
switch (return_value) {
59+
case 0:
60+
cout << "This adapter seems reachable. Trying to reach..." << endl;
61+
break;
62+
case LIBUSB_ERROR_ACCESS:
63+
cout << "LIBUSB_ERROR_ACCESS: gca-node does not have access to this adapter." << endl;
64+
return false;
65+
break;
66+
default:
67+
cout << "gca-node couldn't open this adapter. Error code: " << return_value << endl;
68+
return false;
69+
break;
70+
}
71+
return_value = libusb_kernel_driver_active(device_handle, 0);
72+
if (return_value == 1) {
73+
kernel_value = libusb_detach_kernel_driver(device_handle, 0);
74+
if (kernel_value != 0) {
75+
cout << "gca-node can't attach the kernel of this adapter. Error code:" << return_value << endl;
76+
return false;
77+
}
78+
}
79+
if (return_value == 0 || kernel_value == 0) {
80+
return_value = libusb_claim_interface(device_handle, 0);
81+
if (return_value != 0) {
82+
cout << "gca-node couldn't claim interface 0 of adapter. Error code:" << return_value << endl;
83+
}
84+
return return_value == 0;
85+
}
86+
return false;
87+
}
88+
int AddAdapter(libusb_device *dev) {
89+
int endpoint_number = 0;
90+
libusb_config_descriptor *config = nullptr;
91+
libusb_get_config_descriptor(dev, 0, &config);
92+
for (uint8_t iface=0; iface < config->bNumInterfaces; iface++) {
93+
const libusb_interface *interfaceContainer = &config->interface[iface];
94+
for (int i = 0; i < interfaceContainer->num_altsetting; i++) {
95+
const libusb_interface_descriptor *idesc = &interfaceContainer->altsetting[i];
96+
for (uint8_t epoint = 0; epoint < idesc->bNumEndpoints; epoint++) {
97+
const libusb_endpoint_descriptor *endpoint = &idesc->endpoint[epoint];
98+
endpoint_number++;
99+
if (endpoint->bEndpointAddress & LIBUSB_ENDPOINT_IN) {
100+
endpoint_in = endpoint->bEndpointAddress;
101+
}
102+
else {
103+
endpoint_out = endpoint->bEndpointAddress;
104+
}
105+
}
106+
}
107+
}
108+
return endpoint_number;
109+
}
110+
NAN_METHOD(Load) {
111+
if(info.Length()>0) {
112+
Nan::ThrowError("Load() must not have arguments");
113+
return;
114+
}
115+
int payload_size = 0, tmp = 0;
116+
uint8_t payload = 0x13;
117+
auto return_value = Nan::New<v8::Number>(libusb_interrupt_transfer(device_handle, endpoint_out, &payload, sizeof(payload), &tmp, 16));
118+
info.GetReturnValue().Set(return_value);
119+
}
120+
NAN_METHOD(Read) {
121+
if(info.Length()>0) {
122+
Nan::ThrowError("Read() must not have arguments");
123+
return;
124+
}
125+
Sleep(200);
126+
int code = libusb_interrupt_transfer(device_handle, endpoint_in, controller_payload_swap, sizeof(controller_payload_swap), &controller_payload_size, 16);
127+
stringstream return_value;
128+
if (code == 0) {
129+
int i;
130+
return_value << "[";
131+
for (i = 0; i < 9; i++) {
132+
bitset<8> bits(controller_payload_swap[i]);
133+
return_value << bits << ",";
134+
}
135+
bitset<8> bits(controller_payload_swap[i]);
136+
return_value << bits << "]";
137+
auto returner = Nan::New<v8::String>(return_value.str()).ToLocalChecked();
138+
info.GetReturnValue().Set(returner);
139+
}
140+
else {
141+
return_value << "I couldn't get anything. Error: " << code;
142+
auto error_message = Nan::New<v8::String>(return_value.str()).ToLocalChecked();
143+
info.GetReturnValue().Set(error_message);
144+
}
145+
}
146+
NAN_MODULE_INIT(Bridge) {
147+
NAN_EXPORT(target,Load);
148+
NAN_EXPORT(target,Setup);
149+
NAN_EXPORT(target,Read);
150+
}
151+
152+
NODE_MODULE(BridgeTest_2,Bridge)
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#include "libusb.h"
2+
3+
#include <nan.h>
4+
5+
#pragma once
6+
7+
int AddAdapter(libusb_device *dev);
8+
NAN_METHOD(Load);
9+
NAN_METHOD(Setup);
10+
bool IsAccessible(libusb_device *dev);
11+
12+
const uint16_t GAMECUBE_VID = 0x057E;
13+
const uint16_t GAMECUBE_PID = 0x0337;
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
"targets": [
3+
{
4+
"link_settings": {
5+
"libraries": ["../lib/libusb-1.0.lib"]
6+
},
7+
"include_dirs": [
8+
"<!(node -e \"require('nan')\")",
9+
"include"
10+
],
11+
"target_name": "gca-node",
12+
"sources": ["GCAdapter.cc","GCAdapter.h"]
13+
}
14+
]
15+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
var gca_node = require('../build/Release/gca-node.node')
2+
var proceed = false;
3+
if(gca_node.Setup()>0) {
4+
console.log("I found an available GameCube adapter!");
5+
proceed = true;
6+
} else {
7+
console.error("I haven't found an available GameCube adapter. I can't tell the reason just yet.");
8+
}
9+
if(proceed) {
10+
console.log("I'm going to try and connect to the adapter.");
11+
var code = gca_node.Load();
12+
if(code===0) {
13+
console.log("I did it! Now I'm going to do some buffering...");
14+
for(var i=0;i<100;i++) {
15+
console.log(gca_node.Read());
16+
}
17+
} else {
18+
console.log("Oops! Something happened: " + code);
19+
}
20+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
5+
<title>myou</title>
6+
</head>
7+
<body style="margin:0;height:100vh">
8+
<script src="main.js"></script>
9+
</body>
10+
</html>

0 commit comments

Comments
 (0)