original_code:
static void process_extended(struct haptic_source_state * state, const unsigned char data[7]) {
    s_cmd cmd = { 0xF8, data[1] };
    int i;
    for (i = 0; i < 16; ++i) {
        s_ext_cmd * ext_cmd = state->ext_cmds + i;
        if(!ext_cmd->cmd[0]) {
            memcpy(ext_cmd->cmd, data, sizeof(ext_cmd->cmd));
            ext_cmd->updated = 1;
            ff_lg_fifo_push(state->fifo, cmd, 1);
            break;
        } else if(ext_cmd->cmd[1] == data[1]) {
            if(memcmp(ext_cmd->cmd, data, sizeof(ext_cmd->cmd))) {
                memcpy(ext_cmd->cmd, data, sizeof(ext_cmd->cmd));
                ext_cmd->updated = 1;
                ff_lg_fifo_push(state->fifo, cmd, 1);
            } else {
                do { if(gimx_params.debug.haptic) { printf("> no change\n"); fflush(stdout); } } while (0);
            }
            break;
        }
    }
}

canonical_original_code:
static void process_extended(struct haptic_source_state *state, unsigned char data[7]) {
    struct s_cmd cmd = { 0xF8, data[1] };
    int i;
    for (i = 0; i < 16; ++i) {
        struct s_ext_cmd *ext_cmd = state->ext_cmds + i;
        if(!ext_cmd->cmd[0]) {
            memcpy(ext_cmd->cmd, data, sizeof(ext_cmd->cmd));
            ext_cmd->updated = 1;
            ff_lg_fifo_push(state->fifo, cmd, 1);
            break;
        } else if(ext_cmd->cmd[1] == data[1]) {
            if(memcmp(ext_cmd->cmd, data, sizeof(ext_cmd->cmd))) {
                memcpy(ext_cmd->cmd, data, sizeof(ext_cmd->cmd));
                ext_cmd->updated = 1;
                ff_lg_fifo_push(state->fifo, cmd, 1);
            } else {
                do { if(gimx_params.debug.haptic) { printf("> no change\n"); fflush(stdout); } } while (0);
            }
            break;
        }
    }
}

variable_types:
data
unsigned char [7]

variable_types: struct s_ext_cmd { unsigned char updated; unsigned char cmd[7]; } *

user_defined_types: struct s_cmd { unsigned char cmd; unsigned char ext; }

user_defined_types: struct s_force { unsigned char mask; unsigned char playing; unsigned char updated; unsigned char parameters[-1]; }


repo: matlo/GIMX

original_code:
static void set_wheel_range(struct haptic_source_state * state, unsigned short range) {
    if (range == state->range) {
        return;
    }
    state->range = range;
    unsigned char change_wheel_range[7] = {
            0xF8,
            0x81,
            range & 0xFF,
            range >> 8
    };
    process_extended(state, change_wheel_range);
}

canonical_original_code:
static void set_wheel_range(struct haptic_source_state *state, unsigned short range) {
    if (range == state->range) {
        return;
    }
    state->range = range;
    unsigned char change_wheel_range[7] = {
            0xF8,
            0x81,
            range & 0xFF,
            range >> 8
    };
    process_extended(state, change_wheel_range);
}

variable_types: struct haptic_source_state { unsigned char caps; unsigned char cmd_offset; unsigned short range; struct s_force { unsigned char mask; unsigned char playing; unsigned char updated; unsigned char parameters[-1]; } forces[4]; struct s_ext_cmd { unsigned char updated; unsigned char cmd[7]; } ext_cmds[16]; struct s_cmd { unsigned char cmd; unsigned char ext; } fifo[16]; } *

variable_types:
range
unsigned short

return_type: void

user_defined_types: struct haptic_source_state { unsigned char caps; unsigned char cmd_offset; unsigned short range; struct s_force forces[4]; struct s_ext_cmd ext_cmds[16]; struct s_cmd fifo[16]; }


decompiled_code:
__int64 __fastcall haptic_source_lg_get(unsigned __int8 *a1, __int64 a2)
{
__int16 v3; // ax
__int64 result; // rax
__int16 v5; // r12
__int64 v6; // rax
unsigned __int8 *v7; // rdi

v3 = ff_lg_fifo_peek_isra_0(a1[168], a1[169]);
if ( !(_BYTE)v3 )
return 0LL;
v5 = v3;
ff_lg_fifo_remove(a1 + 168, v3);
if ( (_BYTE)v5 == 0xF8 )
{
v7 = a1 + 40;
while ( v7[2] != HIBYTE(v5) )
{
v7 += 8;
if ( a1 + 168 == v7 )
return 0LL;
}
*v7 = 0;
result = ff_lg_convert_extended(v7 + 2, a2);
}
else
{
if ( (v5 & 0xF) != 0 )
return 0LL;
v6 = (unsigned __int8)slot_index[(unsigned __int8)v5 >> 4];
a1[9 * v6 + 6] = 0;
result = ff_lg_convert_force(*a1, (unsigned __int8)v6, &a1[9 * v6 + 7], a1[9 * v6 + 5], a2);
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func12(unsigned __int8 *a1, __int64 a2)
{
__int16 v3; // ax
__int64 result; // rax
__int16 v5; // r12
__int64 v6; // rax
unsigned __int8 *v7; // rdi

v3 = func11(a1[168], a1[169]);
if ( !(_BYTE)v3 )
return 0LL;
v5 = v3;
func2(a1 + 168, v3);
if ( (_BYTE)v5 == 0xF8 )
{
v7 = a1 + 40;
while ( v7[2] != HIBYTE(v5) )
{
v7 += 8;
if ( a1 + 168 == v7 )
return 0LL;
}
*v7 = 0;
result = ff_lg_convert_extended(v7 + 2, a2);
}
else
{
if ( (v5 & 0xF) != 0 )
return 0LL;
v6 = (unsigned __int8)slot_index[(unsigned __int8)v5 >> 4];
a1[9 * v6 + 6] = 0;
result = ff_lg_convert_force(*a1, (unsigned __int8)v6, &a1[9 * v6 + 7], a1[9 * v6 + 5], a2);
}
return result;
}

original_code:
static int haptic_source_lg_get(struct haptic_source_state * state, s_haptic_core_data * data) {
    s_cmd cmd = ff_lg_fifo_peek(state->fifo);
    if (cmd.cmd) {
        ff_lg_fifo_remove(state->fifo, cmd);
        if(cmd.cmd != 0xF8) {
            if(cmd.cmd & 0x0f)
            {
                return 0;
            }
            else
            {
                unsigned char index = slot_index[cmd.cmd >> 4];
                s_force * force = state->forces + index;
                force->updated = 0;
                return ff_lg_convert_force(state->caps, index, (s_ff_lg_command *)state->forces[index].parameters, state->forces[index].playing, data);
            }
        }
        else {
            int i;
            for (i = 0; i < 16; ++i) {
                s_ext_cmd * ext_cmd = state->ext_cmds + i;
                if(ext_cmd->cmd[1] == cmd.ext) {
                    ext_cmd->updated = 0;
                    return ff_lg_convert_extended((s_ff_lg_command *)(ext_cmd->cmd + 1), data);
                }
            }
        }
    }
    return 0;
}

canonical_original_code:
static int haptic_source_lg_get(struct haptic_source_state *state, struct s_haptic_core_data *data) {
    struct s_cmd cmd = ff_lg_fifo_peek(state->fifo);
    if (cmd.cmd) {
        ff_lg_fifo_remove(state->fifo, cmd);
        if(cmd.cmd != 0xF8) {
            if(cmd.cmd & 0x0f)
            {
                return 0;
            }
            else
            {
                unsigned char index = slot_index[cmd.cmd >> 4];
                struct s_force *force = state->forces + index;
                force->updated = 0;
                return ff_lg_convert_force(state->caps, index, (struct s_ff_lg_command *)state->forces[index].parameters, state->forces[index].playing, data);
            }
        }
        else {
            int i;
            for (i = 0; i < 16; ++i) {
                struct s_ext_cmd *ext_cmd = state->ext_cmds + i;
                if(ext_cmd->cmd[1] == cmd.ext) {
                    ext_cmd->updated = 0;
                    return ff_lg_convert_extended((struct s_ff_lg_command *)(ext_cmd->cmd + 1), data);
                }
            }
        }
    }
    return 0;
}

variable_types: struct s_haptic_core_data { enum e_haptic_core_data_type { E_DATA_TYPE_NONE=0, E_DATA_TYPE_RUMBLE=1, E_DATA_TYPE_CONSTANT=2, E_DATA_TYPE_SPRING=3, E_DATA_TYPE_DAMPER=4, E_DATA_TYPE_LEDS=5, E_DATA_TYPE_RANGE=6 } type; unsigned char playing; union { struct s_haptic_core_rumble { unsigned short weak; unsigned short strong; } rumble; struct s_haptic_core_constant { short level; } constant; struct s_haptic_core_condition { struct { unsigned short left; unsigned short right; } saturation; struct { short left; short right; } coefficient; short center; unsigned short deadband; } spring; struct s_haptic_core_condition damper; struct s_haptic_core_leds { unsigned char value; } leds; struct s_haptic_core_range { unsigned short value; } range; }; } *

variable_types: struct s_cmd { unsigned char cmd; unsigned char ext; }

variable_types:
index
unsigned char

variable_types: struct s_force { unsigned char mask; unsigned char playing; unsigned char updated; unsigned char parameters[-1]; } *

variable_types: i int

return_type: int

user_defined_types: struct s_haptic_core_data { enum e_haptic_core_data_type type; unsigned char playing; union { struct s_haptic_core_rumble rumble; struct s_haptic_core_constant constant; struct s_haptic_core_condition spring; struct s_haptic_core_condition damper; struct s_haptic_core_leds leds; struct s_haptic_core_range range; }; }

user_defined_types: struct s_ext_cmd { unsigned char updated; unsigned char cmd[7]; }

user_defined_types: struct s_ff_lg_command { union { unsigned char force_type; unsigned char cmd_param; }; unsigned char parameters[-1]; }


decompiled_code:
int haptic_source_lg_constructor()
{
int result; // eax

result = haptic_source_register(&source_lg);
if ( result == -1 )
result = fprintf(
stderr,
"%s:%d %s: %s\n",
"haptic/source/haptic_source_lg.c",
295LL,
"haptic_source_lg_constructor",
"failed to register source");
return result;
}

canonical_decompiled_code:
int func13()
{
int result; // eax

result = haptic_source_register(&source_lg);
if ( result == -1 )
result = fprintf(
stderr,
"%s:%d %s: %s\n",
"haptic/source/haptic_source_lg.c",
295LL,
"haptic_source_lg_constructor",
"failed to register source");
return result;
}

original_code:
void haptic_source_lg_constructor(void) {
    if (haptic_source_register(&source_lg) == -1) {
        fprintf(stderr, "%s:%d %s: %s\n", "haptic/source/haptic_source_lg.c", 295, __func__, "failed to register source");
    }
}

canonical_original_code:
void haptic_source_lg_constructor() {
    if (haptic_source_register(&source_lg) == -1) {
        fprintf(stderr, "%s:%d %s: %s\n", "haptic/source/haptic_source_lg.c", 295, __func__, "failed to register source");
    }
}


decompiled_code:
__int64 __fastcall send_report(__int64 a1)
{
__int64 result; // rax

result = ghid_write(*(_QWORD *)a1, a1 + 16, 32LL);
if ( !(_DWORD)result )
*(_DWORD *)(a1 + 8) = 1;
return result;
}

canonical_decompiled_code:
__int64 __fastcall func0(__int64 a1)
{
__int64 result; // rax

result = ghid_write(*(_QWORD *)a1, a1 + 16, 32LL);
if ( !(_DWORD)result )
*(_DWORD *)(a1 + 8) = 1;
return result;
}

original_code:
static int send_report(int sixaxis_number, uint16_t psm, uint8_t type, uint8_t report, int blocking)
{
  uint8_t buf[128];
  int len = 0;
  int i;
  struct sixaxis_state* state = states + sixaxis_number;
  for (i = 0; sixaxis_assemble[i].func; i++)
  {
    if (sixaxis_assemble[i].type == type
        && sixaxis_assemble[i].report == report)
    {
      len = sixaxis_assemble[i].func(&buf[2], sizeof(buf) - 2, state);
      break;
    }
  }
  if (!sixaxis_assemble[i].func || len < 0)
  {
    do { if(!gimx_params.curses_status) { setColorStdout(YELLOW); printf("Warning: "); resetColorStdout(); printf("%s %s report 0x%02x, sending empty response\n", (len < 0) ? "Error assembling" : "Unknown", hid_report_name[type], report); fflush(stdout); } } while (0);
    len = 0;
  }
  buf[0] = 0xa0 | type;
  buf[1] = report;
  len += 2;
  if (gimx_params.debug.sixaxis)
  {
    gtime now = gtime_gettime();
    do { if(!gimx_params.curses_status) { printf("%lu.%06lu Sixaxis %-7s %02x:", ((gtimepart)((now) / 1000000000ULL)), (((gtimepart)((now) % 1000000000ULL)) / 1000UL), hid_report_name[type], report); fflush(stdout); } } while (0);
    for (i = 2; i < len; i++)
      do { if(!gimx_params.curses_status) { printf(" %02x", buf[i]); fflush(stdout); } } while (0);
    do { if(!gimx_params.curses_status) { printf("\n"); fflush(stdout); } } while (0);
  }
  return l2cap_abs_get()->send((psm == 0x11) ? state->channels.control.id : state->channels.interrupt.id, buf, len, blocking);
}

canonical_original_code:
static int send_report(int sixaxis_number, unsigned short psm, unsigned char type, unsigned char report, int blocking)
{
  unsigned char buf[128];
  int len = 0;
  int i;
  struct sixaxis_state *state = states + sixaxis_number;
  for (i = 0; sixaxis_assemble[i].func; i++)
  {
    if (sixaxis_assemble[i].type == type
        && sixaxis_assemble[i].report == report)
    {
      len = sixaxis_assemble[i].func(&buf[2], sizeof(buf) - 2, state);
      break;
    }
  }
  if (!sixaxis_assemble[i].func || len < 0)
  {
    do { if(!gimx_params.curses_status) { setColorStdout(YELLOW); printf("Warning: "); resetColorStdout(); printf("%s %s report 0x%02x, sending empty response\n", (len < 0) ? "Error assembling" : "Unknown", hid_report_name[type], report); fflush(stdout); } } while (0);
    len = 0;
  }
  buf[0] = 0xa0 | type;
  buf[1] = report;
  len += 2;
  if (gimx_params.debug.sixaxis)
  {
    unsigned long long now = gtime_gettime();
    do { if(!gimx_params.curses_status) { printf("%lu.%06lu Sixaxis %-7s %02x:", ((gtimepart)((now) / 1000000000ULL)), (((gtimepart)((now) % 1000000000ULL)) / 1000UL), hid_report_name[type], report); fflush(stdout); } } while (0);
    for (i = 2; i < len; i++)
      do { if(!gimx_params.curses_status) { printf(" %02x", buf[i]); fflush(stdout); } } while (0);
    do { if(!gimx_params.curses_status) { printf("\n"); fflush(stdout); } } while (0);
  }
  return l2cap_abs_get()->send((psm == 0x11) ? state->channels.control.id : state->channels.interrupt.id, buf, len, blocking);
}

variable_types:
psm
unsigned short

variable_types:
type
unsigned char

variable_types:
report
unsigned char

variable_types: blocking int

variable_types:
buf
unsigned char [128]

variable_types: len int

variable_types: struct sixaxis_state { struct { char str[18]; struct bdaddr_t { unsigned char b[6]; } ba; } bdaddr_src; char bdaddr_dst[18]; int dongle_index; int sixaxis_number; struct sixaxis_state_sys { int reporting_enabled; int shutdown; int feature_ef_byte_6; enum led_state_t { LED_OFF=0, LED_FLASH=1, LED_ON=2 } led[5]; unsigned char rumble[2]; } sys; struct s_report_ds3 { unsigned char report_id; unsigned char unused1; unsigned char buttons1; unsigned char buttons2; unsigned char buttons3; unsigned char unused2; char X; char Y; char Z; char Rz; unsigned char unknown1[4]; unsigned char up; unsigned char right; unsigned char down; unsigned char left; unsigned char l2; unsigned char r2; unsigned char l1; unsigned char r1; unsigned char triangle; unsigned char circle; unsigned char cross; unsigned char square; unsigned char unknown2[15]; unsigned char acc_x[2]; unsigned char acc_y[2]; unsigned char acc_z[2]; unsigned char gyro[2]; } user; struct { struct { int id; int pending; } control; struct { int id; int pending; } interrupt; } channels; } *

variable_types:
now
unsigned long long

user_defined_types: struct sixaxis_state { struct { char str[18]; struct bdaddr_t ba; } bdaddr_src; char bdaddr_dst[18]; int dongle_index; int sixaxis_number; struct sixaxis_state_sys sys; struct s_report_ds3 user; struct { struct { int id; int pending; } control; struct { int id; int pending; } interrupt; } channels; }

user_defined_types: struct sixaxis_state_sys { int reporting_enabled; int shutdown; int feature_ef_byte_6; enum led_state_t led[5]; unsigned char rumble[2]; }


decompiled_code:
__int64 haptic_sink_ds4_constructor()
{
return haptic_sink_register(&sink_ds4);
}

canonical_decompiled_code:
__int64 func7()
{
return haptic_sink_register(&sink_ds4);
}

original_code:
void haptic_sink_ds4_constructor(void) {
    haptic_sink_register(&sink_ds4);
}

canonical_original_code:
void haptic_sink_ds4_constructor() {
    haptic_sink_register(&sink_ds4);
}


decompiled_code:
void haptic_source_destructor()
{
free(sources);
nb_sources = 0;
}

canonical_decompiled_code:
void func2()
{
free(sources);
nb_sources = 0;
}

original_code:
void haptic_source_destructor(void) {
    free(sources);
    nb_sources = 0;
}


decompiled_code:
__int64 clocked_timer_read()
{
return 1LL;
}

canonical_decompiled_code:
__int64 func0()
{
return 1LL;
}

original_code:
static int clocked_timer_read(void * user __attribute__((unused)))
{
  return 1;
}

canonical_original_code:
static int clocked_timer_read(void *user)
{
  return 1;
}

variable_types:
user
void *


decompiled_code:
__int64 default_timer_read()
{
return (unsigned int)done;
}

canonical_decompiled_code:
__int64 func1()
{
return (unsigned int)done;
}

original_code:
static int default_timer_read(void * user __attribute__((unused)))
{
  return done;
}

canonical_original_code:
static int default_timer_read(void *user)
{
  return done;
}


resetColorStdout

decompiled_code:
int resetColorStdout()
{
return printf("%s", "\x1B[0m");
}

canonical_decompiled_code:
int func2()
{
return printf("%s", "\x1B[0m");
}

original_code:
static inline void resetColorStdout(void) {
    printf("%s", ANSI_ATTRIBUTE_RESET);
}

canonical_original_code:
static inline void resetColorStdout() {
    printf("%s", ANSI_ATTRIBUTE_RESET);
}


decompiled_code:
void set_done()
{
done = 1;
}

canonical_decompiled_code:
void func5()
{
done = 1;
}

original_code:
void set_done()
{
  done = 1;
}

canonical_original_code:
void set_done()
{
  done = 1;
}


decompiled_code:
__int64 timer_close()
{
set_done();
return 1LL;
}

canonical_decompiled_code:
__int64 func6()
{
func5();
return 1LL;
}

original_code:
static int timer_close(void * user __attribute__((unused)))
{
  set_done();
  return 1;
}

canonical_original_code:
static int timer_close(void *user)
{
  set_done();
  return 1;
}


decompiled_code:
__int64 get_done()
{
return (unsigned int)done;
}

canonical_decompiled_code:
__int64 func7()
{
return (unsigned int)done;
}

original_code:
int get_done()
{
  return done;
}

canonical_original_code:
int get_done()
{
  return done;
}


decompiled_code:
int print_version()
{
return printf("GIMX %s %s\n", "8.0", "x86_64");
}

canonical_decompiled_code:
int func0()
{
return printf("GIMX %s %s\n", "8.0", "x86_64");
}

original_code:
void print_version() {
  printf("GIMX %s %s\n", "8.0", "x86_64");
}


decompiled_code:
int print_os()
{
int result; // eax

result = system("lsb_release -d -s");
if ( result )
result = fwrite("cannot get distribution information\n", 1uLL, 0x24uLL, stderr);
return result;
}

canonical_decompiled_code:
int func1()
{
int result; // eax

result = system("lsb_release -d -s");
if ( result )
result = fwrite("cannot get distribution information\n", 1uLL, 0x24uLL, stderr);
return result;
}

original_code:
void print_os() {
  if (system("lsb_release -d -s") != 0) {
    fprintf(stderr, "cannot get distribution information\n");
  }
}


decompiled_code:
int print_kernel()
{
int result; // eax

result = system("uname -srvp");
if ( result )
result = fwrite("cannot get kernel information\n", 1uLL, 0x1EuLL, stderr);
return result;
}

canonical_decompiled_code:
int func2()
{
int result; // eax

result = system("uname -srvp");
if ( result )
result = fwrite("cannot get kernel information\n", 1uLL, 0x1EuLL, stderr);
return result;
}

original_code:
void print_kernel() {
  if (system("uname -srvp") != 0) {
    fprintf(stderr, "cannot get kernel information\n");
  }
}


decompiled_code:
int print_devices()
{
int result; // eax

if ( !system("lsusb") )
{
result = system("lsusb -t");
if ( !result )
return result;
return fwrite("cannot get USB device tree\n", 1uLL, 0x1BuLL, stderr);
}
fwrite("cannot get USB device list\n", 1uLL, 0x1BuLL, stderr);
result = system("lsusb -t");
if ( result )
return fwrite("cannot get USB device tree\n", 1uLL, 0x1BuLL, stderr);
return result;
}

canonical_decompiled_code:
int func3()
{
int result; // eax

if ( !system("lsusb") )
{
result = system("lsusb -t");
if ( !result )
return result;
return fwrite("cannot get USB device tree\n", 1uLL, 0x1BuLL, stderr);
}
fwrite("cannot get USB device list\n", 1uLL, 0x1BuLL, stderr);
result = system("lsusb -t");
if ( result )
return fwrite("cannot get USB device tree\n", 1uLL, 0x1BuLL, stderr);
return result;
}

original_code:
void print_devices() {
  if (system("lsusb") != 0) {
    fprintf(stderr, "cannot get USB device list\n");
  }
  if (system("lsusb -t") != 0) {
    fprintf(stderr, "cannot get USB device tree\n");
  }
}


decompiled_code:
int log_info()
{
print_version();
print_os();
print_kernel();
return print_devices();
}

canonical_decompiled_code:
int func4()
{
func0();
func1();
func2();
return func3();
}

original_code:
void log_info() {
  print_version();
  print_os();
  print_kernel();
  print_devices();
}


decompiled_code:
__int64 hci_create_cmd(__int64 a1, __int64 a2, ...)
{
gcc_va_list va; // [rsp+8h] [rbp-D0h] BYREF

va_start(va, a2);
return hci_create_cmd_internal(a1, a2, (int *)va);
}

canonical_decompiled_code:
__int64 func1(__int64 a1, __int64 a2, ...)
{
gcc_va_list va; // [rsp+8h] [rbp-D0h] BYREF

va_start(va, a2);
return func0(a1, a2, (int *)va);
}

original_code:
uint16_t hci_create_cmd(uint8_t *hci_cmd_buffer, hci_cmd_t *cmd, ...){
    va_list argptr;
    __builtin_va_start(argptr,cmd);
    uint16_t len = hci_create_cmd_internal(hci_cmd_buffer, cmd, argptr);
    __builtin_va_end(argptr);
    return len;
}

canonical_original_code:
unsigned short hci_create_cmd(unsigned char *hci_cmd_buffer, struct hci_cmd_t *cmd, ...){
    __builtin_va_list argptr;
    __builtin_va_start(argptr,cmd);
    unsigned short len = hci_create_cmd_internal(hci_cmd_buffer, cmd, argptr);
    __builtin_va_end(argptr);
    return len;
}

variable_types: struct hci_cmd_t { unsigned short opcode; char *format; } *

variable_types:
len
unsigned short

return_type: unsigned short


ouitocomp

decompiled_code:
char *__fastcall ouitocomp(char *needle)
{
int v1; // ebp
char *v2; // r13
char *v3; // r14
char *v4; // rax
const char *v5; // r12
char *v6; // rax
char *v8; // rdi
struct stat v9; // [rsp+0h] [rbp-B8h] BYREF

v1 = open("oui.txt", 0);
if ( v1 < 0 )
{
v1 = open("/var/lib/misc/oui.txt", 0);
if ( v1 < 0 )
{
v1 = open("/usr/share/misc/oui.txt", 0);
if ( v1 < 0 )
return 0LL;
}
}
if ( fstat(v1, &v9) < 0 )
goto LABEL_15;
v2 = (char *)calloc(0x80uLL, 1uLL);
if ( v2 )
{
v3 = (char *)mmap(0LL, v9.st_size, 1, 1, v1, 0LL);
if ( (unsigned __int64)(v3 - 1) <= 0xFFFFFFFFFFFFFFFDLL )
{
v4 = strstr(v3, needle);
if ( v4 )
{
v5 = v4 + 18;
v6 = strpbrk(v4 + 18, "\r\n");
strncpy(v2, v5, v6 - v5);
}
else
{
v8 = v2;
v2 = 0LL;
free(v8);
}
munmap(v3, v9.st_size);
goto LABEL_8;
}
free(v2);
LABEL_15:
v2 = 0LL;
close(v1);
return v2;
}
LABEL_8:
close(v1);
return v2;
}

canonical_decompiled_code:
char *__fastcall func0(char *needle)
{
int v1; // ebp
char *v2; // r13
char *v3; // r14
char *v4; // rax
const char *v5; // r12
char *v6; // rax
char *v8; // rdi
struct stat v9; // [rsp+0h] [rbp-B8h] BYREF

v1 = open("oui.txt", 0);
if ( v1 < 0 )
{
v1 = open("/var/lib/misc/oui.txt", 0);
if ( v1 < 0 )
{
v1 = open("/usr/share/misc/oui.txt", 0);
if ( v1 < 0 )
return 0LL;
}
}
if ( fstat(v1, &v9) < 0 )
goto LABEL_15;
v2 = (char *)calloc(0x80uLL, 1uLL);
if ( v2 )
{
v3 = (char *)mmap(0LL, v9.st_size, 1, 1, v1, 0LL);
if ( (unsigned __int64)(v3 - 1) <= 0xFFFFFFFFFFFFFFFDLL )
{
v4 = strstr(v3, needle);
if ( v4 )
{
v5 = v4 + 18;
v6 = strpbrk(v4 + 18, "\r\n");
strncpy(v2, v5, v6 - v5);
}
else
{
v8 = v2;
v2 = 0LL;
free(v8);
}
munmap(v3, v9.st_size);
goto LABEL_8;
}
free(v2);
LABEL_15:
v2 = 0LL;
close(v1);
return v2;
}
LABEL_8:
close(v1);
return v2;
}

original_code:
char *ouitocomp(const char *oui)
{
 struct stat st;
 char *str, *map, *off, *end;
 int fd;
 fd = open("oui.txt", 00);
 if (fd < 0) {
  fd = open("/var/lib/misc/oui.txt", 00);
  if (fd < 0) {
   fd = open("/usr/share/misc/oui.txt", 00);
   if (fd < 0)
    return ((void *)0);
  }
 }
 if (fstat(fd, &st) < 0) {
  close(fd);
  return ((void *)0);
 }
 str = malloc(128);
 if (!str) {
  close(fd);
  return ((void *)0);
 }
 memset(str, 0, 128);
 map = mmap(0, st.st_size, 0x1, 0x01, fd, 0);
 if (!map || map == ((void *) -1)) {
  free(str);
  close(fd);
  return ((void *)0);
 }
 off = strstr(map, oui);
 if (off) {
  off += 18;
  end = strpbrk(off, "\r\n");
  strncpy(str, off, end - off);
 } else {
  free(str);
  str = ((void *)0);
 }
 munmap(map, st.st_size);
 close(fd);
 return str;
}

canonical_original_code:
char *ouitocomp(char *oui)
{
 struct stat st;
 char *str; char *map; char *off; char *end;
 int fd;
 fd = open("oui.txt", 00);
 if (fd < 0) {
  fd = open("/var/lib/misc/oui.txt", 00);
  if (fd < 0) {
   fd = open("/usr/share/misc/oui.txt", 00);
   if (fd < 0)
    return ((void *)0);
  }
 }
 if (fstat(fd, &st) < 0) {
  close(fd);
  return ((void *)0);
 }
 str = malloc(128);
 if (!str) {
  close(fd);
  return ((void *)0);
 }
 memset(str, 0, 128);
 map = mmap(0, st.st_size, 0x1, 0x01, fd, 0);
 if (!map || map == ((void *) -1)) {
  free(str);
  close(fd);
  return ((void *)0);
 }
 off = strstr(map, oui);
 if (off) {
  off += 18;
  end = strpbrk(off, "\r\n");
  strncpy(str, off, end - off);
 } else {
  free(str);
  str = ((void *)0);
 }
 munmap(map, st.st_size);
 close(fd);
 return str;
}

variable_types:
oui
char *

variable_types: struct stat { unsigned long st_dev; unsigned long st_ino; unsigned long st_nlink; unsigned int st_mode; unsigned int st_uid; unsigned int st_gid; int __pad0; unsigned long st_rdev; long st_size; long st_blksize; long st_blocks; struct timespec { long tv_sec; long tv_nsec; } st_atim; struct timespec st_mtim; struct timespec st_ctim; long __glibc_reserved[3]; }

variable_types:
str
char *

variable_types:
map
char *

variable_types:
off
char *

variable_types:
end
char *

variable_types: fd int

return_type: char *

user_defined_types: struct stat { unsigned long st_dev; unsigned long st_ino; unsigned long st_nlink; unsigned int st_mode; unsigned int st_uid; unsigned int st_gid; int __pad0; unsigned long st_rdev; long st_size; long st_blksize; long st_blocks; struct timespec st_atim; struct timespec st_mtim; struct timespec st_ctim; long __glibc_reserved[3]; }


decompiled_code:
__int64 __fastcall oui2comp(char *a1, char *a2, size_t a3)
{
char *v4; // rax
char *v5; // rbp

v4 = ouitocomp(a1);
if ( !v4 )
return 0xFFFFFFFFLL;
v5 = v4;
snprintf(a2, a3, "%s", v4);
free(v5);
return 0LL;
}

canonical_decompiled_code:
__int64 __fastcall func1(char *a1, char *a2, size_t a3)
{
char *v4; // rax
char *v5; // rbp

v4 = func0(a1);
if ( !v4 )
return 0xFFFFFFFFLL;
v5 = v4;
snprintf(a2, a3, "%s", v4);
free(v5);
return 0LL;
}

original_code:
int oui2comp(const char *oui, char *comp, size_t size)
{
 char *tmp;
 tmp = ouitocomp(oui);
 if (!tmp)
  return -1;
 snprintf(comp, size, "%s", tmp);
 free(tmp);
 return 0;
}

canonical_original_code:
int oui2comp(char *oui, char *comp, unsigned long size)
{
 char *tmp;
 tmp = ouitocomp(oui);
 if (!tmp)
  return -1;
 snprintf(comp, size, "%s", tmp);
 free(tmp);
 return 0;
}

variable_types:
comp
char *

variable_types:
size
unsigned long

variable_types:
tmp
char *


resetColorStdout

canonical_decompiled_code:
int func1()
{
return printf("%s", "\x1B[0m");
}


decompiled_code:
int __fastcall haptic_sink_fifo_push(__int64 a1, __int64 a2)
{
int v2; // ecx
__int64 v3; // rax
__int64 v4; // r12

v2 = *(_DWORD *)(a1 + 20);
if ( v2 )
{
v3 = 1LL;
do
{
if ( *(_DWORD *)(a1 + 4 * v3 - 4) == (_DWORD)a2 )
{
if ( gimx_params[13] )
{
printf("< already queued: %d\n", a2);
LODWORD(v3) = fflush(stdout);
}
return v3;
}
v4 = (unsigned int)v3++;
}
while ( v3 != (unsigned int)(v2 - 1) + 2LL );
if ( (_DWORD)v4 == 5 )
return v3;
}
else
{
v4 = 0LL;
}
LODWORD(v3) = gimx_params[13];
if ( (_DWORD)v3 )
{
printf("< push: %d\n", a2);
LODWORD(v3) = fflush(stdout);
v2 = *(_DWORD *)(a1 + 20);
}
*(_DWORD *)(a1 + 4 * v4) = a2;
*(_DWORD *)(a1 + 20) = v2 + 1;
return v3;
}

canonical_decompiled_code:
int __fastcall func2(__int64 a1, __int64 a2)
{
int v2; // ecx
__int64 v3; // rax
__int64 v4; // r12

v2 = *(_DWORD *)(a1 + 20);
if ( v2 )
{
v3 = 1LL;
do
{
if ( *(_DWORD *)(a1 + 4 * v3 - 4) == (_DWORD)a2 )
{
if ( gimx_params[13] )
{
printf("< already queued: %d\n", a2);
LODWORD(v3) = fflush(stdout);
}
return v3;
}
v4 = (unsigned int)v3++;
}
while ( v3 != (unsigned int)(v2 - 1) + 2LL );
if ( (_DWORD)v4 == 5 )
return v3;
}
else
{
v4 = 0LL;
}
LODWORD(v3) = gimx_params[13];
if ( (_DWORD)v3 )
{
printf("< push: %d\n", a2);
LODWORD(v3) = fflush(stdout);
v2 = *(_DWORD *)(a1 + 20);
}
*(_DWORD *)(a1 + 4 * v4) = a2;
*(_DWORD *)(a1 + 20) = v2 + 1;
return v3;
}

original_code:
static inline void haptic_sink_fifo_push(s_haptic_sink_fifo * fifo, e_slot slot) {
    unsigned int i;
    for (i = 0; i < fifo->size; ++i) {
        if (fifo->items[i] == slot) {
            do { if(gimx_params.debug.haptic) { printf("< already queued: %d\n", slot); fflush(stdout); } } while (0);
            return;
        }
    }
    if (i < slot_nb) {
        do { if(gimx_params.debug.haptic) { printf("< push: %d\n", slot); fflush(stdout); } } while (0);
        fifo->items[i] = slot;
        ++(fifo->size);
    }
}

canonical_original_code:
static inline void haptic_sink_fifo_push(struct s_haptic_sink_fifo *fifo, enum e_slot slot) {
    unsigned int i;
    for (i = 0; i < fifo->size; ++i) {
        if (fifo->items[i] == slot) {
            do { if(gimx_params.debug.haptic) { printf("< already queued: %d\n", slot); fflush(stdout); } } while (0);
            return;
        }
    }
    if (i < slot_nb) {
        do { if(gimx_params.debug.haptic) { printf("< push: %d\n", slot); fflush(stdout); } } while (0);
        fifo->items[i] = slot;
        ++(fifo->size);
    }
}

variable_types: struct s_haptic_sink_fifo { enum e_slot { slot_constant=0, slot_spring=1, slot_damper=2, slot_leds=3, slot_range=4, slot_nb=5 } items[-1]; unsigned int size; } *

variable_types:
i
unsigned int

user_defined_types: struct s_haptic_sink_fifo { enum e_slot items[-1]; unsigned int size; }


decompiled_code:
void __fastcall haptic_sink_fifo_remove(_DWORD *a1, __int64 a2)
{
int v2; // edx
_DWORD *v3; // rax
__int64 v4; // rbx
__int64 v5; // rbp
int v6; // edx

v2 = a1[5];
if ( v2 )
{
v3 = a1;
LODWORD(v4) = 0;
while ( 1 )
{
v5 = (unsigned int)v4;
v4 = (unsigned int)(v4 + 1);
if ( *v3 == (_DWORD)a2 )
break;
++v3;
if ( v2 == (_DWORD)v4 )
return;
}
if ( gimx_params[13] )
{
printf("< remove: %d\n", a2);
fflush(stdout);
v2 = a1[5];
}
v6 = v2 - 1;
a1[5] = v6;
memmove(&a1[v5], &a1[v4], 4LL * (unsigned int)(v6 - v5));
}
}

canonical_decompiled_code:
void __fastcall func4(_DWORD *a1, __int64 a2)
{
int v2; // edx
_DWORD *v3; // rax
__int64 v4; // rbx
__int64 v5; // rbp
int v6; // edx

v2 = a1[5];
if ( v2 )
{
v3 = a1;
LODWORD(v4) = 0;
while ( 1 )
{
v5 = (unsigned int)v4;
v4 = (unsigned int)(v4 + 1);
if ( *v3 == (_DWORD)a2 )
break;
++v3;
if ( v2 == (_DWORD)v4 )
return;
}
if ( gimx_params[13] )
{
printf("< remove: %d\n", a2);
fflush(stdout);
v2 = a1[5];
}
v6 = v2 - 1;
a1[5] = v6;
memmove(&a1[v5], &a1[v4], 4LL * (unsigned int)(v6 - v5));
}
}

original_code:
static inline void haptic_sink_fifo_remove(s_haptic_sink_fifo * fifo, e_slot slot) {
    unsigned int i;
    for (i = 0; i < fifo->size; ++i) {
        if (fifo->items[i] == slot) {
            do { if(gimx_params.debug.haptic) { printf("< remove: %d\n", slot); fflush(stdout); } } while (0);
            --fifo->size;
            memmove(fifo->items + i, fifo->items + i + 1, (fifo->size - i) * sizeof(*fifo->items));
            break;
        }
    }
}

canonical_original_code:
static inline void haptic_sink_fifo_remove(struct s_haptic_sink_fifo *fifo, enum e_slot slot) {
    unsigned int i;
    for (i = 0; i < fifo->size; ++i) {
        if (fifo->items[i] == slot) {
            do { if(gimx_params.debug.haptic) { printf("< remove: %d\n", slot); fflush(stdout); } } while (0);
            --fifo->size;
            memmove(fifo->items + i, fifo->items + i + 1, (fifo->size - i) * sizeof(*fifo->items));
            break;
        }
    }
}

variable_types: enum e_slot { slot_constant=0, slot_spring=1, slot_damper=2, slot_leds=3, slot_range=4, slot_nb=5 }


decompiled_code:
void __fastcall send_report(__int64 a1)
{
int v1; // eax

v1 = ghid_write(*(_QWORD *)a1, a1 + 160, 8LL);
if ( v1 )
{
if ( v1 > 0 )
haptic_sink_lg_ack(a1);
}
else
{
*(_DWORD *)(a1 + 8) = 1;
}
}

canonical_decompiled_code:
void __fastcall func6(__int64 a1)
{
int v1; // eax

v1 = ghid_write(*(_QWORD *)a1, a1 + 160, 8LL);
if ( v1 )
{
if ( v1 > 0 )
func5(a1);
}
else
{
*(_DWORD *)(a1 + 8) = 1;
}
}

original_code:
static int send_report(int sixaxis_number, uint16_t psm, uint8_t type, uint8_t report, int blocking)
{
  uint8_t buf[128];
  int len = 0;
  int i;
  struct sixaxis_state* state = states + sixaxis_number;
  for (i = 0; sixaxis_assemble[i].func; i++)
  {
    if (sixaxis_assemble[i].type == type
        && sixaxis_assemble[i].report == report)
    {
      len = sixaxis_assemble[i].func(&buf[2], sizeof(buf) - 2, state);
      break;
    }
  }
  if (!sixaxis_assemble[i].func || len < 0)
  {
    do { if(!gimx_params.curses_status) { setColorStdout(YELLOW); printf("Warning: "); resetColorStdout(); printf("%s %s report 0x%02x, sending empty response\n", (len < 0) ? "Error assembling" : "Unknown", hid_report_name[type], report); fflush(stdout); } } while (0);
    len = 0;
  }
  buf[0] = 0xa0 | type;
  buf[1] = report;
  len += 2;
  if (gimx_params.debug.sixaxis)
  {
    gtime now = gtime_gettime();
    do { if(!gimx_params.curses_status) { printf("%lu.%06lu Sixaxis %-7s %02x:", ((gtimepart)((now) / 1000000000ULL)), (((gtimepart)((now) % 1000000000ULL)) / 1000UL), hid_report_name[type], report); fflush(stdout); } } while (0);
    for (i = 2; i < len; i++)
      do { if(!gimx_params.curses_status) { printf(" %02x", buf[i]); fflush(stdout); } } while (0);
    do { if(!gimx_params.curses_status) { printf("\n"); fflush(stdout); } } while (0);
  }
  return l2cap_abs_get()->send((psm == 0x11) ? state->channels.control.id : state->channels.interrupt.id, buf, len, blocking);
}

variable_types:
psm
unsigned short

variable_types:
type
unsigned char

variable_types:
report
unsigned char

variable_types: blocking int

variable_types:
buf
unsigned char [128]

variable_types: len int

variable_types: i int

variable_types: struct sixaxis_state { struct { char str[18]; struct bdaddr_t { unsigned char b[6]; } ba; } bdaddr_src; char bdaddr_dst[18]; int dongle_index; int sixaxis_number; struct sixaxis_state_sys { int reporting_enabled; int shutdown; int feature_ef_byte_6; enum led_state_t { LED_OFF=0, LED_FLASH=1, LED_ON=2 } led[5]; unsigned char rumble[2]; } sys; struct s_report_ds3 { unsigned char report_id; unsigned char unused1; unsigned char buttons1; unsigned char buttons2; unsigned char buttons3; unsigned char unused2; char X; char Y; char Z; char Rz; unsigned char unknown1[4]; unsigned char up; unsigned char right; unsigned char down; unsigned char left; unsigned char l2; unsigned char r2; unsigned char l1; unsigned char r1; unsigned char triangle; unsigned char circle; unsigned char cross; unsigned char square; unsigned char unknown2[15]; unsigned char acc_x[2]; unsigned char acc_y[2]; unsigned char acc_z[2]; unsigned char gyro[2]; } user; struct { struct { int id; int pending; } control; struct { int id; int pending; } interrupt; } channels; } *

variable_types:
now
unsigned long long


decompiled_code:
__int64 haptic_sink_lg_constructor()
{
return haptic_sink_register(&sink_lg);
}

canonical_decompiled_code:
__int64 func15()
{
return haptic_sink_register(&sink_lg);
}

original_code:
void haptic_sink_lg_constructor(void) {
    haptic_sink_register(&sink_lg);
}

canonical_original_code:
void haptic_sink_lg_constructor() {
    haptic_sink_register(&sink_lg);
}


decompiled_code:
__int64 __fastcall control_key(int a1, int a2)
{
int v2; // edx
__int64 result; // rax

if ( a1 == 54 )
{
rshift = a2 != 0;
result = (unsigned int)lalt;
if ( !lshift )
goto LABEL_12;
goto LABEL_8;
}
if ( a1 > 54 )
{
if ( a1 == 56 )
{
result = a2 != 0;
lalt = a2 != 0;
if ( !lshift )
goto LABEL_12;
goto LABEL_8;
}
if ( a1 == 100 )
ralt = a2 != 0;
LABEL_6:
v2 = lshift;
result = (unsigned int)lalt;
goto LABEL_7;
}
if ( a1 != 1 )
{
if ( a1 == 42 )
{
result = (unsigned int)lalt;
lshift = a2 != 0;
if ( !a2 )
goto LABEL_12;
goto LABEL_8;
}
goto LABEL_6;
}
result = (unsigned int)lalt;
if ( !lshift )
goto LABEL_12;
result = (unsigned int)lalt;
if ( !*((_QWORD *)&gimx_params + 16) )
goto LABEL_8;
set_done();
v2 = lshift;
result = (unsigned int)lalt;
LABEL_7:
if ( !v2 )
goto LABEL_12;
LABEL_8:
if ( rshift )
{
if ( *((_DWORD *)&gimx_params + 10) )
{
*((_DWORD *)&gimx_params + 10) = 0;
if ( !(_DWORD)result )
return result;
goto LABEL_13;
}
if ( !*((_DWORD *)&gimx_params + 11) )
*((_DWORD *)&gimx_params + 10) = 1;
}
LABEL_12:
if ( !(_DWORD)result )
return result;
LABEL_13:
result = (unsigned int)ralt;
if ( ralt )
{
if ( *((_QWORD *)&gimx_params + 16) )
{
result = ginput_grab_toggle();
*((_DWORD *)&gimx_params + 6) = result;
}
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func0(int a1, int a2)
{
int v2; // edx
__int64 result; // rax

if ( a1 == 54 )
{
rshift = a2 != 0;
result = (unsigned int)lalt;
if ( !lshift )
goto LABEL_12;
goto LABEL_8;
}
if ( a1 > 54 )
{
if ( a1 == 56 )
{
result = a2 != 0;
lalt = a2 != 0;
if ( !lshift )
goto LABEL_12;
goto LABEL_8;
}
if ( a1 == 100 )
ralt = a2 != 0;
LABEL_6:
v2 = lshift;
result = (unsigned int)lalt;
goto LABEL_7;
}
if ( a1 != 1 )
{
if ( a1 == 42 )
{
result = (unsigned int)lalt;
lshift = a2 != 0;
if ( !a2 )
goto LABEL_12;
goto LABEL_8;
}
goto LABEL_6;
}
result = (unsigned int)lalt;
if ( !lshift )
goto LABEL_12;
result = (unsigned int)lalt;
if ( !*((_QWORD *)&gimx_params + 16) )
goto LABEL_8;
set_done();
v2 = lshift;
result = (unsigned int)lalt;
LABEL_7:
if ( !v2 )
goto LABEL_12;
LABEL_8:
if ( rshift )
{
if ( *((_DWORD *)&gimx_params + 10) )
{
*((_DWORD *)&gimx_params + 10) = 0;
if ( !(_DWORD)result )
return result;
goto LABEL_13;
}
if ( !*((_DWORD *)&gimx_params + 11) )
*((_DWORD *)&gimx_params + 10) = 1;
}
LABEL_12:
if ( !(_DWORD)result )
return result;
LABEL_13:
result = (unsigned int)ralt;
if ( ralt )
{
if ( *((_QWORD *)&gimx_params + 16) )
{
result = ginput_grab_toggle();
*((_DWORD *)&gimx_params + 6) = result;
}
}
return result;
}

original_code:
void control_key(int sym, int down) {
    switch (sym) {
    case 1:
        if (lshift && gimx_params.config_file != ((void *)0)) {
            set_done();
        }
        break;
    case 42:
        lshift = down ? 1 : 0;
        break;
    case 54:
        rshift = down ? 1 : 0;
        break;
    case 56:
        lalt = down ? 1 : 0;
        break;
    case 100:
        ralt = down ? 1 : 0;
        break;
    }
    if (lshift && rshift) {
        if (gimx_params.status) {
            gimx_params.status = 0;
        } else {
            if (!gimx_params.curses) {
                gimx_params.status = 1;
            }
        }
    }
    if (lalt && ralt && gimx_params.config_file) {
        gimx_params.grab = ginput_grab_toggle();
    }
}

variable_types: sym int

variable_types: down int


decompiled_code:
void __fastcall report2event_set_callback(__int64 a1)
{
event_callback = a1;
}

canonical_decompiled_code:
void __fastcall func0(__int64 a1)
{
event_callback = a1;
}

original_code:
void report2event_set_callback(int (*fp)(GE_Event*))
{
  event_callback = fp;
}

canonical_original_code:
void report2event_set_callback(int (*fp)(union GE_Event *))
{
  event_callback = fp;
}

variable_types: int (*)(union GE_Event { struct { unsigned char type; unsigned char which; }; struct GE_KeyboardEvent { unsigned char type; unsigned char which; unsigned short keysym; } key; struct GE_MouseMotionEvent { unsigned char type; unsigned char which; short xrel; short yrel; } motion; struct GE_MouseButtonEvent { unsigned char type; unsigned char which; unsigned char button; } button; struct GE_JoyAxisEvent { unsigned char type; unsigned char which; unsigned char axis; short value; } jaxis; struct GE_JoyHatEvent { unsigned char type; unsigned char which; unsigned char hat; unsigned char value; } jhat; struct GE_JoyButtonEvent { unsigned char type; unsigned char which; unsigned char button; unsigned char state; } jbutton; struct GE_JoyRumbleEvent { unsigned char type; unsigned char which; unsigned short weak; unsigned short strong; } jrumble; struct GE_JoyConstantForceEvent { unsigned char type; unsigned char which; short level; } jconstant; struct GE_JoyConditionForceEvent { unsigned char type; unsigned char which; struct { unsigned short left; unsigned short right; } saturation; struct { short left; short right; } coefficient; short center; unsigned short deadband; } jcondition; struct GE_JoyPeriodicForceEvent { unsigned char type; unsigned char which; struct { int direction; unsigned short period; short magnitude; short offset; } sine; } jperiodic; } *)

user_defined_types: union GE_Event { struct { unsigned char type; unsigned char which; }; struct GE_KeyboardEvent key; struct GE_MouseMotionEvent motion; struct GE_MouseButtonEvent button; struct GE_JoyAxisEvent jaxis; struct GE_JoyHatEvent jhat; struct GE_JoyButtonEvent jbutton; struct GE_JoyRumbleEvent jrumble; struct GE_JoyConstantForceEvent jconstant; struct GE_JoyConditionForceEvent jcondition; struct GE_JoyPeriodicForceEvent jperiodic; }


decompiled_code:
int __fastcall report2event(int a1, unsigned int a2, __int64 a3, __int64 a4, unsigned int a5)
{
__int64 (__fastcall *v5)(_QWORD, __int64, __int64, _QWORD); // rax
const char *v6; // rax

v5 = (__int64 (__fastcall *)(_QWORD, __int64, __int64, _QWORD))controllers[a1];
if ( v5 )
{
if ( event_callback )
LODWORD(v5) = v5(a2, a3, a4, a5);
}
else
{
v6 = (const char *)controller_get_name();
LODWORD(v5) = fprintf(stderr, "Controller is missing a report2event function: %s\n", v6);
}
return (int)v5;
}

canonical_decompiled_code:
int __fastcall func1(int a1, unsigned int a2, __int64 a3, __int64 a4, unsigned int a5)
{
__int64 (__fastcall *v5)(_QWORD, __int64, __int64, _QWORD); // rax
const char *v6; // rax

v5 = (__int64 (__fastcall *)(_QWORD, __int64, __int64, _QWORD))controllers[a1];
if ( v5 )
{
if ( event_callback )
LODWORD(v5) = v5(a2, a3, a4, a5);
}
else
{
v6 = (const char *)controller_get_name();
LODWORD(v5) = fprintf(stderr, "Controller is missing a report2event function: %s\n", v6);
}
return (int)v5;
}

original_code:
void report2event(e_controller_type type, int adapter_id, s_report* current,
    s_report* previous, int joystick_id)
{
  if (controllers[type].r2e)
  {
    if (event_callback)
    {
      controllers[type].r2e(adapter_id, current, previous, joystick_id, event_callback);
    }
  }
  else
  {
    fprintf(stderr, "Controller is missing a report2event function: %s\n", controller_get_name(type));
  }
}

canonical_original_code:
void report2event(enum e_controller_type type, int adapter_id, union s_report *current, union s_report *previous, int joystick_id)
{
  if (controllers[type].r2e)
  {
    if (event_callback)
    {
      controllers[type].r2e(adapter_id, current, previous, joystick_id, event_callback);
    }
  }
  else
  {
    fprintf(stderr, "Controller is missing a report2event function: %s\n", controller_get_name(type));
  }
}

variable_types: enum e_controller_type { C_TYPE_JOYSTICK=0, C_TYPE_360_PAD=1, C_TYPE_SIXAXIS=2, C_TYPE_PS2_PAD=3, C_TYPE_XBOX_PAD=4, C_TYPE_DS4=5, C_TYPE_XONE_PAD=6, C_TYPE_T300RS_PS4=7, C_TYPE_G27_PS3=8, C_TYPE_G29_PS4=9, C_TYPE_DF_PS2=10, C_TYPE_DFP_PS2=11, C_TYPE_GTF_PS2=12, C_TYPE_NONE=13, C_TYPE_MAX=expr }

variable_types: union s_report { struct s_report_joystick { short X; short Y; short Z; short Rz; unsigned short Hat; unsigned short Bt; } js; struct s_report_ds2 { unsigned char head; unsigned char Bt1; unsigned char Bt2; char Z; char Rz; char X; char Y; } ds2; struct s_report_ds3 { unsigned char report_id; unsigned char unused1; unsigned char buttons1; unsigned char buttons2; unsigned char buttons3; unsigned char unused2; char X; char Y; char Z; char Rz; unsigned char unknown1[4]; unsigned char up; unsigned char right; unsigned char down; unsigned char left; unsigned char l2; unsigned char r2; unsigned char l1; unsigned char r1; unsigned char triangle; unsigned char circle; unsigned char cross; unsigned char square; unsigned char unknown2[15]; unsigned char acc_x[2]; unsigned char acc_y[2]; unsigned char acc_z[2]; unsigned char gyro[2]; } ds3; struct s_report_ds4 { unsigned char report_id; unsigned char X; unsigned char Y; unsigned char Z; unsigned char Rz; unsigned char HatAndButtons; unsigned short ButtonsAndCounter; unsigned char Rx; unsigned char Ry; unsigned short _time; unsigned char battery_level; struct s_motion_acc { short x; short y; short z; } motion_acc; struct s_motion_gyro { short roll; short yaw; short pitch; } motion_gyro; unsigned char _unknown1[5]; unsigned char ext; unsigned char _unknown2[2]; unsigned char packets; struct s_trackpad_packet { unsigned char counter; struct s_trackpad_finger { unsigned char id; unsigned char coords[3]; } finger1; struct s_trackpad_finger finger2; } packet1; struct s_trackpad_packet packet2; struct s_trackpad_packet packet3; struct s_trackpad_packet packet4; unsigned char _unknown5[2]; } ds4; struct s_report_xbox { unsigned char type; unsigned char size; unsigned char buttons; unsigned char ununsed2; unsigned char btnA; unsigned char btnB; unsigned char btnX; unsigned char btnY; unsigned char btnBlack; unsigned char btnWhite; unsigned char ltrigger; unsigned char rtrigger; short xaxis; short yaxis; short zaxis; short taxis; } xbox; struct s_report_x360 { unsigned char type; unsigned char size; unsigned short buttons; unsigned char ltrigger; unsigned char rtrigger; short xaxis; short yaxis; short zaxis; short taxis; unsigned char unused[6]; } x360; struct s_report_xone { union { unsigned char type; struct { unsigned char type; unsigned char unknown; unsigned char counter; unsigned char size; unsigned short buttons; unsigned short ltrigger; unsigned short rtrigger; short xaxis; short yaxis; short zaxis; short taxis; } input; struct { unsigned char type; unsigned char unknown1; unsigned char counter; unsigned char size; unsigned char button; unsigned char unknown2; } guide; }; } xone; struct s_report_t300rsPs4 { unsigned char report_id; unsigned char X; unsigned char Y; unsigned char Z; unsigned char Rz; unsigned char HatAndButtons; unsigned short Buttons; unsigned char unused0[35]; unsigned short wheel; unsigned short gasPedal; unsigned short brakePedal; unsigned short unknown1; unsigned char unknown2; unsigned short unknown3; unsigned char unused1[10]; } t300rsPs4; struct s_report_g27Ps3 { unsigned char hatAndButtons; unsigned short buttons; unsigned short buttonsAndWheel; unsigned char gasPedal; unsigned char brakePedal; unsigned char clutchPedal; struct { unsigned char x; unsigned char y; unsigned char b; } shifter; } g27Ps3; struct s_report_g29Ps4 { unsigned char report_id; unsigned char X; unsigned char Y; unsigned char Z; unsigned char Rz; unsigned char HatAndButtons; unsigned short Buttons; unsigned char unused0[35]; unsigned short wheel; unsigned short gasPedal; unsigned short brakePedal; unsigned short clutchPedal; unsigned char Buttons2; unsigned short unknown3; unsigned char Buttons3; unsigned char unused1[9]; } g29Ps4; struct s_report_dfPs2 { unsigned short buttonsAndWheel; unsigned char buttons; unsigned char unknown; unsigned char hat; unsigned char gasPedal; unsigned char brakePedal; } dfPs2; struct s_report_dfpPs2 { unsigned short buttonsAndWheel; unsigned short hatAndButtons; unsigned char unknown1; unsigned char gasPedal; unsigned char brakePedal; unsigned char unknown2; } dfpPs2; struct s_report_gtfPs2 { unsigned short buttonsAndWheel; unsigned char; unsigned char pedals; unsigned char gasPedal; unsigned char brakePedal; unsigned char; } gtfPs2; } *

variable_types:
previous
union s_report *

user_defined_types: union s_report { struct s_report_joystick js; struct s_report_ds2 ds2; struct s_report_ds3 ds3; struct s_report_ds4 ds4; struct s_report_xbox xbox; struct s_report_x360 x360; struct s_report_xone xone; struct s_report_t300rsPs4 t300rsPs4; struct s_report_g27Ps3 g27Ps3; struct s_report_g29Ps4 g29Ps4; struct s_report_dfPs2 dfPs2; struct s_report_dfpPs2 dfpPs2; struct s_report_gtfPs2 gtfPs2; }

user_defined_types: struct s_report_ds4 { unsigned char report_id; unsigned char X; unsigned char Y; unsigned char Z; unsigned char Rz; unsigned char HatAndButtons; unsigned short ButtonsAndCounter; unsigned char Rx; unsigned char Ry; unsigned short _time; unsigned char battery_level; struct s_motion_acc motion_acc; struct s_motion_gyro motion_gyro; unsigned char _unknown1[5]; unsigned char ext; unsigned char _unknown2[2]; unsigned char packets; struct s_trackpad_packet packet1; struct s_trackpad_packet packet2; struct s_trackpad_packet packet3; struct s_trackpad_packet packet4; unsigned char _unknown5[2]; }

user_defined_types: struct s_trackpad_packet { unsigned char counter; struct s_trackpad_finger finger1; struct s_trackpad_finger finger2; }


decompiled_code:
void haptic_sink_destructor()
{
free(sinks);
nb_sinks = 0;
}

canonical_decompiled_code:
void func2()
{
free(sinks);
nb_sinks = 0;
}

original_code:
void haptic_sink_destructor(void) {
    free(sinks);
    nb_sinks = 0;
}


decompiled_code:
int resetColorStdout()
{
return printf("%s", "\x1B[0m");
}

canonical_decompiled_code:
int func0()
{
return printf("%s", "\x1B[0m");
}

original_code:
static inline void resetColorStdout(void) {
    printf("%s", ANSI_ATTRIBUTE_RESET);
}


decompiled_code:
__int64 __fastcall button2event(__int64 (__fastcall *a1)(_BYTE *), _BYTE *a2, __int16 a3, unsigned __int16 a4, unsigned __int16 a5, char a6)
{
__int16 v6; // dx
__int64 result; // rax

v6 = a5 & a3;
result = (__int64)a1;
if ( (a4 & a5) != v6 )
{
a2[2] = a6;
*a2 = (v6 == 0) + 8;
result = a1(a2);
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func1(__int64 (__fastcall *a1)(_BYTE *), _BYTE *a2, __int16 a3, unsigned __int16 a4, unsigned __int16 a5, char a6)
{
__int16 v6; // dx
__int64 result; // rax

v6 = a5 & a3;
result = (__int64)a1;
if ( (a4 & a5) != v6 )
{
a2[2] = a6;
*a2 = (v6 == 0) + 8;
result = a1(a2);
}
return result;
}

original_code:
static inline void button2event(int (*callback)(GE_Event*), GE_Event* event, unsigned short buttons,
    unsigned short pbuttons, unsigned short button_mask, uint8_t button_id)
{
  unsigned short value;
  if((value = (buttons & button_mask)) ^ (pbuttons & button_mask))
  {
    event->type = value ? GE_JOYBUTTONDOWN : GE_JOYBUTTONUP;
    event->jbutton.button = button_id;
    callback(event);
  }
}

canonical_original_code:
static inline void button2event(int (*callback)(union GE_Event *), union GE_Event *event, unsigned short buttons, unsigned short pbuttons, unsigned short button_mask, unsigned char button_id)
{
  unsigned short value;
  if((value = (buttons & button_mask)) ^ (pbuttons & button_mask))
  {
    event->type = value ? GE_JOYBUTTONDOWN : GE_JOYBUTTONUP;
    event->jbutton.button = button_id;
    callback(event);
  }
}

variable_types:
event
union GE_Event *

variable_types:
buttons
unsigned short

variable_types:
pbuttons
unsigned short

variable_types:
value
unsigned short

user_defined_types: struct GE_KeyboardEvent { unsigned char type; unsigned char which; unsigned short keysym; }

user_defined_types: struct GE_MouseMotionEvent { unsigned char type; unsigned char which; short xrel; short yrel; }

user_defined_types: struct GE_MouseButtonEvent { unsigned char type; unsigned char which; unsigned char button; }

user_defined_types: struct GE_JoyAxisEvent { unsigned char type; unsigned char which; unsigned char axis; short value; }

user_defined_types: struct GE_JoyHatEvent { unsigned char type; unsigned char which; unsigned char hat; unsigned char value; }

user_defined_types: struct GE_JoyButtonEvent { unsigned char type; unsigned char which; unsigned char button; unsigned char state; }

user_defined_types: struct GE_JoyRumbleEvent { unsigned char type; unsigned char which; unsigned short weak; unsigned short strong; }

user_defined_types: struct GE_JoyConstantForceEvent { unsigned char type; unsigned char which; short level; }

user_defined_types: struct GE_JoyConditionForceEvent { unsigned char type; unsigned char which; struct { unsigned short left; unsigned short right; } saturation; struct { short left; short right; } coefficient; short center; unsigned short deadband; }

user_defined_types: struct GE_JoyPeriodicForceEvent { unsigned char type; unsigned char which; struct { int direction; unsigned short period; short magnitude; short offset; } sine; }


decompiled_code:
__int16 __fastcall update_finger(char *a1, int a2, _DWORD *a3, _DWORD *a4)
{
char v5; // al
__int16 v7; // si
char v8; // dl
int v9; // esi
int v10; // er12
unsigned int v11; // er12
__int16 v12; // bp
unsigned __int16 v13; // ax
char v14; // dl
__int16 result; // ax

v5 = *a1;
if ( a2 )
{
if ( v5 < 0 )
{
++v5;
v10 = 459;
v9 = 959;
}
else
{
v7 = (unsigned __int8)a1[2];
v8 = (unsigned __int8)v7 >> 4;
v9 = (unsigned __int16)(unsigned __int8)a1[1] | (v7 << 8) & 0xF00;
v10 = (16 * (unsigned __int8)a1[3]) | v8 & 0xF;
}
*a1 = v5 & 0x7F;
v11 = *a4 + v10;
v12 = clamp(0LL, (unsigned int)(*a3 + v9), 1919LL);
v13 = clamp(0LL, v11, 919LL);
a1[1] = v12;
v14 = v13;
result = v13 >> 4;
a1[3] = result;
a1[2] = (16 * v14) | HIBYTE(v12) & 0xF;
}
else
{
result = *(_WORD *)&v5 | 0xFF80;
*a1 = result;
}
return result;
}

original_code:
static inline void update_finger(s_trackpad_finger* current, s_trackpad_finger* previous, int* presence, int* axis_x, int* axis_y)
{
  unsigned char* coords = current->coords;
  unsigned char* prevCoords = previous->coords;
  if(current->id & 0x80)
  {
    if(*presence == 1)
    {
      *presence = 0;
    }
  }
  else
  {
    *presence = 1;
    unsigned short prev_x;
    unsigned short prev_y;
    if(previous->id & 0x80)
    {
      prev_x = 1919/2;
      prev_y = 919/2;
    }
    else
    {
      prev_x = ((prevCoords[1] & 0x0F) << 8) | prevCoords[0];
      prev_y = prevCoords[2] << 4 | (prevCoords[1]>>4);
    }
    *axis_x = (((coords[1] & 0x0F) << 8) | coords[0]) - prev_x;
    *axis_y = (coords[2] << 4 | (coords[1]>>4)) - prev_y;
  }
}

canonical_original_code:
static inline void update_finger(struct s_trackpad_finger *current, struct s_trackpad_finger *previous, int *presence, int *axis_x, int *axis_y)
{
  unsigned char *coords = current->coords;
  unsigned char *prevCoords = previous->coords;
  if(current->id & 0x80)
  {
    if(*presence == 1)
    {
      *presence = 0;
    }
  }
  else
  {
    *presence = 1;
    unsigned short prev_x;
    unsigned short prev_y;
    if(previous->id & 0x80)
    {
      prev_x = 1919/2;
      prev_y = 919/2;
    }
    else
    {
      prev_x = ((prevCoords[1] & 0x0F) << 8) | prevCoords[0];
      prev_y = prevCoords[2] << 4 | (prevCoords[1]>>4);
    }
    *axis_x = (((coords[1] & 0x0F) << 8) | coords[0]) - prev_x;
    *axis_y = (coords[2] << 4 | (coords[1]>>4)) - prev_y;
  }
}

variable_types: struct s_trackpad_finger { unsigned char id; unsigned char coords[3]; } *

variable_types:
previous
struct s_trackpad_finger *

variable_types:
presence
int *

variable_types:
coords
unsigned char *

variable_types:
prevCoords
unsigned char *


terminate

decompiled_code:
void terminate()
{
done = 1;
}

canonical_decompiled_code:
void func0()
{
done = 1;
}

original_code:
void terminate(int sig)
{
  done = 1;
}

canonical_original_code:
void terminate(int sig)
{
  done = 1;
}

variable_types: sig int


decompiled_code:
int __fastcall close_fd(int *a1)
{
int result; // eax

result = close(*a1);
*a1 = -1;
return result;
}

canonical_decompiled_code:
int __fastcall func1(int *a1)
{
int result; // eax

result = close(*a1);
*a1 = -1;
return result;
}

original_code:
static void close_fd(struct pollfd* pfd)
{
  close(pfd->fd);
  pfd->fd = -1;
}

canonical_original_code:
static void close_fd(struct pollfd *pfd)
{
  close(pfd->fd);
  pfd->fd = -1;
}

variable_types: struct pollfd { int fd; short events; short revents; } *


bacmp

decompiled_code:
int __fastcall bacmp(const void *a1, const void *a2)
{
return memcmp(a1, a2, 6uLL);
}

canonical_decompiled_code:
int __fastcall func2(const void *a1, const void *a2)
{
return memcmp(a1, a2, 6uLL);
}

original_code:
static inline int bacmp(const bdaddr_t *ba1, const bdaddr_t *ba2)
{
 return memcmp(ba1, ba2, sizeof(bdaddr_t));
}

canonical_original_code:
static inline int bacmp(struct bdaddr_t *ba1, struct bdaddr_t *ba2)
{
 return memcmp(ba1, ba2, sizeof(bdaddr_t));
}

variable_types: struct bdaddr_t { unsigned char b[6]; } *


dump

decompiled_code:
int __fastcall dump(unsigned __int8 *a1, int a2)
{
__int64 v2; // rbx

if ( a2 > 0 )
{
v2 = 2LL;
printf("0x%02x ", *a1);
while ( v2 != a2 + 1 )
{
printf("0x%02x ", a1[v2 - 1]);
if ( (v2 & 7) == 0 )
putchar(10);
++v2;
}
}
return putchar(10);
}

original_code:
void dump(unsigned char* buf, int len)
{
  int i;
  for(i=0; i<len; ++i)
  {
    printf("0x%02x ", buf[i]);
    if(!((i+1)%8))
    {
      printf("\n");
    }
  }
  printf("\n");
}

canonical_original_code:
void dump(unsigned char *buf, int len)
{
  int i;
  for(i=0; i<len; ++i)
  {
    printf("0x%02x ", buf[i]);
    if(!((i+1)%8))
    {
      printf("\n");
    }
  }
  printf("\n");
}

variable_types:
buf
unsigned char *

variable_types: len int

variable_types: i int


main

canonical_name: main

decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
unsigned int v3; // er12
struct pollfd *v4; // rdx
struct pollfd *v5; // rax
__int64 i; // rbx
int v7; // er14
struct pollfd *v8; // r13
struct pollfd *v9; // rbx
int v10; // edi
struct pollfd *v12; // rbx
struct pollfd *v13; // r13
__int64 v14; // rbp
int v15; // er15
struct pollfd *v16; // r14
__int16 v17; // ax
int v18; // eax
ssize_t v19; // rax
int *v20; // rax
__int64 v21; // rsi
ssize_t v22; // rax
int v23; // eax
int v24; // eax
__int64 v25; // rdx
__int64 v26; // rcx
int v27; // er8
int v28; // edi
int v29; // eax
unsigned int v30; // er8
int v31; // eax
int v32; // eax
const char *v33; // [rsp+0h] [rbp-12F8h]
struct pollfd *v34; // [rsp+8h] [rbp-12F0h]
const char *v35; // [rsp+10h] [rbp-12E8h]
unsigned __int16 fd; // [rsp+18h] [rbp-12E0h]
unsigned int fda; // [rsp+18h] [rbp-12E0h]
unsigned int fdb; // [rsp+18h] [rbp-12E0h]
unsigned int fdc; // [rsp+18h] [rbp-12E0h]
char v40; // [rsp+1Ch] [rbp-12DCh]
char v41[2]; // [rsp+3Ch] [rbp-12BCh] BYREF
__int16 v42; // [rsp+3Eh] [rbp-12BAh] BYREF
struct sched_param param; // [rsp+40h] [rbp-12B8h] BYREF
char v44[6]; // [rsp+44h] [rbp-12B4h] BYREF
char v45[6]; // [rsp+4Ah] [rbp-12AEh] BYREF
__int128 v46; // [rsp+50h] [rbp-12A8h] BYREF
__int16 v47; // [rsp+60h] [rbp-1298h]
char v48; // [rsp+62h] [rbp-1296h]
__int16 v49[19]; // [rsp+8Ah] [rbp-126Eh]
struct pollfd fds[66]; // [rsp+B0h] [rbp-1248h] BYREF
char buf[96]; // [rsp+2C0h] [rbp-1038h] BYREF
char v52[4056]; // [rsp+320h] [rbp-FD8h] BYREF

v46 = 0LL;
v47 = 0;
v48 = 0;
param.__sched_priority = sched_get_priority_max(1);
sched_setscheduler(0, 1, &param);
setlinebuf(stdout);
signal(2, (__sighandler_t)terminate);
if ( argc <= 0 )
goto LABEL_24;
v33 = argv[1];
if ( argc == 1 )
{
v35 = 0LL;
v3 = 1288;
}
else
{
v3 = 1288;
v35 = argv[2];
if ( argc != 2 )
v3 = strtol(argv[3], 0LL, 0);
}
if ( !v33 || (unsigned int)((__int64 (*)(void))bachk)() == -1 || v35 && (unsigned int)bachk(v35) == -1 )
{
LABEL_24:
printf("usage: %s <ps3-mac-address> <dongle-mac-address> <device-class>\n", *argv);
return 1;
}
str2ba(v33, v45);
if ( (int)bt_write_device_class(v35, v3) < 0 )
{
puts("failed to set device class");
return 1;
}
memset(fds, 0, 0x208uLL);
v4 = &fds[13];
do
{
v5 = v4 - 13;
do
{
v5->fd = -1;
++v5;
}
while ( v5 != v4 );
v4 = v5 + 13;
}
while ( &v5[13] != (struct pollfd *)v52 );
for ( i = 0LL; i != 13; ++i )
{
fds[i].fd = l2cap_listen((unsigned __int16)psm_list[i]);
fds[i].events = 1;
}
v40 = 0;
LABEL_18:
while ( 2 )
{
v7 = done;
if ( !done )
{
if ( !poll(fds, 0x41uLL, -1) )
continue;
v34 = fds;
while ( 1 )
{
v12 = &fds[26];
v13 = &fds[13];
v14 = 0LL;
v15 = v7;
v16 = v34;
do
{
v17 = v16->revents;
if ( (v17 & 0x18) != 0 )
{
switch ( v15 )
{
case 1:
printf("poll error from SLAVE (psm: 0x%04x)\n", (unsigned __int16)psm_list[v14]);
close_fd((int *)v13);
close_fd((int *)v12);
v17 = v16->revents;
break;
case 2:
printf("poll error from MASTER (psm: 0x%04x)\n", (unsigned __int16)psm_list[v14]);
close_fd((int *)v12);
close_fd((int *)v13);
v17 = v16->revents;
break;
case 0:
printf("poll error from listening socket (psm: 0x%04x)\n", (unsigned __int16)psm_list[v14]);
v17 = v16->revents;
break;
}
}
if ( (v17 & 4) != 0 )
{
if ( (unsigned int)l2cap_is_connected((unsigned int)v16->fd) )
{
if ( v15 == 3 )
{
printf("connected to %s (psm: 0x%04x)\n", (const char *)&v46, (unsigned __int16)psm_list[v14]);
v29 = v12[13].fd;
v12[-13].events = 1;
v12[-13].fd = v29;
}
else if ( v15 == 4 )
{
printf("connected to %s (psm: 0x%04x)\n", v33, (unsigned __int16)psm_list[v14]);
v18 = v12[26].fd;
v12->events = 1;
v12->fd = v18;
}
v16->fd = -1;
}
v17 = v16->revents;
}
if ( (v17 & 1) != 0 )
{
if ( v15 == 1 )
{
if ( v12->fd >= 0 )
{
v22 = read(v12[-13].fd, buf, 0x1000uLL);
++v40;
if ( psm_list[v14] != 19 || (v40 & 7) == 0 )
{
fd = psm_list[v14];
if ( v22 > 0 )
{
if ( (int)l2cap_send(
v33,
(unsigned __int16)v49[v14 + 13],
(unsigned int)v12->fd,
buf,
(unsigned int)v22) < 0 )
printf("write error (SLAVE > MASTER) (psm: 0x%04x)\n", fd);
}
else if ( *_errno_location() == 4 )
{
printf("write interrupted (SLAVE > MASTER) (psm: 0x%04x)\n", fd);
}
else
{
printf("recv error from SLAVE (psm: 0x%04x)\n", fd);
close_fd((int *)v13);
close_fd((int *)v12);
}
}
}
}
else if ( v15 == 2 )
{
if ( v12[-13].fd >= 0 )
{
v19 = read(v12->fd, buf, 0x1000uLL);
if ( v19 > 0 )
{
if ( (int)l2cap_send(
v33,
(unsigned __int16)v49[v14],
(unsigned int)v12[-13].fd,
buf,
(unsigned int)v19) < 0 )
printf("write error (MASTER > SLAVE) (psm: 0x%04x)\n", (unsigned __int16)psm_list[v14]);
}
else
{
v20 = _errno_location();
v21 = (unsigned __int16)psm_list[v14];
if ( *v20 == 4 )
{
printf("write interrupted (MASTER > SLAVE) (psm: 0x%04x)\n", v21);
}
else
{
printf("recv error from server (psm: 0x%04x)\n", v21);
close_fd((int *)v12);
close_fd((int *)v13);
}
}
}
}
else
{
if ( v15 )
goto LABEL_31;
v23 = l2cap_accept((unsigned int)v12[-26].fd, v44, v41, &v42);
if ( v23 < 0 )
{
printf("accept error (psm: 0x%04x)\n", (unsigned __int16)psm_list[v14]);
}
else
{
fda = v23;
v24 = bacmp(v44, v45);
v27 = fda;
if ( v24 )
{
ba2str(v44, &v46, v25, v26, fda);
v27 = fda;
if ( v12[-13].fd >= 0 )
{
LABEL_58:
close(v27);
fprintf(stderr, "psm already used: 0x%04x\n", (unsigned __int16)psm_list[v14]);
goto LABEL_31;
}
v12[-13].fd = fda;
v30 = (unsigned __int16)psm_list[v14];
v12[-13].events = 1;
fdb = v30;
printf("connecting with %s to %s (psm: 0x%04x)\n", v35, v33, v30);
v31 = l2cap_connect(v35, v33, fdb);
v12[26].events = 4;
v12[26].fd = v31;
if ( v31 < 0 )
{
printf("can't start connection to MASTER (psm: 0x%04x)\n", fdb);
close_fd((int *)v13);
}
}
else
{
v28 = v12->fd;
v49[v14] = v42;
if ( v28 >= 0 )
goto LABEL_58;
v12->fd = fda;
v12->events = 1;
fdc = (unsigned __int16)psm_list[v14];
printf(
"connecting with %s to %s (psm: 0x%04x)\n",
v35,
(const char *)&v46,
(unsigned __int16)psm_list[v14]);
v32 = l2cap_connect(v35, &v46, fdc);
v12[13].fd = v32;
v12[13].events = 4;
if ( v32 < 0 )
{
printf("can't start connection to SLAVE (psm: 0x%04x)\n", fdc);
close_fd((int *)v12);
}
}
}
}
}
LABEL_31:
++v12;
++v16;
++v13;
++v14;
}
while ( v12 != &fds[39] );
v34 += 13;
v7 = v15 + 1;
if ( v15 == 4 )
goto LABEL_18;
}
}
break;
}
v8 = &fds[13];
do
{
v9 = v8 - 13;
do
{
v10 = v9->fd;
++v9;
close(v10);
}
while ( v9 != v8 );
v8 = v9 + 13;
}
while ( &v9[13] != (struct pollfd *)v52 );
return 0;
}

canonical_decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
unsigned int v3; // er12
struct pollfd *v4; // rdx
struct pollfd *v5; // rax
__int64 i; // rbx
int v7; // er14
struct pollfd *v8; // r13
struct pollfd *v9; // rbx
int v10; // edi
struct pollfd *v12; // rbx
struct pollfd *v13; // r13
__int64 v14; // rbp
int v15; // er15
struct pollfd *v16; // r14
__int16 v17; // ax
int v18; // eax
ssize_t v19; // rax
int *v20; // rax
__int64 v21; // rsi
ssize_t v22; // rax
int v23; // eax
int v24; // eax
__int64 v25; // rdx
__int64 v26; // rcx
int v27; // er8
int v28; // edi
int v29; // eax
unsigned int v30; // er8
int v31; // eax
int v32; // eax
const char *v33; // [rsp+0h] [rbp-12F8h]
struct pollfd *v34; // [rsp+8h] [rbp-12F0h]
const char *v35; // [rsp+10h] [rbp-12E8h]
unsigned __int16 fd; // [rsp+18h] [rbp-12E0h]
unsigned int fda; // [rsp+18h] [rbp-12E0h]
unsigned int fdb; // [rsp+18h] [rbp-12E0h]
unsigned int fdc; // [rsp+18h] [rbp-12E0h]
char v40; // [rsp+1Ch] [rbp-12DCh]
char v41[2]; // [rsp+3Ch] [rbp-12BCh] BYREF
__int16 v42; // [rsp+3Eh] [rbp-12BAh] BYREF
struct sched_param param; // [rsp+40h] [rbp-12B8h] BYREF
char v44[6]; // [rsp+44h] [rbp-12B4h] BYREF
char v45[6]; // [rsp+4Ah] [rbp-12AEh] BYREF
__int128 v46; // [rsp+50h] [rbp-12A8h] BYREF
__int16 v47; // [rsp+60h] [rbp-1298h]
char v48; // [rsp+62h] [rbp-1296h]
__int16 v49[19]; // [rsp+8Ah] [rbp-126Eh]
struct pollfd fds[66]; // [rsp+B0h] [rbp-1248h] BYREF
char buf[96]; // [rsp+2C0h] [rbp-1038h] BYREF
char v52[4056]; // [rsp+320h] [rbp-FD8h] BYREF

v46 = 0LL;
v47 = 0;
v48 = 0;
param.__sched_priority = sched_get_priority_max(1);
sched_setscheduler(0, 1, &param);
setlinebuf(stdout);
signal(2, (__sighandler_t)terminate);
if ( argc <= 0 )
goto LABEL_24;
v33 = argv[1];
if ( argc == 1 )
{
v35 = 0LL;
v3 = 1288;
}
else
{
v3 = 1288;
v35 = argv[2];
if ( argc != 2 )
v3 = strtol(argv[3], 0LL, 0);
}
if ( !v33 || (unsigned int)((__int64 (*)(void))bachk)() == -1 || v35 && (unsigned int)bachk(v35) == -1 )
{
LABEL_24:
printf("usage: %s <ps3-mac-address> <dongle-mac-address> <device-class>\n", *argv);
return 1;
}
str2ba(v33, v45);
if ( (int)bt_write_device_class(v35, v3) < 0 )
{
puts("failed to set device class");
return 1;
}
memset(fds, 0, 0x208uLL);
v4 = &fds[13];
do
{
v5 = v4 - 13;
do
{
v5->fd = -1;
++v5;
}
while ( v5 != v4 );
v4 = v5 + 13;
}
while ( &v5[13] != (struct pollfd *)v52 );
for ( i = 0LL; i != 13; ++i )
{
fds[i].fd = l2cap_listen((unsigned __int16)psm_list[i]);
fds[i].events = 1;
}
v40 = 0;
LABEL_18:
while ( 2 )
{
v7 = done;
if ( !done )
{
if ( !poll(fds, 0x41uLL, -1) )
continue;
v34 = fds;
while ( 1 )
{
v12 = &fds[26];
v13 = &fds[13];
v14 = 0LL;
v15 = v7;
v16 = v34;
do
{
v17 = v16->revents;
if ( (v17 & 0x18) != 0 )
{
switch ( v15 )
{
case 1:
printf("poll error from SLAVE (psm: 0x%04x)\n", (unsigned __int16)psm_list[v14]);
func1((int *)v13);
func1((int *)v12);
v17 = v16->revents;
break;
case 2:
printf("poll error from MASTER (psm: 0x%04x)\n", (unsigned __int16)psm_list[v14]);
func1((int *)v12);
func1((int *)v13);
v17 = v16->revents;
break;
case 0:
printf("poll error from listening socket (psm: 0x%04x)\n", (unsigned __int16)psm_list[v14]);
v17 = v16->revents;
break;
}
}
if ( (v17 & 4) != 0 )
{
if ( (unsigned int)l2cap_is_connected((unsigned int)v16->fd) )
{
if ( v15 == 3 )
{
printf("connected to %s (psm: 0x%04x)\n", (const char *)&v46, (unsigned __int16)psm_list[v14]);
v29 = v12[13].fd;
v12[-13].events = 1;
v12[-13].fd = v29;
}
else if ( v15 == 4 )
{
printf("connected to %s (psm: 0x%04x)\n", v33, (unsigned __int16)psm_list[v14]);
v18 = v12[26].fd;
v12->events = 1;
v12->fd = v18;
}
v16->fd = -1;
}
v17 = v16->revents;
}
if ( (v17 & 1) != 0 )
{
if ( v15 == 1 )
{
if ( v12->fd >= 0 )
{
v22 = read(v12[-13].fd, buf, 0x1000uLL);
++v40;
if ( psm_list[v14] != 19 || (v40 & 7) == 0 )
{
fd = psm_list[v14];
if ( v22 > 0 )
{
if ( (int)l2cap_send(
v33,
(unsigned __int16)v49[v14 + 13],
(unsigned int)v12->fd,
buf,
(unsigned int)v22) < 0 )
printf("write error (SLAVE > MASTER) (psm: 0x%04x)\n", fd);
}
else if ( *_errno_location() == 4 )
{
printf("write interrupted (SLAVE > MASTER) (psm: 0x%04x)\n", fd);
}
else
{
printf("recv error from SLAVE (psm: 0x%04x)\n", fd);
func1((int *)v13);
func1((int *)v12);
}
}
}
}
else if ( v15 == 2 )
{
if ( v12[-13].fd >= 0 )
{
v19 = read(v12->fd, buf, 0x1000uLL);
if ( v19 > 0 )
{
if ( (int)l2cap_send(
v33,
(unsigned __int16)v49[v14],
(unsigned int)v12[-13].fd,
buf,
(unsigned int)v19) < 0 )
printf("write error (MASTER > SLAVE) (psm: 0x%04x)\n", (unsigned __int16)psm_list[v14]);
}
else
{
v20 = _errno_location();
v21 = (unsigned __int16)psm_list[v14];
if ( *v20 == 4 )
{
printf("write interrupted (MASTER > SLAVE) (psm: 0x%04x)\n", v21);
}
else
{
printf("recv error from server (psm: 0x%04x)\n", v21);
func1((int *)v12);
func1((int *)v13);
}
}
}
}
else
{
if ( v15 )
goto LABEL_31;
v23 = l2cap_accept((unsigned int)v12[-26].fd, v44, v41, &v42);
if ( v23 < 0 )
{
printf("accept error (psm: 0x%04x)\n", (unsigned __int16)psm_list[v14]);
}
else
{
fda = v23;
v24 = func2(v44, v45);
v27 = fda;
if ( v24 )
{
ba2str(v44, &v46, v25, v26, fda);
v27 = fda;
if ( v12[-13].fd >= 0 )
{
LABEL_58:
close(v27);
fprintf(stderr, "psm already used: 0x%04x\n", (unsigned __int16)psm_list[v14]);
goto LABEL_31;
}
v12[-13].fd = fda;
v30 = (unsigned __int16)psm_list[v14];
v12[-13].events = 1;
fdb = v30;
printf("connecting with %s to %s (psm: 0x%04x)\n", v35, v33, v30);
v31 = l2cap_connect(v35, v33, fdb);
v12[26].events = 4;
v12[26].fd = v31;
if ( v31 < 0 )
{
printf("can't start connection to MASTER (psm: 0x%04x)\n", fdb);
func1((int *)v13);
}
}
else
{
v28 = v12->fd;
v49[v14] = v42;
if ( v28 >= 0 )
goto LABEL_58;
v12->fd = fda;
v12->events = 1;
fdc = (unsigned __int16)psm_list[v14];
printf(
"connecting with %s to %s (psm: 0x%04x)\n",
v35,
(const char *)&v46,
(unsigned __int16)psm_list[v14]);
v32 = l2cap_connect(v35, &v46, fdc);
v12[13].fd = v32;
v12[13].events = 4;
if ( v32 < 0 )
{
printf("can't start connection to SLAVE (psm: 0x%04x)\n", fdc);
func1((int *)v12);
}
}
}
}
}
LABEL_31:
++v12;
++v16;
++v13;
++v14;
}
while ( v12 != &fds[39] );
v34 += 13;
v7 = v15 + 1;
if ( v15 == 4 )
goto LABEL_18;
}
}
break;
}
v8 = &fds[13];
do
{
v9 = v8 - 13;
do
{
v10 = v9->fd;
++v9;
close(v10);
}
while ( v9 != v8 );
v8 = v9 + 13;
}
while ( &v9[13] != (struct pollfd *)v52 );
return 0;
}

original_code:
int main(int argc, char *argv[])
{
  char* master = ((void *)0);
  char* local = ((void *)0);
  uint32_t device_class = 0x508;
  unsigned char buf[4096];
  ssize_t len;
  int ret;
  unsigned int cpt = 0;
  bdaddr_t bdaddr_a;
  unsigned short psm_a;
  unsigned short cid_a;
  int fd_a;
  bdaddr_t bdaddr_m;
  char slave[sizeof("00:00:00:00:00:00")+1] = {};
  unsigned short cid[2][(sizeof(psm_list)/sizeof(*psm_list))];
  struct sched_param p =
  { .sched_priority = sched_get_priority_max(1) };
  sched_setscheduler(0, 1, &p);
  setlinebuf(stdout);
  (void) signal(2, terminate);
  if (argc >= 1)
    master = argv[1];
  if (argc >= 2)
    local = argv[2];
  if (argc >= 3)
    device_class = strtol(argv[3], ((void *)0), 0);
  if (!master || bachk(master) == -1 || (local && bachk(local) == -1)) {
    printf("usage: %s <ps3-mac-address> <dongle-mac-address> <device-class>\n", *argv);
    return 1;
  }
  str2ba(master, &bdaddr_m);
  if(bt_write_device_class(local, device_class) < 0)
  {
    printf("failed to set device class\n");
    return 1;
  }
  struct pollfd pfd[5][(sizeof(psm_list)/sizeof(*psm_list))] = {};
  int i, psm;
  for(i=0; i<5; ++i)
  {
    for(psm=0; psm<(sizeof(psm_list)/sizeof(*psm_list)); ++psm)
    {
      pfd[i][psm].fd = -1;
    }
  }
  for(psm=0; psm<(sizeof(psm_list)/sizeof(*psm_list)); ++psm)
  {
    pfd[0][psm].fd = l2cap_listen(psm_list[psm]);
    pfd[0][psm].events = 0x001;
  }
  while(!done)
  {
    if(poll(*pfd, 5*(sizeof(psm_list)/sizeof(*psm_list)), -1))
    {
      for(i=0; i<5; ++i)
      {
        for(psm=0; psm<(sizeof(psm_list)/sizeof(*psm_list)); ++psm)
        {
          if (pfd[i][psm].revents & (0x008 | 0x010))
          {
            switch(i)
            {
              case 0:
                printf("poll error from listening socket (psm: 0x%04x)\n", psm_list[psm]);
                break;
              case 1:
                printf("poll error from SLAVE (psm: 0x%04x)\n", psm_list[psm]);
                close_fd(&pfd[1][psm]);
                close_fd(&pfd[2][psm]);
                break;
              case 2:
                printf("poll error from MASTER (psm: 0x%04x)\n", psm_list[psm]);
                close_fd(&pfd[2][psm]);
                close_fd(&pfd[1][psm]);
                break;
            }
          }
          if(pfd[i][psm].revents & 0x004)
          {
            if(l2cap_is_connected(pfd[i][psm].fd))
            {
              switch(i)
              {
                case 3:
                  printf("connected to %s (psm: 0x%04x)\n", slave, psm_list[psm]);
                  pfd[1][psm].fd = pfd[i][psm].fd;
                  pfd[1][psm].events = 0x001;
                  break;
                case 4:
                  printf("connected to %s (psm: 0x%04x)\n", master, psm_list[psm]);
                  pfd[2][psm].fd = pfd[i][psm].fd;
                  pfd[2][psm].events = 0x001;
                  break;
              }
              pfd[i][psm].fd = -1;
            }
          }
          if(pfd[i][psm].revents & 0x001)
          {
            switch(i)
            {
              case 0:
                fd_a = l2cap_accept(pfd[i][psm].fd, &bdaddr_a, &psm_a, &cid_a);
                if(fd_a < 0)
                {
                  printf("accept error (psm: 0x%04x)\n", psm_list[psm]);
                  break;
                }
                if(bacmp(&bdaddr_a, &bdaddr_m))
                {
                  ba2str(&bdaddr_a, slave);
                  cid[0][psm] = cid_a;
                  if(pfd[1][psm].fd < 0)
                  {
                    pfd[1][psm].fd = fd_a;
                    pfd[1][psm].events = 0x001;
                    printf("connecting with %s to %s (psm: 0x%04x)\n", local, master, psm_list[psm]);
                    pfd[4][psm].fd = l2cap_connect(local, master, psm_list[psm]);
                    pfd[4][psm].events = 0x004;
                    if(pfd[4][psm].fd < 0)
                    {
                      printf("can't start connection to MASTER (psm: 0x%04x)\n", psm_list[psm]);
                      close_fd(&pfd[1][psm]);
                    }
                  }
                  else
                  {
                    close(fd_a);
                    fprintf(stderr, "psm already used: 0x%04x\n", psm_list[psm]);
                  }
                }
                else
                {
                  cid[1][psm] = cid_a;
                  if(pfd[2][psm].fd < 0)
                  {
                    pfd[2][psm].fd = fd_a;
                    pfd[2][psm].events = 0x001;
                    printf("connecting with %s to %s (psm: 0x%04x)\n", local, slave, psm_list[psm]);
                    pfd[3][psm].fd = l2cap_connect(local, slave, psm_list[psm]);
                    pfd[3][psm].events = 0x004;
                    if(pfd[3][psm].fd < 0)
                    {
                      printf("can't start connection to SLAVE (psm: 0x%04x)\n", psm_list[psm]);
                      close_fd(&pfd[2][psm]);
                    }
                  }
                  else
                  {
                    close(fd_a);
                    fprintf(stderr, "psm already used: 0x%04x\n", psm_list[psm]);
                  }
                }
                break;
              case 1:
                if(pfd[2][psm].fd < 0)
                {
                  break;
                }
                len = read(pfd[1][psm].fd, buf, sizeof(buf));
                cpt++;
                if(psm_list[psm] == 0x0013)
                {
                  if(cpt%8)
                  {
                    break;
                  }
                }
                if (len > 0)
                {
                  ret = l2cap_send(master, cid[2][psm], pfd[2][psm].fd, buf, len);
                  if(ret < 0)
                  {
                    printf("write error (SLAVE > MASTER) (psm: 0x%04x)\n", psm_list[psm]);
                  }
                  if(debug)
                  {
                    printf("SLAVE > MASTER (psm: 0x%04x)\n", psm_list[psm]);
                    dump(buf, len);
                  }
                }
                else if((*__errno_location ()) != 4)
                {
                  printf("recv error from SLAVE (psm: 0x%04x)\n", psm_list[psm]);
                  close_fd(&pfd[1][psm]);
                  close_fd(&pfd[2][psm]);
                }
                else
                {
                  printf("write interrupted (SLAVE > MASTER) (psm: 0x%04x)\n", psm_list[psm]);
                }
                break;
              case 2:
                if(pfd[1][psm].fd < 0)
                {
                  break;
                }
                len = read(pfd[2][psm].fd, buf, sizeof(buf));
                if (len > 0)
                {
                  ret = l2cap_send(master, cid[1][psm], pfd[1][psm].fd, buf, len);
                  if(ret < 0)
                  {
                    printf("write error (MASTER > SLAVE) (psm: 0x%04x)\n", psm_list[psm]);
                  }
                  if(debug)
                  {
                    printf("MASTER > SLAVE (psm: 0x%04x)\n", psm_list[psm]);
                    dump(buf, len);
                  }
                }
                else if((*__errno_location ()) != 4)
                {
                  printf("recv error from server (psm: 0x%04x)\n", psm_list[psm]);
                  close_fd(&pfd[2][psm]);
                  close_fd(&pfd[1][psm]);
                }
                else
                {
                  printf("write interrupted (MASTER > SLAVE) (psm: 0x%04x)\n", psm_list[psm]);
                }
                break;
            }
          }
        }
      }
    }
  }
  for(i=0; i<5; ++i)
  {
    for(psm=0; psm<(sizeof(psm_list)/sizeof(*psm_list)); ++psm)
    {
      close(pfd[i][psm].fd);
    }
  }
  return 0;
}

canonical_original_code:
int main(int argc, char *argv[])
{
  char *master = ((void *)0);
  char *local = ((void *)0);
  unsigned int device_class = 0x508;
  unsigned char buf[4096];
  long len;
  int ret;
  unsigned int cpt = 0;
  struct bdaddr_t bdaddr_a;
  unsigned short psm_a;
  unsigned short cid_a;
  int fd_a;
  struct bdaddr_t bdaddr_m;
  char slave[-1] = {};
  unsigned short cid[2][-1];
  struct sched_param p = { .sched_priority = sched_get_priority_max(1) };
  sched_setscheduler(0, 1, &p);
  setlinebuf(stdout);
  (void) signal(2, terminate);
  if (argc >= 1)
    master = argv[1];
  if (argc >= 2)
    local = argv[2];
  if (argc >= 3)
    device_class = strtol(argv[3], ((void *)0), 0);
  if (!master || bachk(master) == -1 || (local && bachk(local) == -1)) {
    printf("usage: %s <ps3-mac-address> <dongle-mac-address> <device-class>\n", *argv);
    return 1;
  }
  str2ba(master, &bdaddr_m);
  if(bt_write_device_class(local, device_class) < 0)
  {
    printf("failed to set device class\n");
    return 1;
  }
  struct pollfd pfd[5][-1] = {};
  int i; int psm;
  for(i=0; i<5; ++i)
  {
    for(psm=0; psm<(sizeof(psm_list)/sizeof(*psm_list)); ++psm)
    {
      pfd[i][psm].fd = -1;
    }
  }
  for(psm=0; psm<(sizeof(psm_list)/sizeof(*psm_list)); ++psm)
  {
    pfd[0][psm].fd = l2cap_listen(psm_list[psm]);
    pfd[0][psm].events = 0x001;
  }
  while(!done)
  {
    if(poll(*pfd, 5*(sizeof(psm_list)/sizeof(*psm_list)), -1))
    {
      for(i=0; i<5; ++i)
      {
        for(psm=0; psm<(sizeof(psm_list)/sizeof(*psm_list)); ++psm)
        {
          if (pfd[i][psm].revents & (0x008 | 0x010))
          {
            switch(i)
            {
              case 0:
                printf("poll error from listening socket (psm: 0x%04x)\n", psm_list[psm]);
                break;
              case 1:
                printf("poll error from SLAVE (psm: 0x%04x)\n", psm_list[psm]);
                close_fd(&pfd[1][psm]);
                close_fd(&pfd[2][psm]);
                break;
              case 2:
                printf("poll error from MASTER (psm: 0x%04x)\n", psm_list[psm]);
                close_fd(&pfd[2][psm]);
                close_fd(&pfd[1][psm]);
                break;
            }
          }
          if(pfd[i][psm].revents & 0x004)
          {
            if(l2cap_is_connected(pfd[i][psm].fd))
            {
              switch(i)
              {
                case 3:
                  printf("connected to %s (psm: 0x%04x)\n", slave, psm_list[psm]);
                  pfd[1][psm].fd = pfd[i][psm].fd;
                  pfd[1][psm].events = 0x001;
                  break;
                case 4:
                  printf("connected to %s (psm: 0x%04x)\n", master, psm_list[psm]);
                  pfd[2][psm].fd = pfd[i][psm].fd;
                  pfd[2][psm].events = 0x001;
                  break;
              }
              pfd[i][psm].fd = -1;
            }
          }
          if(pfd[i][psm].revents & 0x001)
          {
            switch(i)
            {
              case 0:
                fd_a = l2cap_accept(pfd[i][psm].fd, &bdaddr_a, &psm_a, &cid_a);
                if(fd_a < 0)
                {
                  printf("accept error (psm: 0x%04x)\n", psm_list[psm]);
                  break;
                }
                if(bacmp(&bdaddr_a, &bdaddr_m))
                {
                  ba2str(&bdaddr_a, slave);
                  cid[0][psm] = cid_a;
                  if(pfd[1][psm].fd < 0)
                  {
                    pfd[1][psm].fd = fd_a;
                    pfd[1][psm].events = 0x001;
                    printf("connecting with %s to %s (psm: 0x%04x)\n", local, master, psm_list[psm]);
                    pfd[4][psm].fd = l2cap_connect(local, master, psm_list[psm]);
                    pfd[4][psm].events = 0x004;
                    if(pfd[4][psm].fd < 0)
                    {
                      printf("can't start connection to MASTER (psm: 0x%04x)\n", psm_list[psm]);
                      close_fd(&pfd[1][psm]);
                    }
                  }
                  else
                  {
                    close(fd_a);
                    fprintf(stderr, "psm already used: 0x%04x\n", psm_list[psm]);
                  }
                }
                else
                {
                  cid[1][psm] = cid_a;
                  if(pfd[2][psm].fd < 0)
                  {
                    pfd[2][psm].fd = fd_a;
                    pfd[2][psm].events = 0x001;
                    printf("connecting with %s to %s (psm: 0x%04x)\n", local, slave, psm_list[psm]);
                    pfd[3][psm].fd = l2cap_connect(local, slave, psm_list[psm]);
                    pfd[3][psm].events = 0x004;
                    if(pfd[3][psm].fd < 0)
                    {
                      printf("can't start connection to SLAVE (psm: 0x%04x)\n", psm_list[psm]);
                      close_fd(&pfd[2][psm]);
                    }
                  }
                  else
                  {
                    close(fd_a);
                    fprintf(stderr, "psm already used: 0x%04x\n", psm_list[psm]);
                  }
                }
                break;
              case 1:
                if(pfd[2][psm].fd < 0)
                {
                  break;
                }
                len = read(pfd[1][psm].fd, buf, sizeof(buf));
                cpt++;
                if(psm_list[psm] == 0x0013)
                {
                  if(cpt%8)
                  {
                    break;
                  }
                }
                if (len > 0)
                {
                  ret = l2cap_send(master, cid[2][psm], pfd[2][psm].fd, buf, len);
                  if(ret < 0)
                  {
                    printf("write error (SLAVE > MASTER) (psm: 0x%04x)\n", psm_list[psm]);
                  }
                  if(debug)
                  {
                    printf("SLAVE > MASTER (psm: 0x%04x)\n", psm_list[psm]);
                    dump(buf, len);
                  }
                }
                else if((*__errno_location ()) != 4)
                {
                  printf("recv error from SLAVE (psm: 0x%04x)\n", psm_list[psm]);
                  close_fd(&pfd[1][psm]);
                  close_fd(&pfd[2][psm]);
                }
                else
                {
                  printf("write interrupted (SLAVE > MASTER) (psm: 0x%04x)\n", psm_list[psm]);
                }
                break;
              case 2:
                if(pfd[1][psm].fd < 0)
                {
                  break;
                }
                len = read(pfd[2][psm].fd, buf, sizeof(buf));
                if (len > 0)
                {
                  ret = l2cap_send(master, cid[1][psm], pfd[1][psm].fd, buf, len);
                  if(ret < 0)
                  {
                    printf("write error (MASTER > SLAVE) (psm: 0x%04x)\n", psm_list[psm]);
                  }
                  if(debug)
                  {
                    printf("MASTER > SLAVE (psm: 0x%04x)\n", psm_list[psm]);
                    dump(buf, len);
                  }
                }
                else if((*__errno_location ()) != 4)
                {
                  printf("recv error from server (psm: 0x%04x)\n", psm_list[psm]);
                  close_fd(&pfd[2][psm]);
                  close_fd(&pfd[1][psm]);
                }
                else
                {
                  printf("write interrupted (MASTER > SLAVE) (psm: 0x%04x)\n", psm_list[psm]);
                }
                break;
            }
          }
        }
      }
    }
  }
  for(i=0; i<5; ++i)
  {
    for(psm=0; psm<(sizeof(psm_list)/sizeof(*psm_list)); ++psm)
    {
      close(pfd[i][psm].fd);
    }
  }
  return 0;
}

variable_types: argc int

variable_types:
argv
char *[]

variable_types:
master
char *

variable_types:
local
char *

variable_types:
buf
unsigned char [4096]

variable_types: len long

variable_types: ret int

variable_types:
cpt
unsigned int

variable_types:
slave
char [-1]

variable_types:
cid
unsigned short [2][-1]

variable_types: struct sched_param { int sched_priority; }

variable_types: struct pollfd { int fd; short events; short revents; } [5][-1]

variable_types: psm int


bacpy

decompiled_code:
__int64 __fastcall bacpy(__int64 a1, __int64 a2)
{
__int64 result; // rax

*(_DWORD *)a1 = *(_DWORD *)a2;
result = *(unsigned __int16 *)(a2 + 4);
*(_WORD *)(a1 + 4) = result;
return result;
}

canonical_decompiled_code:
__int64 __fastcall func0(__int64 a1, __int64 a2)
{
__int64 result; // rax

*(_DWORD *)a1 = *(_DWORD *)a2;
result = *(unsigned __int16 *)(a2 + 4);
*(_WORD *)(a1 + 4) = result;
return result;
}

original_code:
static inline void bacpy(bdaddr_t *dst, const bdaddr_t *src)
{
 memcpy(dst, src, sizeof(bdaddr_t));
}

canonical_original_code:
static inline void bacpy(struct bdaddr_t *dst, struct bdaddr_t *src)
{
 memcpy(dst, src, sizeof(bdaddr_t));
}

variable_types: struct bdaddr_t { unsigned char b[6]; } *

variable_types:
src
struct bdaddr_t *


decompiled_code:
void __fastcall l2cap_setsockopt(int fd)
{
char v1; // [rsp+Bh] [rbp-1Dh] BYREF
socklen_t optlen; // [rsp+Ch] [rbp-1Ch] BYREF
int optval; // [rsp+10h] [rbp-18h] BYREF
__int64 v4; // [rsp+14h] [rbp-14h] BYREF
int v5; // [rsp+1Ch] [rbp-Ch]

optlen = 12;
optval = 1;
if ( setsockopt(fd, 6, 3, &optval, 4u) < 0 )
perror("setsockopt L2CAP_LM");
v5 = 0;
v4 = 0LL;
if ( getsockopt(fd, 6, 1, &v4, &optlen) < 0 )
{
perror("getsockopt L2CAP_OPTIONS");
}
else
{
LODWORD(v4) = 67109888;
if ( setsockopt(fd, 6, 1, &v4, 0xCu) < 0 )
perror("setsockopt L2CAP_OPTIONS");
}
v1 = 0;
if ( setsockopt(fd, 274, 9, &v1, 1u) < 0 )
perror("setsockopt BT_POWER");
}

canonical_decompiled_code:
void __fastcall func1(int fd)
{
char v1; // [rsp+Bh] [rbp-1Dh] BYREF
socklen_t optlen; // [rsp+Ch] [rbp-1Ch] BYREF
int optval; // [rsp+10h] [rbp-18h] BYREF
__int64 v4; // [rsp+14h] [rbp-14h] BYREF
int v5; // [rsp+1Ch] [rbp-Ch]

optlen = 12;
optval = 1;
if ( setsockopt(fd, 6, 3, &optval, 4u) < 0 )
perror("setsockopt L2CAP_LM");
v5 = 0;
v4 = 0LL;
if ( getsockopt(fd, 6, 1, &v4, &optlen) < 0 )
{
perror("getsockopt L2CAP_OPTIONS");
}
else
{
LODWORD(v4) = 67109888;
if ( setsockopt(fd, 6, 1, &v4, 0xCu) < 0 )
perror("setsockopt L2CAP_OPTIONS");
}
v1 = 0;
if ( setsockopt(fd, 274, 9, &v1, 1u) < 0 )
perror("setsockopt BT_POWER");
}

original_code:
static void l2cap_setsockopt(int fd)
{
  struct l2cap_options l2o;
  socklen_t len = sizeof(l2o);
  int opt = 0x0001;
  if (setsockopt(fd, 6, 0x03, &opt, sizeof(opt)) < 0)
  {
    perror("setsockopt L2CAP_LM");
  }
  memset(&l2o, 0, sizeof(l2o));
  if(getsockopt(fd, 6, 0x01, &l2o, &len) < 0)
  {
    perror("getsockopt L2CAP_OPTIONS");
  }
  else
  {
    l2o.omtu = 1024;
    l2o.imtu = 1024;
    if(setsockopt(fd, 6, 0x01, &l2o, sizeof(l2o)) < 0)
    {
      perror("setsockopt L2CAP_OPTIONS");
    }
  }
  struct bt_power pwr = {.force_active = 0};
  if (setsockopt(fd, 274, 9, &pwr, sizeof(pwr)) < 0)
  {
    perror("setsockopt BT_POWER");
  }
}

canonical_original_code:
static void l2cap_setsockopt(int fd)
{
  struct l2cap_options l2o;
  unsigned int len = sizeof(l2o);
  int opt = 0x0001;
  if (setsockopt(fd, 6, 0x03, &opt, sizeof(opt)) < 0)
  {
    perror("setsockopt L2CAP_LM");
  }
  memset(&l2o, 0, sizeof(l2o));
  if(getsockopt(fd, 6, 0x01, &l2o, &len) < 0)
  {
    perror("getsockopt L2CAP_OPTIONS");
  }
  else
  {
    l2o.omtu = 1024;
    l2o.imtu = 1024;
    if(setsockopt(fd, 6, 0x01, &l2o, sizeof(l2o)) < 0)
    {
      perror("setsockopt L2CAP_OPTIONS");
    }
  }
  struct bt_power pwr = {.force_active = 0};
  if (setsockopt(fd, 274, 9, &pwr, sizeof(pwr)) < 0)
  {
    perror("setsockopt BT_POWER");
  }
}

variable_types: fd int

variable_types: struct l2cap_options { unsigned short omtu; unsigned short imtu; unsigned short flush_to; unsigned char mode; unsigned char fcs; unsigned char max_tx; unsigned short txwin_size; }

variable_types:
len
unsigned int

variable_types: opt int

variable_types: struct bt_power { unsigned char force_active; }


original_code:
int acl_send_data (const char *bdaddr_dst, unsigned short cid, const unsigned char *data, unsigned short plen)
{
  int ret = -1, dd, device;
  struct hci_conn_info_req *cr = 0;
  bdaddr_t ba;
  uint8_t type = 0x02;
  hci_acl_hdr acl_hdr;
  l2cap_hdr l2_hdr;
  struct iovec iv[4];
  int ivn;
  unsigned short data_len;
  char* pdata = (char*)data;
  str2ba(bdaddr_dst, &ba);
  cr = (struct hci_conn_info_req*) malloc(
      sizeof(struct hci_conn_info_req) + sizeof(struct hci_conn_info));
  bacpy(&cr->bdaddr, &ba);
  cr->type = 0x01;
  if ((device = hci_get_route(&ba)) < 0)
  {
    perror("hci_get_route");
    goto cleanup;
  }
  if ((dd = hci_open_dev(device)) < 0)
  {
    perror("hci_open_dev");
    goto cleanup;
  }
  if (ioctl(dd, (((2U) << (((0 +8)+8)+14)) | ((('H')) << (0 +8)) | (((213)) << 0) | ((((sizeof(int)))) << ((0 +8)+8))), (unsigned long) cr) < 0)
  {
    perror("ioctl HCIGETCONNINFO");
    goto cleanup;
  }
  data_len = 1024 -1-4 -4;
  if(plen < data_len)
  {
    data_len = plen;
  }
  iv[0].iov_base = &type;
  iv[0].iov_len = 1;
  acl_hdr.handle = ((uint16_t)((cr->conn_info->handle & 0x0fff)|(0x02 << 12)));
  acl_hdr.dlen = (data_len+4);
  iv[1].iov_base = &acl_hdr;
  iv[1].iov_len = 4;
  l2_hdr.cid = (cid);
  l2_hdr.len = (plen);
  iv[2].iov_base = &l2_hdr;
  iv[2].iov_len = 4;
  ivn = 3;
  if (data_len)
  {
    iv[3].iov_base = pdata;
    iv[3].iov_len = (data_len);
    ivn = 4;
  }
  while ((ret = writev(dd, iv, ivn)) < 0)
  {
    if ((*__errno_location ()) == 11 || (*__errno_location ()) == 4)
    {
      continue;
    }
    perror("writev: ");
    break;
  }
  plen -= data_len;
  while(plen)
  {
    pdata += data_len;
    data_len = 1024 -1-4;
    if(plen < data_len)
    {
      data_len = plen;
    }
    iv[0].iov_base = &type;
    iv[0].iov_len = 1;
    acl_hdr.handle = ((uint16_t)((cr->conn_info->handle & 0x0fff)|(0x01 << 12)));
    acl_hdr.dlen = (plen);
    iv[1].iov_base = &acl_hdr;
    iv[1].iov_len = 4;
    iv[2].iov_base = pdata;
    iv[2].iov_len = (data_len);
    ivn = 3;
    while ((ret = writev(dd, iv, ivn)) < 0)
    {
      if ((*__errno_location ()) == 11 || (*__errno_location ()) == 4)
      {
        continue;
      }
      perror("writev: ");
      break;
    }
    plen -= data_len;
  }
  cleanup: free(cr);
  if (dd >= 0)
    close(dd);
  return ret;
}

canonical_original_code:
int acl_send_data(char *bdaddr_dst, unsigned short cid, unsigned char *data, unsigned short plen)
{
  int ret = -1; int dd; int device;
  struct hci_conn_info_req *cr = 0;
  struct bdaddr_t ba;
  unsigned char type = 0x02;
  struct hci_acl_hdr acl_hdr;
  struct l2cap_hdr l2_hdr;
  struct iovec iv[4];
  int ivn;
  unsigned short data_len;
  char *pdata = (char*)data;
  str2ba(bdaddr_dst, &ba);
  cr = (struct hci_conn_info_req *) malloc(
      sizeof(struct hci_conn_info_req) + sizeof(struct hci_conn_info));
  bacpy(&cr->bdaddr, &ba);
  cr->type = 0x01;
  if ((device = hci_get_route(&ba)) < 0)
  {
    perror("hci_get_route");
    goto cleanup;
  }
  if ((dd = hci_open_dev(device)) < 0)
  {
    perror("hci_open_dev");
    goto cleanup;
  }
  if (ioctl(dd, (((2U) << (((0 +8)+8)+14)) | ((('H')) << (0 +8)) | (((213)) << 0) | ((((sizeof(int)))) << ((0 +8)+8))), (unsigned long) cr) < 0)
  {
    perror("ioctl HCIGETCONNINFO");
    goto cleanup;
  }
  data_len = 1024 -1-4 -4;
  if(plen < data_len)
  {
    data_len = plen;
  }
  iv[0].iov_base = &type;
  iv[0].iov_len = 1;
  acl_hdr.handle = ((unsigned short)((cr->conn_info->handle & 0x0fff)|(0x02 << 12)));
  acl_hdr.dlen = (data_len+4);
  iv[1].iov_base = &acl_hdr;
  iv[1].iov_len = 4;
  l2_hdr.cid = (cid);
  l2_hdr.len = (plen);
  iv[2].iov_base = &l2_hdr;
  iv[2].iov_len = 4;
  ivn = 3;
  if (data_len)
  {
    iv[3].iov_base = pdata;
    iv[3].iov_len = (data_len);
    ivn = 4;
  }
  while ((ret = writev(dd, iv, ivn)) < 0)
  {
    if ((*__errno_location ()) == 11 || (*__errno_location ()) == 4)
    {
      continue;
    }
    perror("writev: ");
    break;
  }
  plen -= data_len;
  while(plen)
  {
    pdata += data_len;
    data_len = 1024 -1-4;
    if(plen < data_len)
    {
      data_len = plen;
    }
    iv[0].iov_base = &type;
    iv[0].iov_len = 1;
    acl_hdr.handle = ((unsigned short)((cr->conn_info->handle & 0x0fff)|(0x01 << 12)));
    acl_hdr.dlen = (plen);
    iv[1].iov_base = &acl_hdr;
    iv[1].iov_len = 4;
    iv[2].iov_base = pdata;
    iv[2].iov_len = (data_len);
    ivn = 3;
    while ((ret = writev(dd, iv, ivn)) < 0)
    {
      if ((*__errno_location ()) == 11 || (*__errno_location ()) == 4)
      {
        continue;
      }
      perror("writev: ");
      break;
    }
    plen -= data_len;
  }
  cleanup: free(cr);
  if (dd >= 0)
    close(dd);
  return ret;
}

variable_types:
cid
unsigned short

variable_types:
data
unsigned char *

variable_types:
plen
unsigned short

variable_types: dd int

variable_types: device int

variable_types: struct hci_conn_info_req { struct bdaddr_t { unsigned char b[6]; } bdaddr; unsigned char type; struct hci_conn_info { unsigned short handle; struct bdaddr_t bdaddr; unsigned char type; unsigned char out; unsigned short state; unsigned int link_mode; } conn_info[]; } *

variable_types:
ba
struct bdaddr_t { unsigned char b[6]; }

variable_types:
type
unsigned char

variable_types: struct hci_acl_hdr { unsigned short handle; unsigned short dlen; }

variable_types: struct l2cap_hdr { unsigned short len; unsigned short cid; }

variable_types: struct iovec { void *iov_base; unsigned long iov_len; } [4]

variable_types: ivn int

variable_types:
pdata
char *

user_defined_types: struct hci_conn_info_req { struct bdaddr_t bdaddr; unsigned char type; struct hci_conn_info conn_info[]; }


decompiled_code:
__int64 __fastcall l2cap_connect(__int64 a1, __int64 a2, __int16 a3)
{
int v4; // eax
unsigned int v5; // er12
int v7; // edi
struct sockaddr addr; // [rsp+2h] [rbp-36h] BYREF

v4 = socket(31, 2053, 0);
v5 = v4;
if ( v4 == -1 )
{
perror("socket");
}
else
{
l2cap_setsockopt(v4);
*(_DWORD *)&addr.sa_data[6] = 0;
*(_WORD *)&addr.sa_data[10] = 0;
*(_QWORD *)&addr.sa_family = 31LL;
str2ba(a1, &addr.sa_data[2]);
bind(v5, &addr, 0xEu);
*(_QWORD *)&addr.sa_family = 31LL;
*(_DWORD *)&addr.sa_data[6] = 0;
*(_WORD *)&addr.sa_data[10] = 0;
*(_WORD *)addr.sa_data = a3;
str2ba(a2, &addr.sa_data[2]);
if ( connect(v5, &addr, 0xEu) == -1 && *_errno_location() != 115 )
{
perror("connect");
v7 = v5;
v5 = -4;
close(v7);
}
}
return v5;
}

canonical_decompiled_code:
__int64 __fastcall func3(__int64 a1, __int64 a2, __int16 a3)
{
int v4; // eax
unsigned int v5; // er12
int v7; // edi
struct sockaddr addr; // [rsp+2h] [rbp-36h] BYREF

v4 = socket(31, 2053, 0);
v5 = v4;
if ( v4 == -1 )
{
perror("socket");
}
else
{
func1(v4);
*(_DWORD *)&addr.sa_data[6] = 0;
*(_WORD *)&addr.sa_data[10] = 0;
*(_QWORD *)&addr.sa_family = 31LL;
str2ba(a1, &addr.sa_data[2]);
bind(v5, &addr, 0xEu);
*(_QWORD *)&addr.sa_family = 31LL;
*(_DWORD *)&addr.sa_data[6] = 0;
*(_WORD *)&addr.sa_data[10] = 0;
*(_WORD *)addr.sa_data = a3;
str2ba(a2, &addr.sa_data[2]);
if ( connect(v5, &addr, 0xEu) == -1 && *_errno_location() != 115 )
{
perror("connect");
v7 = v5;
v5 = -4;
close(v7);
}
}
return v5;
}

original_code:
int l2cap_connect(const char *bdaddr_src, const char *bdaddr_dest, int psm)
{
    int fd;
    struct sockaddr_l2 addr;
    if ((fd = socket(31, SOCK_SEQPACKET | SOCK_NONBLOCK, 0)) == -1)
    {
      perror("socket");
      return -1;
    }
    l2cap_setsockopt(fd);
    memset(&addr, 0, sizeof(addr));
    addr.l2_family = 31;
    str2ba(bdaddr_src, &addr.l2_bdaddr);
    bind(fd, (struct sockaddr *)&addr, sizeof(addr));
    memset(&addr, 0, sizeof(addr));
    addr.l2_family = 31;
    addr.l2_psm = (psm);
    str2ba(bdaddr_dest, &addr.l2_bdaddr);
    if (connect(fd, (struct sockaddr *)&addr, sizeof(addr)) == -1)
    {
      if((*__errno_location ()) != 115)
      {
        perror("connect");
        close(fd);
        return -4;
      }
    }
    return fd;
}

canonical_original_code:
int l2cap_connect(char *bdaddr_src, char *bdaddr_dest, int psm)
{
    int fd;
    struct sockaddr_l2 addr;
    if ((fd = socket(31, SOCK_SEQPACKET | SOCK_NONBLOCK, 0)) == -1)
    {
      perror("socket");
      return -1;
    }
    l2cap_setsockopt(fd);
    memset(&addr, 0, sizeof(addr));
    addr.l2_family = 31;
    str2ba(bdaddr_src, &addr.l2_bdaddr);
    bind(fd, (struct sockaddr *)&addr, sizeof(addr));
    memset(&addr, 0, sizeof(addr));
    addr.l2_family = 31;
    addr.l2_psm = (psm);
    str2ba(bdaddr_dest, &addr.l2_bdaddr);
    if (connect(fd, (struct sockaddr *)&addr, sizeof(addr)) == -1)
    {
      if((*__errno_location ()) != 115)
      {
        perror("connect");
        close(fd);
        return -4;
      }
    }
    return fd;
}

variable_types: psm int

variable_types: fd int

variable_types: struct sockaddr_l2 { unsigned short l2_family; unsigned short l2_psm; struct bdaddr_t { unsigned char b[6]; } l2_bdaddr; unsigned short l2_cid; unsigned char l2_bdaddr_type; }

user_defined_types: struct sockaddr_l2 { unsigned short l2_family; unsigned short l2_psm; struct bdaddr_t l2_bdaddr; unsigned short l2_cid; unsigned char l2_bdaddr_type; }

user_defined_types: struct sockaddr { unsigned short sa_family; char sa_data[14]; }