Skip to content

Commit

Permalink
implemented proof-of-concept device reset
Browse files Browse the repository at this point in the history
  • Loading branch information
tolga9009 committed Mar 20, 2016
1 parent 72516ed commit ba02428
Show file tree
Hide file tree
Showing 11 changed files with 688 additions and 1,019 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ CC = clang
CFLAGS = -std=c99 -Wall -Wextra
LDFLAGS = -lusb-1.0

SRCS = elgato-gchd.c commands.c init_720p.c init_1080p.c remove.c
SRCS = elgato-gchd.c commands.c init.c init_720p.c init_1080p.c remove.c
OBJS = $(SRCS:.c=.o)
EXEC = elgato-gchd

Expand Down
10 changes: 6 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ Usage
According to your HDMI source, run `./elgato-gchd -r 720p` or
`./elgato-gchd -r 1080p` with root permissions in a terminal and leave it open.
This driver will create a new file `/tmp/elgato-gchd.ts`.
This command will create a new file `/tmp/elgato-gchd.ts`.
Please note, that this file is actually a FIFO pipe and will not grow. You will
need an external program to record footage.
Expand All @@ -70,9 +70,11 @@ You can open up this file using any media player, which supports reading from
pipes. There will be a slight delay, which is hardware limited and can not be
worked around.
After closing the file, you will not be able to reopen it again. You will need
to stop the terminal using "Ctrl + C", disconnect and reconnect your Elgato Game
Capture HD's USB cable and start over again.
If you're done using this driver, close the file. Then stop the terminal using
"Ctrl + C" and wait for the program to successfully terminate. The driver is
resetting your device, so it can be used again. If you interrupt this step, it
will leave your device in an undefined state and you will need to replug your
device, to manually reset it.
Currently, 1080p30 and 720p60 are supported.
Expand Down
20 changes: 20 additions & 0 deletions commands.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#include <libusb-1.0/libusb.h>

Expand All @@ -20,6 +21,17 @@ void read_config(uint8_t bRequest, uint16_t wValue, uint16_t wIndex, uint16_t wL
free(recv);
}

int read_config4(uint8_t bRequest, uint16_t wValue, uint16_t wIndex, unsigned char data0, unsigned char data1, unsigned char data2, unsigned char data3) {
unsigned char recv[4];
libusb_control_transfer(devh, 0xc0, bRequest, wValue, wIndex, recv, 4, 0);

if (recv[0] == data0 && recv[1] == data1 && recv[2] == data2 && recv[3] == data3) {
return 1;
}

return 0;
}

void write_config2(uint8_t bRequest, uint16_t wValue, uint16_t wIndex, unsigned char data0, unsigned char data1) {
unsigned char send[2] = {data0, data1};
libusb_control_transfer(devh, 0x40, bRequest, wValue, wIndex, send, 2, 0);
Expand Down Expand Up @@ -168,3 +180,11 @@ void dlfirm(const char *file) {

fclose(bin);
}

void receive_data() {
int transfer;
unsigned char data[DATA_BUF] = {0};

libusb_bulk_transfer(devh, 0x81, data, DATA_BUF, &transfer, 5000);
write(fd_fifo, (char *)data, DATA_BUF);
}
9 changes: 6 additions & 3 deletions commands.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,13 @@
#include <stdint.h>

// scmd commands
#define SCMD_IDLE 1
#define SCMD_INIT 4
#define SCMD_IDLE 1
#define SCMD_INIT 4
#define SCMD_STATE_CHANGE 5

// deprecated functions. Getting replaced by reverse engineered functions.
// Getting replaced by reverse engineered functions.
void read_config(uint8_t bRequest, uint16_t wValue, uint16_t wIndex, uint16_t wLength);
int read_config4(uint8_t bRequest, uint16_t wValue, uint16_t wIndex, unsigned char data0, unsigned char data1, unsigned char data2, unsigned char data3);
void write_config2(uint8_t bRequest, uint16_t wValue, uint16_t wIndex, unsigned char data0, unsigned char data1);
void write_config3(uint8_t bRequest, uint16_t wValue, uint16_t wIndex, unsigned char data0, unsigned char data1, unsigned char data2);
void write_config4(uint8_t bRequest, uint16_t wValue, uint16_t wIndex, unsigned char data0, unsigned char data1, unsigned char data2, unsigned char data3);
Expand Down Expand Up @@ -79,4 +80,6 @@ void slsi(uint16_t wIndex, uint16_t data);
*/
void dlfirm(const char *file);

void receive_data();

#endif
2 changes: 2 additions & 0 deletions common.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,7 @@
#define FW_MB86H57_H58_ENC "firmware/mb86h57_h58_enc_h.bin"

struct libusb_device_handle *devh;
extern int fd_fifo;
extern int init_has_been_run;

#endif
37 changes: 23 additions & 14 deletions elgato-gchd.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
static volatile sig_atomic_t is_running = 1;
int libusb_ret = 1;
int fd_fifo = 0;
int init_has_been_run = 0;
char *fifo_path = "/tmp/elgato_gchd.ts";

enum video_resoltion {
Expand All @@ -47,6 +48,8 @@ enum video_resoltion {
};

void sig_handler(int sig) {
fprintf(stderr, "Stop signal received. Do not interrupt or unplug your device.\n");

switch(sig) {
case SIGINT:
is_running = 0;
Expand Down Expand Up @@ -104,17 +107,13 @@ int get_interface() {
return 0;
}

void receive_data() {
int transfer;
unsigned char data[DATA_BUF] = {0};

libusb_bulk_transfer(devh, 0x81, data, DATA_BUF, &transfer, 5000);
write(fd_fifo, (char *)data, DATA_BUF);
}

void clean_up() {
if (devh) {
remove_elgato();
if (init_has_been_run) {
remove_elgato();
fprintf(stderr, "Device has been reset.\n");
}

libusb_release_interface(devh, INTERFACE_NUM);
libusb_close(devh);
}
Expand All @@ -125,6 +124,8 @@ void clean_up() {

close(fd_fifo);
unlink(fifo_path);

fprintf(stderr, "Clean up done. Terminating\n");
}

int main(int argc, char *argv[]) {
Expand Down Expand Up @@ -188,18 +189,26 @@ int main(int argc, char *argv[]) {
// create the FIFO (also known as named pipe)
mkfifo(fifo_path, 0644);

fprintf(stderr, "%s has been created. Waiting for user to open it.\n", fifo_path);

// open FIFO
fd_fifo = open(fifo_path, O_WRONLY);

// set device configuration
switch (resolution) {
case v720p: configure_dev_720p(); break;
case v1080p: configure_dev_1080p(); break;
default: clean_up();
if (is_running) {
fprintf(stderr, "Running. Initializing device.\n");

switch (resolution) {
case v720p: configure_dev_720p(); break;
case v1080p: configure_dev_1080p(); break;
default: clean_up();
}

fprintf(stderr, "Streaming data from device now.\n");
}

// receive audio and video from device
while(is_running) {
while (is_running) {
receive_data();
}

Expand Down
Loading

0 comments on commit ba02428

Please sign in to comment.