decompiled_code:
__int64 __fastcall Bitcoin_FixBase58Check(void *a1, __int64 a2, size_t *a3, char *a4, size_t a5, _QWORD *a6, void *src, size_t n, int a9, int a10, int a11)
{
size_t v12; // rbx
void *v13; // r15
unsigned int v14; // er14
unsigned int v15; // er13
const char *v16; // r8
__int64 result; // rax
int *v18; // rax
__int64 v19; // rcx
__int64 v20; // rdx
__int64 v21; // rsi
_BOOL4 v22; // ecx
__int64 v23; // rax
__int64 v24; // rdi
__int64 v25; // rax
__int64 v26; // rdx
__int64 v27; // rdx
_BYTE *v28; // rbx
double v29; // xmm0_8
double v30; // xmm0_8
__int64 v34; // [rsp+18h] [rbp-70h]
size_t v36; // [rsp+28h] [rbp-60h]
size_t v37; // [rsp+28h] [rbp-60h]
char v38[8]; // [rsp+40h] [rbp-48h] BYREF
int *v39; // [rsp+48h] [rbp-40h]

v12 = a2 + (unsigned int)a11;
if ( a9 == 1 )
{
applog(
2LL,
"Bitcoin_FixBase58Check",
"Attempting to fix Base58Check input by changing %s%d character%s ...",
(const char *)&unk_9D6,
1LL,
(const char *)&unk_9D6);
if ( v12 >= n )
{
v13 = malloc(v12 + 1);
*a3 = n;
goto LABEL_4;
}
LABEL_5:
applog(
4LL,
"Bitcoin_FixBase58Check",
"output buffer is not large enough (%u) to store changed input text (%u)",
(unsigned int)n,
(unsigned int)v12);
return 5LL;
}
applog(
2LL,
"Bitcoin_FixBase58Check",
"Attempting to fix Base58Check input by changing %s%d character%s ...",
"up to ",
(unsigned int)a9,
"s");
if ( v12 < n )
goto LABEL_5;
v13 = malloc(v12 + 1);
*a3 = n;
if ( !a9 )
{
free(v13);
v34 = 0LL;
goto LABEL_36;
}
LABEL_4:
v14 = 0;
v15 = 1;
v34 = 0LL;
v16 = (const char *)&unk_9D6;
LABEL_32:
applog(2LL, "Bitcoin_FixBase58Check", "Changing %d character%s ...", v15, v16);
Combination_create(v38, (unsigned int)n, v15);
v28 = malloc(v15);
while ( 2 )
{
memcpy(a1, src, n);
memset(v28, 0, v15);
while ( 1 )
{
LABEL_17:
if ( v15 )
{
v24 = (__int64)v39;
v25 = 0LL;
do
{
*((_BYTE *)a1 + *(int *)(v24 + 4 * v25)) = base58_digits[(char)v28[v25]];
v26 = v25++;
}
while ( v26 != v14 );
v34 += v14 + 1LL;
}
if ( !(unsigned int)Bitcoin_DecodeBase58Check(a4, a5, a6, (char *)a1, n) )
break;
++*v28;
v21 = 0LL;
if ( v15 )
goto LABEL_23;
}
memcpy(v13, src, n);
*((_BYTE *)v13 + n) = 0;
applog(3LL, "Bitcoin_FixBase58Check", "from: %s", (const char *)v13);
v36 = *a3;
memcpy(v13, a1, *a3);
*((_BYTE *)v13 + v36) = 0;
applog(3LL, "Bitcoin_FixBase58Check", " to: %s", (const char *)v13);
v37 = *a3;
memset(v13, 32, *a3);
*((_BYTE *)v13 + v37) = 0;
if ( v15 )
{
v18 = v39;
v19 = (__int64)&v39[v15];
do
*((_BYTE *)v13 + *v18++) = 94;
while ( (int *)v19 != v18 );
}
applog(3LL, "Bitcoin_FixBase58Check", " %s", (const char *)v13);
++*v28;
if ( !v15 )
{
v21 = 1LL;
goto LABEL_25;
}
v21 = 1LL;
LABEL_23:
v20 = v14;
v23 = 0LL;
v22 = 0;
while ( v28[v23] == 58 )
{
v28[v23] = 0;
v22 = v14 == v23;
if ( v14 == v23 )
goto LABEL_16;
++v28[v23 + 1];
LABEL_13:
++v23;
}
if ( v14 != v23 )
goto LABEL_13;
LABEL_16:
if ( !((unsigned int)v21 | v22) )
goto LABEL_17;
LABEL_25:
if ( (_DWORD)v21 )
{
Combination_destroy(v38, v21, v20);
free(v28);
free(v13);
if ( v34 < 0 )
v30 = (double)(int)(v34 & 1 | ((unsigned __int64)v34 >> 1))
+ (double)(int)(v34 & 1 | ((unsigned __int64)v34 >> 1));
else
v30 = (double)(int)v34;
applog(
3LL,
"Bitcoin_FixBase58Check",
"Base58Check input has been corrected after %llu combinations (%f%% chance of error).",
v34,
v30 * 2.328306436538696e-10 * 100.0);
result = 0LL;
}
else
{
if ( (unsigned int)Combination_next(v38, v21, v20) )
continue;
Combination_destroy(v38, v21, v27);
free(v28);
if ( a9 >= ++v15 )
{
v16 = "s";
if ( v15 == 1 )
v16 = (const char *)&unk_9D6;
++v14;
goto LABEL_32;
}
free(v13);
LABEL_36:
if ( v34 < 0 )
v29 = (double)(int)(v34 & 1 | ((unsigned __int64)v34 >> 1))
+ (double)(int)(v34 & 1 | ((unsigned __int64)v34 >> 1));
else
v29 = (double)(int)v34;
applog(
3LL,
"Bitcoin_FixBase58Check",
"Failed to find any combination of changing the Base58Check input that results in a valid checksum. %llu combinat"
"ions were tried. (%f%% chance of error).",
v34,
v29 * 2.328306436538696e-10 * 100.0);
result = 6LL;
}
return result;
}
}

canonical_decompiled_code:
__int64 __fastcall func4(void *a1, __int64 a2, size_t *a3, char *a4, size_t a5, _QWORD *a6, void *src, size_t n, int a9, int a10, int a11)
{
size_t v12; // rbx
void *v13; // r15
unsigned int v14; // er14
unsigned int v15; // er13
const char *v16; // r8
__int64 result; // rax
int *v18; // rax
__int64 v19; // rcx
__int64 v20; // rdx
__int64 v21; // rsi
_BOOL4 v22; // ecx
__int64 v23; // rax
__int64 v24; // rdi
__int64 v25; // rax
__int64 v26; // rdx
__int64 v27; // rdx
_BYTE *v28; // rbx
double v29; // xmm0_8
double v30; // xmm0_8
__int64 v34; // [rsp+18h] [rbp-70h]
size_t v36; // [rsp+28h] [rbp-60h]
size_t v37; // [rsp+28h] [rbp-60h]
char v38[8]; // [rsp+40h] [rbp-48h] BYREF
int *v39; // [rsp+48h] [rbp-40h]

v12 = a2 + (unsigned int)a11;
if ( a9 == 1 )
{
applog(
2LL,
"Bitcoin_FixBase58Check",
"Attempting to fix Base58Check input by changing %s%d character%s ...",
(const char *)&unk_9D6,
1LL,
(const char *)&unk_9D6);
if ( v12 >= n )
{
v13 = malloc(v12 + 1);
*a3 = n;
goto LABEL_4;
}
LABEL_5:
applog(
4LL,
"Bitcoin_FixBase58Check",
"output buffer is not large enough (%u) to store changed input text (%u)",
(unsigned int)n,
(unsigned int)v12);
return 5LL;
}
applog(
2LL,
"Bitcoin_FixBase58Check",
"Attempting to fix Base58Check input by changing %s%d character%s ...",
"up to ",
(unsigned int)a9,
"s");
if ( v12 < n )
goto LABEL_5;
v13 = malloc(v12 + 1);
*a3 = n;
if ( !a9 )
{
free(v13);
v34 = 0LL;
goto LABEL_36;
}
LABEL_4:
v14 = 0;
v15 = 1;
v34 = 0LL;
v16 = (const char *)&unk_9D6;
LABEL_32:
applog(2LL, "Bitcoin_FixBase58Check", "Changing %d character%s ...", v15, v16);
Combination_create(v38, (unsigned int)n, v15);
v28 = malloc(v15);
while ( 2 )
{
memcpy(a1, src, n);
memset(v28, 0, v15);
while ( 1 )
{
LABEL_17:
if ( v15 )
{
v24 = (__int64)v39;
v25 = 0LL;
do
{
*((_BYTE *)a1 + *(int *)(v24 + 4 * v25)) = base58_digits[(char)v28[v25]];
v26 = v25++;
}
while ( v26 != v14 );
v34 += v14 + 1LL;
}
if ( !(unsigned int)func3(a4, a5, a6, (char *)a1, n) )
break;
++*v28;
v21 = 0LL;
if ( v15 )
goto LABEL_23;
}
memcpy(v13, src, n);
*((_BYTE *)v13 + n) = 0;
applog(3LL, "Bitcoin_FixBase58Check", "from: %s", (const char *)v13);
v36 = *a3;
memcpy(v13, a1, *a3);
*((_BYTE *)v13 + v36) = 0;
applog(3LL, "Bitcoin_FixBase58Check", " to: %s", (const char *)v13);
v37 = *a3;
memset(v13, 32, *a3);
*((_BYTE *)v13 + v37) = 0;
if ( v15 )
{
v18 = v39;
v19 = (__int64)&v39[v15];
do
*((_BYTE *)v13 + *v18++) = 94;
while ( (int *)v19 != v18 );
}
applog(3LL, "Bitcoin_FixBase58Check", " %s", (const char *)v13);
++*v28;
if ( !v15 )
{
v21 = 1LL;
goto LABEL_25;
}
v21 = 1LL;
LABEL_23:
v20 = v14;
v23 = 0LL;
v22 = 0;
while ( v28[v23] == 58 )
{
v28[v23] = 0;
v22 = v14 == v23;
if ( v14 == v23 )
goto LABEL_16;
++v28[v23 + 1];
LABEL_13:
++v23;
}
if ( v14 != v23 )
goto LABEL_13;
LABEL_16:
if ( !((unsigned int)v21 | v22) )
goto LABEL_17;
LABEL_25:
if ( (_DWORD)v21 )
{
Combination_destroy(v38, v21, v20);
free(v28);
free(v13);
if ( v34 < 0 )
v30 = (double)(int)(v34 & 1 | ((unsigned __int64)v34 >> 1))
+ (double)(int)(v34 & 1 | ((unsigned __int64)v34 >> 1));
else
v30 = (double)(int)v34;
applog(
3LL,
"Bitcoin_FixBase58Check",
"Base58Check input has been corrected after %llu combinations (%f%% chance of error).",
v34,
v30 * 2.328306436538696e-10 * 100.0);
result = 0LL;
}
else
{
if ( (unsigned int)Combination_next(v38, v21, v20) )
continue;
Combination_destroy(v38, v21, v27);
free(v28);
if ( a9 >= ++v15 )
{
v16 = "s";
if ( v15 == 1 )
v16 = (const char *)&unk_9D6;
++v14;
goto LABEL_32;
}
free(v13);
LABEL_36:
if ( v34 < 0 )
v29 = (double)(int)(v34 & 1 | ((unsigned __int64)v34 >> 1))
+ (double)(int)(v34 & 1 | ((unsigned __int64)v34 >> 1));
else
v29 = (double)(int)v34;
applog(
3LL,
"Bitcoin_FixBase58Check",
"Failed to find any combination of changing the Base58Check input that results in a valid checksum. %llu combinat"
"ions were tried. (%f%% chance of error).",
v34,
v29 * 2.328306436538696e-10 * 100.0);
result = 6LL;
}
return result;
}
}

original_code:
BitcoinResult Bitcoin_FixBase58Check(
 char *fixed_output, size_t fixed_output_buffer_size, size_t *fixed_output_size,
 uint8_t *output, size_t output_buffer_size, size_t *decoded_output_size,
 const char *input, size_t input_size,
 unsigned change_chars,
 unsigned remove_chars,
 unsigned insert_chars
)
{
 uint64_t change_count = 0;
 size_t required_fixed_output_size = fixed_output_buffer_size + insert_chars;
 BitcoinResult result;
 static const unsigned radix = 58;
 unsigned i, j, overflow;
 char *format_output = ((void *)0);
 struct Combination c;
 unsigned n, r, done = 0;
 char *digits;
 applog(APPLOG_NOTICE, __func__,
  "Attempting to fix Base58Check input by changing %s%d character%s ...",
  change_chars == 1 ? "" : "up to ",
  (int)change_chars,
  change_chars == 1 ? "" : "s"
 );
 if (required_fixed_output_size < input_size) {
  applog(APPLOG_ERROR, __func__,
   "output buffer is not large enough (%u) to store changed"
   " input text (%u)",
   (unsigned)input_size,
   (unsigned)required_fixed_output_size
  );
  return BITCOIN_ERROR_OUTPUT_BUFFER_TOO_SMALL;
 }
 format_output = malloc(required_fixed_output_size + 1);
 *fixed_output_size = input_size;
 for (r = 1; r <= change_chars && !done; r++) {
  applog(APPLOG_NOTICE, __func__,
   "Changing %d character%s ...",
   r,
   r == 1 ? "" : "s"
  );
  n = input_size;
  Combination_create(&c, n, r);
  digits = malloc(r);
  do {
   memcpy(fixed_output, input, input_size);
   memset(digits, 0, r);
   overflow = 0;
   while (!overflow && !done) {
    int carry = 0;
    for (i=0; i < r; i++) {
     fixed_output[c.k[i]] = base58_digits[(int)digits[i]];
     change_count++;
    }
    result = Bitcoin_DecodeBase58Check(output, output_buffer_size,
     decoded_output_size, fixed_output, input_size
    );
    if (result == BITCOIN_SUCCESS) {
     memcpy(format_output, input, input_size);
     format_output[input_size] = '\0';
     applog(APPLOG_WARNING, __func__,
      "from: %s", format_output
     );
     memcpy(format_output, fixed_output, *fixed_output_size);
     format_output[*fixed_output_size] = '\0';
     applog(APPLOG_WARNING, __func__,
      "  to: %s", format_output
     );
     memset(format_output, ' ', *fixed_output_size);
     format_output[*fixed_output_size] = '\0';
     for (j=0; j < r; j++) {
      format_output[c.k[j]] = '^';
     }
     applog(APPLOG_WARNING, __func__,
      "      %s", format_output
     );
     done = 1;
    }
    digits[0]++;
    for (i=0; i < r; i++) {
     if (carry) {
      digits[i] += carry;
      carry = 0;
     }
     if (digits[i] == radix) {
      digits[i] = 0;
      carry = 1;
      overflow = i == r-1;
     } else {
      carry = 0;
     }
    }
   }
  } while (!done && Combination_next(&c));
  Combination_destroy(&c);
  free(digits);
 }
 free(format_output);
 if (!done) {
  applog(APPLOG_WARNING, __func__,
   "Failed to find any combination of changing the Base58Check input"
   " that results in a valid checksum. %llu combinations were tried."
   " (%f%% chance of error).",
   (long long unsigned)change_count,
   ((double)change_count / ((unsigned long long)1 << 32)) * 100
  );
  return BITCOIN_ERROR_CHECKSUM_FAILURE;
 }
 applog(APPLOG_WARNING, __func__,
  "Base58Check input has been corrected after %llu combinations "
  " (%f%% chance of error).",
  (long long unsigned)change_count,
  ((double)change_count / ((unsigned long long)1 << 32)) * 100
 );
 return BITCOIN_SUCCESS;
}

canonical_original_code:
enum BitcoinResult Bitcoin_FixBase58Check(char *fixed_output, unsigned long fixed_output_buffer_size, unsigned long *fixed_output_size, unsigned char *output, unsigned long output_buffer_size, unsigned long *decoded_output_size, char *input, unsigned long input_size, unsigned int change_chars, unsigned int remove_chars, unsigned int insert_chars)
{
 unsigned long change_count = 0;
 unsigned long required_fixed_output_size = fixed_output_buffer_size + insert_chars;
 enum BitcoinResult result;
 static unsigned int radix = 58;
 unsigned int i; unsigned int j; unsigned int overflow;
 char *format_output = ((void *)0);
 struct Combination c;
 unsigned int n; unsigned int r; unsigned int done = 0;
 char *digits;
 applog(APPLOG_NOTICE, __func__,
  "Attempting to fix Base58Check input by changing %s%d character%s ...",
  change_chars == 1 ? "" : "up to ",
  (int)change_chars,
  change_chars == 1 ? "" : "s"
 );
 if (required_fixed_output_size < input_size) {
  applog(APPLOG_ERROR, __func__,
   "output buffer is not large enough (%u) to store changed"
   " input text (%u)",
   (unsigned int)input_size,
   (unsigned int)required_fixed_output_size
  );
  return BITCOIN_ERROR_OUTPUT_BUFFER_TOO_SMALL;
 }
 format_output = malloc(required_fixed_output_size + 1);
 *fixed_output_size = input_size;
 for (r = 1; r <= change_chars && !done; r++) {
  applog(APPLOG_NOTICE, __func__,
   "Changing %d character%s ...",
   r,
   r == 1 ? "" : "s"
  );
  n = input_size;
  Combination_create(&c, n, r);
  digits = malloc(r);
  do {
   memcpy(fixed_output, input, input_size);
   memset(digits, 0, r);
   overflow = 0;
   while (!overflow && !done) {
    int carry = 0;
    for (i=0; i < r; i++) {
     fixed_output[c.k[i]] = base58_digits[(int)digits[i]];
     change_count++;
    }
    result = Bitcoin_DecodeBase58Check(output, output_buffer_size,
     decoded_output_size, fixed_output, input_size
    );
    if (result == BITCOIN_SUCCESS) {
     memcpy(format_output, input, input_size);
     format_output[input_size] = '\0';
     applog(APPLOG_WARNING, __func__,
      "from: %s", format_output
     );
     memcpy(format_output, fixed_output, *fixed_output_size);
     format_output[*fixed_output_size] = '\0';
     applog(APPLOG_WARNING, __func__,
      "  to: %s", format_output
     );
     memset(format_output, ' ', *fixed_output_size);
     format_output[*fixed_output_size] = '\0';
     for (j=0; j < r; j++) {
      format_output[c.k[j]] = '^';
     }
     applog(APPLOG_WARNING, __func__,
      "      %s", format_output
     );
     done = 1;
    }
    digits[0]++;
    for (i=0; i < r; i++) {
     if (carry) {
      digits[i] += carry;
      carry = 0;
     }
     if (digits[i] == radix) {
      digits[i] = 0;
      carry = 1;
      overflow = i == r-1;
     } else {
      carry = 0;
     }
    }
   }
  } while (!done && Combination_next(&c));
  Combination_destroy(&c);
  free(digits);
 }
 free(format_output);
 if (!done) {
  applog(APPLOG_WARNING, __func__,
   "Failed to find any combination of changing the Base58Check input"
   " that results in a valid checksum. %llu combinations were tried."
   " (%f%% chance of error).",
   (unsigned long long)change_count,
   ((double)change_count / ((unsigned long long)1 << 32)) * 100
  );
  return BITCOIN_ERROR_CHECKSUM_FAILURE;
 }
 applog(APPLOG_WARNING, __func__,
  "Base58Check input has been corrected after %llu combinations "
  " (%f%% chance of error).",
  (unsigned long long)change_count,
  ((double)change_count / ((unsigned long long)1 << 32)) * 100
 );
 return BITCOIN_SUCCESS;
}

variable_types:
input
char *

variable_types:
radix
unsigned int

variable_types:
i
unsigned int

variable_types:
j
unsigned int

variable_types:
overflow
unsigned int

variable_types: struct Combination { int n; int r; int *k; }

variable_types:
n
unsigned int

variable_types:
r
unsigned int

variable_types:
done
unsigned int

variable_types:
digits
char *

variable_types: carry int


repo: matlo/GIMX

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;
if ( (a4 & a5) != v6 )
{
*a2 = (v6 == 0) + 8;
a2[2] = a6;
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;
if ( (a4 & a5) != v6 )
{
*a2 = (v6 == 0) + 8;
a2[2] = a6;
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: 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; } *)

variable_types:
event
union GE_Event *

variable_types:
buttons
unsigned short

variable_types:
pbuttons
unsigned short

variable_types:
value
unsigned short

return_type: void

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; }


original_code:
void xOnePad2event(int adapter_id __attribute__((unused)), s_report* current, s_report* previous,
    int joystick_id, int (*callback)(GE_Event*))
{
  GE_Event event = { .jbutton = { .which = joystick_id } };
  if(current->xone.input.type == 0x20)
  {
    s_report_xone* xone_current = &current->xone;
    s_report_xone* xone_previous = &previous->xone;
    unsigned short buttons = xone_current->input.buttons;
    unsigned short prevButtons = xone_previous->input.buttons;
    button2event(callback, &event, buttons, prevButtons, 0x0100, 11);
    button2event(callback, &event, buttons, prevButtons, 0x0200, 13);
    button2event(callback, &event, buttons, prevButtons, 0x0400, 14);
    button2event(callback, &event, buttons, prevButtons, 0x0800, 12);
    button2event(callback, &event, buttons, prevButtons, 0x0004, 7);
    button2event(callback, &event, buttons, prevButtons, 0x0008, 6);
    button2event(callback, &event, buttons, prevButtons, 0x4000, 9);
    button2event(callback, &event, buttons, prevButtons, 0x8000, 10);
    button2event(callback, &event, buttons, prevButtons, 0x1000, 4);
    button2event(callback, &event, buttons, prevButtons, 0x2000, 5);
    button2event(callback, &event, buttons, prevButtons, 0x0010, 0);
    button2event(callback, &event, buttons, prevButtons, 0x0020, 1);
    button2event(callback, &event, buttons, prevButtons, 0x0040, 2);
    button2event(callback, &event, buttons, prevButtons, 0x0080, 3);
    event.type = GE_JOYAXISMOTION;
    axis2event(callback, &event, xone_current->input.xaxis, xone_previous->input.xaxis, 0, 0);
    axis2event(callback, &event, xone_current->input.yaxis, xone_previous->input.yaxis, 1, 1);
    axis2event(callback, &event, xone_current->input.zaxis, xone_previous->input.zaxis, 0, 3);
    axis2event(callback, &event, xone_current->input.taxis, xone_previous->input.taxis, 1, 4);
    trigger2event(callback, &event, xone_current->input.ltrigger, xone_previous->input.ltrigger, 2);
    trigger2event(callback, &event, xone_current->input.rtrigger, xone_previous->input.rtrigger, 5);
  }
  else if(current->xone.input.type == 0x07)
  {
    s_report_xone* xone_current = &current->xone;
    s_report_xone* xone_previous = &previous->xone;
    unsigned short buttons = xone_current->guide.button;
    unsigned short prevButtons = xone_previous->guide.button;
    button2event(callback, &event, buttons, prevButtons, 0x01, 8);
  }
}

canonical_original_code:
void xOnePad2event(int adapter_id, union s_report *current, union s_report *previous, int joystick_id, int (*callback)(union GE_Event *))
{
  union GE_Event event = { .jbutton = { .which = joystick_id } };
  if(current->xone.input.type == 0x20)
  {
    struct s_report_xone *xone_current = &current->xone;
    struct s_report_xone *xone_previous = &previous->xone;
    unsigned short buttons = xone_current->input.buttons;
    unsigned short prevButtons = xone_previous->input.buttons;
    button2event(callback, &event, buttons, prevButtons, 0x0100, 11);
    button2event(callback, &event, buttons, prevButtons, 0x0200, 13);
    button2event(callback, &event, buttons, prevButtons, 0x0400, 14);
    button2event(callback, &event, buttons, prevButtons, 0x0800, 12);
    button2event(callback, &event, buttons, prevButtons, 0x0004, 7);
    button2event(callback, &event, buttons, prevButtons, 0x0008, 6);
    button2event(callback, &event, buttons, prevButtons, 0x4000, 9);
    button2event(callback, &event, buttons, prevButtons, 0x8000, 10);
    button2event(callback, &event, buttons, prevButtons, 0x1000, 4);
    button2event(callback, &event, buttons, prevButtons, 0x2000, 5);
    button2event(callback, &event, buttons, prevButtons, 0x0010, 0);
    button2event(callback, &event, buttons, prevButtons, 0x0020, 1);
    button2event(callback, &event, buttons, prevButtons, 0x0040, 2);
    button2event(callback, &event, buttons, prevButtons, 0x0080, 3);
    event.type = GE_JOYAXISMOTION;
    axis2event(callback, &event, xone_current->input.xaxis, xone_previous->input.xaxis, 0, 0);
    axis2event(callback, &event, xone_current->input.yaxis, xone_previous->input.yaxis, 1, 1);
    axis2event(callback, &event, xone_current->input.zaxis, xone_previous->input.zaxis, 0, 3);
    axis2event(callback, &event, xone_current->input.taxis, xone_previous->input.taxis, 1, 4);
    trigger2event(callback, &event, xone_current->input.ltrigger, xone_previous->input.ltrigger, 2);
    trigger2event(callback, &event, xone_current->input.rtrigger, xone_previous->input.rtrigger, 5);
  }
  else if(current->xone.input.type == 0x07)
  {
    struct s_report_xone *xone_current = &current->xone;
    struct s_report_xone *xone_previous = &previous->xone;
    unsigned short buttons = xone_current->guide.button;
    unsigned short prevButtons = xone_previous->guide.button;
    button2event(callback, &event, buttons, prevButtons, 0x01, 8);
  }
}

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 *

variable_types: 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; }

variable_types: 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; }; } *

variable_types:
prevButtons
unsigned short

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; }


original_code:
void bt_flip_addr(bd_addr_t dest, bd_addr_t src){
    dest[0] = src[5];
    dest[1] = src[4];
    dest[2] = src[3];
    dest[3] = src[2];
    dest[4] = src[1];
    dest[5] = src[0];
}

canonical_original_code:
void bt_flip_addr(unsigned char dest[6], unsigned char src[6]){
    dest[0] = src[5];
    dest[1] = src[4];
    dest[2] = src[3];
    dest[3] = src[2];
    dest[4] = src[1];
    dest[5] = src[0];
}

variable_types:
dest
unsigned char [6]

variable_types:
src
unsigned char [6]


hexdump

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

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

canonical_decompiled_code:
int __fastcall func5(unsigned __int8 *a1, int a2)
{
unsigned __int8 *v2; // rbx

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

original_code:
void hexdump(void *data, int size){
    int i;
    for (i=0; i<size;i++){
        printf("%02X ", ((uint8_t *)data)[i]);
    }
    printf("\n");
}

canonical_original_code:
void hexdump(void *data, int size){
    int i;
    for (i=0; i<size;i++){
        printf("%02X ", ((unsigned char *)data)[i]);
    }
    printf("\n");
}

variable_types:
data
void *

variable_types: size int

variable_types: i int


decompiled_code:
char *__fastcall bd_addr_to_str(unsigned __int8 *a1)
{
sprintf(bd_addr_to_str_buffer, "%02x:%02x:%02x:%02x:%02x:%02x", *a1, a1[1], a1[2], a1[3], a1[4], a1[5]);
return bd_addr_to_str_buffer;
}

canonical_decompiled_code:
char *__fastcall func7(unsigned __int8 *a1)
{
sprintf(bd_addr_to_str_buffer, "%02x:%02x:%02x:%02x:%02x:%02x", *a1, a1[1], a1[2], a1[3], a1[4], a1[5]);
return bd_addr_to_str_buffer;
}

original_code:
char * bd_addr_to_str(bd_addr_t addr){
    sprintf(bd_addr_to_str_buffer, "%02x:%02x:%02x:%02x:%02x:%02x", addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
    return (char *) bd_addr_to_str_buffer;
}

canonical_original_code:
char *bd_addr_to_str(unsigned char addr[6]){
    sprintf(bd_addr_to_str_buffer, "%02x:%02x:%02x:%02x:%02x:%02x", addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
    return (char *) bd_addr_to_str_buffer;
}

variable_types:
addr
unsigned char [6]

return_type: char *


decompiled_code:
int __fastcall print_bd_addr(unsigned __int8 *a1)
{
char *v1; // rax

v1 = bd_addr_to_str(a1);
return printf("%s", v1);
}

canonical_decompiled_code:
int __fastcall func8(unsigned __int8 *a1)
{
char *v1; // rax

v1 = func7(a1);
return printf("%s", v1);
}

original_code:
void print_bd_addr( bd_addr_t addr){
    printf("%s", bd_addr_to_str(addr));
}

canonical_original_code:
void print_bd_addr(unsigned char addr[6]){
    printf("%s", bd_addr_to_str(addr));
}


original_code:
int sscan_bd_addr(uint8_t * addr_string, bd_addr_t addr){
 unsigned int bd_addr_buffer[6];
 int i;
    for (i = 0; i < 6; i++) {
        bd_addr_buffer[i] = 0;
    }
    int result = sscanf( (char *) addr_string, "%2x:%2x:%2x:%2x:%2x:%2x", &bd_addr_buffer[0], &bd_addr_buffer[1], &bd_addr_buffer[2],
      &bd_addr_buffer[3], &bd_addr_buffer[4], &bd_addr_buffer[5]);
 if (result == 6){
  for (i = 0; i < 6; i++) {
   addr[i] = (uint8_t) bd_addr_buffer[i];
  }
 }
 return (result == 6);
}

canonical_original_code:
int sscan_bd_addr(unsigned char *addr_string, unsigned char addr[6]){
 unsigned int bd_addr_buffer[6];
 int i;
    for (i = 0; i < 6; i++) {
        bd_addr_buffer[i] = 0;
    }
    int result = sscanf( (char *) addr_string, "%2x:%2x:%2x:%2x:%2x:%2x", &bd_addr_buffer[0], &bd_addr_buffer[1], &bd_addr_buffer[2],
      &bd_addr_buffer[3], &bd_addr_buffer[4], &bd_addr_buffer[5]);
 if (result == 6){
  for (i = 0; i < 6; i++) {
   addr[i] = (unsigned char) bd_addr_buffer[i];
  }
 }
 return (result == 6);
}

variable_types: result int

return_type: int


decompiled_code:
__int64 __fastcall crc8(_BYTE *a1, __int16 a2)
{
_BYTE *v2; // rdx
__int64 result; // rax

if ( !a2 )
return 0xFFFFFFFFLL;
v2 = a1;
LOBYTE(result) = -1;
do
result = (unsigned __int8)crc8table[(unsigned __int8)(*v2++ ^ result)];
while ( v2 != &a1[(unsigned __int16)(a2 - 1) + 1] );
return result;
}

canonical_decompiled_code:
__int64 __fastcall func10(_BYTE *a1, __int16 a2)
{
_BYTE *v2; // rdx
__int64 result; // rax

if ( !a2 )
return 0xFFFFFFFFLL;
v2 = a1;
LOBYTE(result) = -1;
do
result = (unsigned __int8)crc8table[(unsigned __int8)(*v2++ ^ result)];
while ( v2 != &a1[(unsigned __int16)(a2 - 1) + 1] );
return result;
}

original_code:
uint8_t crc8(uint8_t *data, uint16_t len)
{
    uint16_t count;
    uint8_t crc = 0xFF;
    for (count = 0; count < len; count++)
        crc = crc8table[crc ^ data[count]];
    return crc;
}

canonical_original_code:
unsigned char crc8(unsigned char *data, unsigned short len)
{
    unsigned short count;
    unsigned char crc = 0xFF;
    for (count = 0; count < len; count++)
        crc = crc8table[crc ^ data[count]];
    return crc;
}

variable_types:
data
unsigned char *

variable_types:
len
unsigned short

variable_types:
count
unsigned short

variable_types:
crc
unsigned char

return_type: unsigned char


decompiled_code:
bool __fastcall crc8_check(_BYTE *a1, __int16 a2, char a3)
{
return crc8table[(unsigned __int8)(a3 ^ crc8(a1, a2))] != -49;
}

canonical_decompiled_code:
bool __fastcall func11(_BYTE *a1, __int16 a2, char a3)
{
return crc8table[(unsigned __int8)(a3 ^ func10(a1, a2))] != -49;
}

original_code:
uint8_t crc8_check(uint8_t *data, uint16_t len, uint8_t check_sum)
{
    uint8_t crc;
    crc = crc8(data, len);
    crc = crc8table[crc ^ check_sum];
    if (crc == 0xCF)
        return 0;
    else
        return 1;
}

canonical_original_code:
unsigned char crc8_check(unsigned char *data, unsigned short len, unsigned char check_sum)
{
    unsigned char crc;
    crc = crc8(data, len);
    crc = crc8table[crc ^ check_sum];
    if (crc == 0xCF)
        return 0;
    else
        return 1;
}


decompiled_code:
__int64 __fastcall crc8_calc(_BYTE *a1, __int16 a2)
{
return (unsigned int)~crc8(a1, a2);
}

canonical_decompiled_code:
__int64 __fastcall func12(_BYTE *a1, __int16 a2)
{
return (unsigned int)~func10(a1, a2);
}

original_code:
uint8_t crc8_calc(uint8_t *data, uint16_t len)
{
    return 0xFF - crc8(data, len);
}

canonical_original_code:
unsigned char crc8_calc(unsigned char *data, unsigned short len)
{
    return 0xFF - crc8(data, len);
}


decompiled_code:
__int64 __fastcall mgmt_set_local_name(int fd, __int16 a2)
{
__int16 buf[140]; // [rsp+20h] [rbp-118h] BYREF

memset(buf, 0, 0x108uLL);
buf[132] = 0;
buf[0] = 15;
buf[1] = a2;
buf[2] = 260;
strcpy((char *)&buf[3], "Wireless Controller");
if ( write(fd, buf, 0x10AuLL) >= 0 )
return 0LL;
perror("write");
return 0xFFFFFFFFLL;
}

canonical_decompiled_code:
__int64 __fastcall func0(int fd, __int16 a2)
{
__int16 buf[140]; // [rsp+20h] [rbp-118h] BYREF

memset(buf, 0, 0x108uLL);
buf[132] = 0;
buf[0] = 15;
buf[1] = a2;
buf[2] = 260;
strcpy((char *)&buf[3], "Wireless Controller");
if ( write(fd, buf, 0x10AuLL) >= 0 )
return 0LL;
perror("write");
return 0xFFFFFFFFLL;
}

original_code:
static int mgmt_set_local_name(int sk, uint16_t index)
{
  char buf[6 + sizeof(struct mgmt_cp_set_local_name)];
  struct mgmt_hdr *hdr = (void *) buf;
  struct mgmt_cp_set_local_name *cp = (void *) &buf[sizeof(*hdr)];
  memset(buf, 0, sizeof(buf));
  hdr->opcode = (0x000F);
  hdr->index = (index);
  hdr->len = (sizeof(*cp));
  char name[] = "Wireless Controller";
  memcpy(cp->name, name, sizeof(name));
  if (write(sk, buf, sizeof(buf)) < 0)
  {
    perror("write");
    return -1;
  }
  return 0;
}

canonical_original_code:
static int mgmt_set_local_name(int sk, unsigned short index)
{
  char buf[-1];
  struct mgmt_hdr *hdr = (void *) buf;
  struct mgmt_cp_set_local_name *cp = (void *) &buf[sizeof(*hdr)];
  memset(buf, 0, sizeof(buf));
  hdr->opcode = (0x000F);
  hdr->index = (index);
  hdr->len = (sizeof(*cp));
  char name[] = "Wireless Controller";
  memcpy(cp->name, name, sizeof(name));
  if (write(sk, buf, sizeof(buf)) < 0)
  {
    perror("write");
    return -1;
  }
  return 0;
}

variable_types: sk int

variable_types:
index
unsigned short

variable_types:
buf
char [-1]

variable_types: struct mgmt_hdr { unsigned short opcode; unsigned short index; unsigned short len; } *

variable_types: struct mgmt_cp_set_local_name { unsigned char name[-1]; unsigned char short_name[-1]; } *

variable_types:
name
char []


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 func5(__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:
__int64 mgmt_create()
{
int v0; // eax
unsigned int v1; // ebx
__int16 v3[7]; // [rsp+Ah] [rbp-Eh] BYREF

v0 = socket(31, 526339, 1);
if ( v0 < 0 )
{
perror("socket");
v1 = -1;
}
else
{
v1 = v0;
v3[0] = 31;
v3[1] = -1;
v3[2] = 3;
if ( bind(v0, (const struct sockaddr *)v3, 6u) < 0 )
{
perror("bind");
close(v1);
v1 = -1;
}
}
return v1;
}

canonical_decompiled_code:
__int64 func8()
{
int v0; // eax
unsigned int v1; // ebx
__int16 v3[7]; // [rsp+Ah] [rbp-Eh] BYREF

v0 = socket(31, 526339, 1);
if ( v0 < 0 )
{
perror("socket");
v1 = -1;
}
else
{
v1 = v0;
v3[0] = 31;
v3[1] = -1;
v3[2] = 3;
if ( bind(v0, (const struct sockaddr *)v3, 6u) < 0 )
{
perror("bind");
close(v1);
v1 = -1;
}
}
return v1;
}

original_code:
int mgmt_create(void)
{
  struct sockaddr_hci addr;
  int sk;
  sk = socket(31, SOCK_RAW | SOCK_CLOEXEC | SOCK_NONBLOCK, 1);
  if (sk < 0)
  {
    perror("socket");
    return -1;
  }
  memset(&addr, 0, sizeof(addr));
  addr.hci_family = 31;
  addr.hci_dev = 0xffff;
  addr.hci_channel = 3;
  if (bind(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0)
  {
    perror("bind");
    close(sk);
    return -1;
  }
  return sk;
}

canonical_original_code:
int mgmt_create()
{
  struct sockaddr_hci addr;
  int sk;
  sk = socket(31, SOCK_RAW | SOCK_CLOEXEC | SOCK_NONBLOCK, 1);
  if (sk < 0)
  {
    perror("socket");
    return -1;
  }
  memset(&addr, 0, sizeof(addr));
  addr.hci_family = 31;
  addr.hci_dev = 0xffff;
  addr.hci_channel = 3;
  if (bind(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0)
  {
    perror("bind");
    close(sk);
    return -1;
  }
  return sk;
}

variable_types: struct sockaddr_hci { unsigned short hci_family; unsigned short hci_dev; unsigned short hci_channel; }

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


decompiled_code:
__int64 __fastcall bt_mgmt_adapter_init(__int16 a1)
{
int v1; // eax
int v2; // ebx
__int64 result; // rax
__m128i v4[2]; // [rsp+0h] [rbp-48h] BYREF
char v5[36]; // [rsp+24h] [rbp-24h] BYREF

v1 = mgmt_create();
if ( v1 < 0 )
{
fwrite("can't open a management socket\n", 1uLL, 0x1FuLL, stderr);
return 0xFFFFFFFFLL;
}
v2 = v1;
step = 1;
if ( (int)mgmt_set_mode(v1, a1, 5, 1) < 0 )
{
fwrite("set_powered failed\n", 1uLL, 0x13uLL, stderr);
close(v2);
return 0xFFFFFFFFLL;
}
if ( (int)mgmt_read_evt(v2) < 0 )
goto LABEL_18;
step = 3;
if ( (int)mgmt_set_local_name(v2, a1) < 0 )
{
fwrite("set_local_name failed\n", 1uLL, 0x16uLL, stderr);
close(v2);
return 0xFFFFFFFFLL;
}
if ( (int)mgmt_read_evt(v2) < 0 )
goto LABEL_18;
step = 2;
if ( (int)mgmt_set_mode(v2, a1, 7, 1) < 0 )
{
fwrite("set_connectable failed\n", 1uLL, 0x17uLL, stderr);
close(v2);
return 0xFFFFFFFFLL;
}
if ( (int)mgmt_read_evt(v2) < 0 )
{
LABEL_18:
close(v2);
result = 0xFFFFFFFFLL;
}
else
{
step = 4;
if ( (int)read_link_keys(a1, 2u, (__int64)v5, (char *)v4) < 0 )
{
fwrite("read_link_keys failed\n", 1uLL, 0x16uLL, stderr);
close(v2);
result = 0xFFFFFFFFLL;
}
else if ( (int)mgmt_load_link_keys(v2, a1, 2u, (__int64)v5, v4) < 0 )
{
fwrite("load_link_keys failed\n", 1uLL, 0x16uLL, stderr);
close(v2);
result = 0xFFFFFFFFLL;
}
else if ( (int)mgmt_read_evt(v2) < 0 )
{
close(v2);
result = 0xFFFFFFFFLL;
}
else
{
close(v2);
result = 0LL;
}
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func9(__int16 a1)
{
int v1; // eax
int v2; // ebx
__int64 result; // rax
__m128i v4[2]; // [rsp+0h] [rbp-48h] BYREF
char v5[36]; // [rsp+24h] [rbp-24h] BYREF

v1 = func8();
if ( v1 < 0 )
{
fwrite("can't open a management socket\n", 1uLL, 0x1FuLL, stderr);
return 0xFFFFFFFFLL;
}
v2 = v1;
step = 1;
if ( (int)func1(v1, a1, 5, 1) < 0 )
{
fwrite("set_powered failed\n", 1uLL, 0x13uLL, stderr);
close(v2);
return 0xFFFFFFFFLL;
}
if ( (int)func7(v2) < 0 )
goto LABEL_18;
step = 3;
if ( (int)func0(v2, a1) < 0 )
{
fwrite("set_local_name failed\n", 1uLL, 0x16uLL, stderr);
close(v2);
return 0xFFFFFFFFLL;
}
if ( (int)func7(v2) < 0 )
goto LABEL_18;
step = 2;
if ( (int)func1(v2, a1, 7, 1) < 0 )
{
fwrite("set_connectable failed\n", 1uLL, 0x17uLL, stderr);
close(v2);
return 0xFFFFFFFFLL;
}
if ( (int)func7(v2) < 0 )
{
LABEL_18:
close(v2);
result = 0xFFFFFFFFLL;
}
else
{
step = 4;
if ( (int)func4(a1, 2u, (__int64)v5, (char *)v4) < 0 )
{
fwrite("read_link_keys failed\n", 1uLL, 0x16uLL, stderr);
close(v2);
result = 0xFFFFFFFFLL;
}
else if ( (int)func6(v2, a1, 2u, (__int64)v5, v4) < 0 )
{
fwrite("load_link_keys failed\n", 1uLL, 0x16uLL, stderr);
close(v2);
result = 0xFFFFFFFFLL;
}
else if ( (int)func7(v2) < 0 )
{
close(v2);
result = 0xFFFFFFFFLL;
}
else
{
close(v2);
result = 0LL;
}
}
return result;
}

original_code:
int bt_mgmt_adapter_init(uint16_t index)
{
  int sk;
  if((sk = mgmt_create()) < 0)
  {
    fprintf(stderr, "can't open a management socket\n");
    return -1;
  }
  step = E_SET_POWERED;
  if(mgmt_set_mode(sk, index, 0x0005, 1) < 0)
  {
    fprintf(stderr, "set_powered failed\n");
    close(sk);
    return -1;
  }
  if(mgmt_read_evt(sk) < 0)
  {
    close(sk);
    return -1;
  }
  step = E_SET_LOCAL_NAME;
  if(mgmt_set_local_name(sk, index) < 0)
  {
    fprintf(stderr, "set_local_name failed\n");
    close(sk);
    return -1;
  }
  if(mgmt_read_evt(sk) < 0)
  {
    close(sk);
    return -1;
  }
  step = E_SET_CONNECTABLE;
  if(mgmt_set_mode(sk, index, 0x0007, 1) < 0)
  {
    fprintf(stderr, "set_connectable failed\n");
    close(sk);
    return -1;
  }
  if(mgmt_read_evt(sk) < 0)
  {
    close(sk);
    return -1;
  }
  step = E_LOAD_LINK_KEYS;
  bdaddr_t bdaddrs[2];
  unsigned char keys[2][16];
  if(read_link_keys(index, 2, bdaddrs, keys) < 0)
  {
    fprintf(stderr, "read_link_keys failed\n");
    close(sk);
    return -1;
  }
  if(mgmt_load_link_keys(sk, index, 2, bdaddrs, keys) < 0)
  {
    fprintf(stderr, "load_link_keys failed\n");
    close(sk);
    return -1;
  }
  if(mgmt_read_evt(sk) < 0)
  {
    close(sk);
    return -1;
  }
  close(sk);
  return 0;
}

canonical_original_code:
int bt_mgmt_adapter_init(unsigned short index)
{
  int sk;
  if((sk = mgmt_create()) < 0)
  {
    fprintf(stderr, "can't open a management socket\n");
    return -1;
  }
  step = E_SET_POWERED;
  if(mgmt_set_mode(sk, index, 0x0005, 1) < 0)
  {
    fprintf(stderr, "set_powered failed\n");
    close(sk);
    return -1;
  }
  if(mgmt_read_evt(sk) < 0)
  {
    close(sk);
    return -1;
  }
  step = E_SET_LOCAL_NAME;
  if(mgmt_set_local_name(sk, index) < 0)
  {
    fprintf(stderr, "set_local_name failed\n");
    close(sk);
    return -1;
  }
  if(mgmt_read_evt(sk) < 0)
  {
    close(sk);
    return -1;
  }
  step = E_SET_CONNECTABLE;
  if(mgmt_set_mode(sk, index, 0x0007, 1) < 0)
  {
    fprintf(stderr, "set_connectable failed\n");
    close(sk);
    return -1;
  }
  if(mgmt_read_evt(sk) < 0)
  {
    close(sk);
    return -1;
  }
  step = E_LOAD_LINK_KEYS;
  struct bdaddr_t bdaddrs[2];
  unsigned char keys[2][16];
  if(read_link_keys(index, 2, bdaddrs, keys) < 0)
  {
    fprintf(stderr, "read_link_keys failed\n");
    close(sk);
    return -1;
  }
  if(mgmt_load_link_keys(sk, index, 2, bdaddrs, keys) < 0)
  {
    fprintf(stderr, "load_link_keys failed\n");
    close(sk);
    return -1;
  }
  if(mgmt_read_evt(sk) < 0)
  {
    close(sk);
    return -1;
  }
  close(sk);
  return 0;
}

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

variable_types:
keys
unsigned char [2][16]


original_code:
int csr_read_pskey_complex(int dd, uint16_t seqnum, uint16_t pskey, uint16_t stores, uint8_t *value, uint16_t length)
{
  unsigned char cmd[] = { 0x00, 0x00, ((length / 2) + 8) & 0xff, ((length / 2) + 8) >> 8,
        seqnum & 0xff, seqnum >> 8, 0x03, 0x70, 0x00, 0x00,
        pskey & 0xff, pskey >> 8,
        (length / 2) & 0xff, (length / 2) >> 8,
        stores & 0xff, stores >> 8, 0x00, 0x00 };
  unsigned char cp[254], rp[254];
  struct hci_request rq;
  memset(&cp, 0, sizeof(cp));
  cp[0] = 0xc2;
  memcpy(cp + 1, cmd, sizeof(cmd));
  memset(&rq, 0, sizeof(rq));
  rq.ogf = 0x3f;
  rq.ocf = 0x00;
  rq.event = 0xFF;
  rq.cparam = cp;
  rq.clen = sizeof(cmd) + length - 1;
  rq.rparam = rp;
  rq.rlen = sizeof(rp);
  if (hci_send_req(dd, &rq, 2000) < 0)
    return -1;
  if (rp[0] != 0xc2) {
    (*__errno_location ()) = 5;
    return -1;
  }
  if ((rp[9] + (rp[10] << 8)) != 0) {
    (*__errno_location ()) = 6;
    return -1;
  }
  memcpy(value, rp + 17, length);
  return 0;
}

canonical_original_code:
int csr_read_pskey_complex(int dd, unsigned short seqnum, unsigned short pskey, unsigned short stores, unsigned char *value, unsigned short length)
{
  unsigned char cmd[] = { 0x00, 0x00, ((length / 2) + 8) & 0xff, ((length / 2) + 8) >> 8,
        seqnum & 0xff, seqnum >> 8, 0x03, 0x70, 0x00, 0x00,
        pskey & 0xff, pskey >> 8,
        (length / 2) & 0xff, (length / 2) >> 8,
        stores & 0xff, stores >> 8, 0x00, 0x00 };
  unsigned char cp[254]; unsigned char rp[254];
  struct hci_request rq;
  memset(&cp, 0, sizeof(cp));
  cp[0] = 0xc2;
  memcpy(cp + 1, cmd, sizeof(cmd));
  memset(&rq, 0, sizeof(rq));
  rq.ogf = 0x3f;
  rq.ocf = 0x00;
  rq.event = 0xFF;
  rq.cparam = cp;
  rq.clen = sizeof(cmd) + length - 1;
  rq.rparam = rp;
  rq.rlen = sizeof(rp);
  if (hci_send_req(dd, &rq, 2000) < 0)
    return -1;
  if (rp[0] != 0xc2) {
    (*__errno_location ()) = 5;
    return -1;
  }
  if ((rp[9] + (rp[10] << 8)) != 0) {
    (*__errno_location ()) = 6;
    return -1;
  }
  memcpy(value, rp + 17, length);
  return 0;
}

variable_types: dd int

variable_types:
seqnum
unsigned short

variable_types:
pskey
unsigned short

variable_types:
stores
unsigned short

variable_types:
value
unsigned char *

variable_types:
length
unsigned short

variable_types:
cmd
unsigned char []

variable_types:
cp
unsigned char [254]

variable_types:
rp
unsigned char [254]

variable_types: struct hci_request { unsigned short ogf; unsigned short ocf; int event; void *cparam; int clen; void *rparam; int rlen; }


decompiled_code:
__int64 __fastcall csr_read_pskey_uint16(unsigned int a1, __int16 a2, __int16 a3, __int16 a4, _WORD *a5)
{
__int64 result; // rax
__int16 v7; // [rsp+Eh] [rbp-Ah] BYREF

v7 = 0;
LODWORD(result) = csr_read_pskey_complex(a1, a2, a3, a4, &v7, 2u);
*a5 = (unsigned __int8)v7 + (HIBYTE(v7) << 8);
return (unsigned int)result;
}

canonical_decompiled_code:
__int64 __fastcall func1(unsigned int a1, __int16 a2, __int16 a3, __int16 a4, _WORD *a5)
{
__int64 result; // rax
__int16 v7; // [rsp+Eh] [rbp-Ah] BYREF

v7 = 0;
LODWORD(result) = func0(a1, a2, a3, a4, &v7, 2u);
*a5 = (unsigned __int8)v7 + (HIBYTE(v7) << 8);
return (unsigned int)result;
}

original_code:
int csr_read_pskey_uint16(int dd, uint16_t seqnum, uint16_t pskey, uint16_t stores, uint16_t *value)
{
  uint8_t array[2] = { 0x00, 0x00 };
  int err;
  err = csr_read_pskey_complex(dd, seqnum, pskey, stores, array, 2);
  *value = array[0] + (array[1] << 8);
  return err;
}

canonical_original_code:
int csr_read_pskey_uint16(int dd, unsigned short seqnum, unsigned short pskey, unsigned short stores, unsigned short *value)
{
  unsigned char array[2] = { 0x00, 0x00 };
  int err;
  err = csr_read_pskey_complex(dd, seqnum, pskey, stores, array, 2);
  *value = array[0] + (array[1] << 8);
  return err;
}

variable_types:
value
unsigned short *

variable_types:
array
unsigned char [2]

variable_types: err int


decompiled_code:
const char *__fastcall csr_chipvertostr(__int16 a1, unsigned __int16 a2)
{
const char *result; // rax

switch ( a1 )
{
case 0:
result = "BlueCore01a";
break;
case 1:
result = "BlueCore01b (ES)";
if ( a2 != 100 )
result = "BlueCore01b";
break;
case 2:
result = "BlueCore02-External (ES2)";
if ( a2 != 137 )
{
result = "BlueCore02-External";
if ( a2 != 138 )
{
result = "BlueCore02";
if ( a2 == 40 )
result = "BlueCore02-ROM/Audio/Flash";
}
}
break;
case 3:
if ( a2 == 48 )
{
result = "BlueCore4-ROM";
}
else if ( a2 <= 0x30u )
{
result = "BlueCore3-ROM";
if ( a2 != 21 )
{
result = "BlueCore3 or BlueCore4";
if ( a2 == 38 )
result = "BlueCore4-External";
}
}
else
{
result = "BlueCore3-MM";
if ( a2 != 67 )
{
result = "BlueCore3 or BlueCore4";
if ( a2 == 226 )
result = "BlueCore3-Flash";
}
}
break;
case 7:
result = "CSR8510";
if ( a2 )
result = "CSR8510 or later";
break;
default:
result = "Unknown";
break;
}
return result;
}

canonical_decompiled_code:
const char *__fastcall func2(__int16 a1, unsigned __int16 a2)
{
const char *result; // rax

switch ( a1 )
{
case 0:
result = "BlueCore01a";
break;
case 1:
result = "BlueCore01b (ES)";
if ( a2 != 100 )
result = "BlueCore01b";
break;
case 2:
result = "BlueCore02-External (ES2)";
if ( a2 != 137 )
{
result = "BlueCore02-External";
if ( a2 != 138 )
{
result = "BlueCore02";
if ( a2 == 40 )
result = "BlueCore02-ROM/Audio/Flash";
}
}
break;
case 3:
if ( a2 == 48 )
{
result = "BlueCore4-ROM";
}
else if ( a2 <= 0x30u )
{
result = "BlueCore3-ROM";
if ( a2 != 21 )
{
result = "BlueCore3 or BlueCore4";
if ( a2 == 38 )
result = "BlueCore4-External";
}
}
else
{
result = "BlueCore3-MM";
if ( a2 != 67 )
{
result = "BlueCore3 or BlueCore4";
if ( a2 == 226 )
result = "BlueCore3-Flash";
}
}
break;
case 7:
result = "CSR8510";
if ( a2 )
result = "CSR8510 or later";
break;
default:
result = "Unknown";
break;
}
return result;
}

original_code:
char *csr_chipvertostr(uint16_t ver, uint16_t rev)
{
  switch (ver) {
  case 0x00:
    return "BlueCore01a";
  case 0x01:
    switch (rev) {
    case 0x64:
      return "BlueCore01b (ES)";
    case 0x65:
    default:
      return "BlueCore01b";
    }
    break;
  case 0x02:
    switch (rev) {
    case 0x89:
      return "BlueCore02-External (ES2)";
    case 0x8a:
      return "BlueCore02-External";
    case 0x28:
      return "BlueCore02-ROM/Audio/Flash";
    default:
      return "BlueCore02";
    }
    break;
  case 0x03:
    switch (rev) {
    case 0x43:
      return "BlueCore3-MM";
    case 0x15:
      return "BlueCore3-ROM";
    case 0xe2:
      return "BlueCore3-Flash";
    case 0x26:
      return "BlueCore4-External";
    case 0x30:
      return "BlueCore4-ROM";
    default:
      return "BlueCore3 or BlueCore4";
    }
    break;
  case 0x07:
    switch (rev) {
    case 0x00:
      return "CSR8510";
    default:
      return "CSR8510 or later";
    }
    break;
  default:
    return "Unknown";
  }
}

canonical_original_code:
char *csr_chipvertostr(unsigned short ver, unsigned short rev)
{
  switch (ver) {
  case 0x00:
    return "BlueCore01a";
  case 0x01:
    switch (rev) {
    case 0x64:
      return "BlueCore01b (ES)";
    case 0x65:
    default:
      return "BlueCore01b";
    }
    break;
  case 0x02:
    switch (rev) {
    case 0x89:
      return "BlueCore02-External (ES2)";
    case 0x8a:
      return "BlueCore02-External";
    case 0x28:
      return "BlueCore02-ROM/Audio/Flash";
    default:
      return "BlueCore02";
    }
    break;
  case 0x03:
    switch (rev) {
    case 0x43:
      return "BlueCore3-MM";
    case 0x15:
      return "BlueCore3-ROM";
    case 0xe2:
      return "BlueCore3-Flash";
    case 0x26:
      return "BlueCore4-External";
    case 0x30:
      return "BlueCore4-ROM";
    default:
      return "BlueCore3 or BlueCore4";
    }
    break;
  case 0x07:
    switch (rev) {
    case 0x00:
      return "CSR8510";
    default:
      return "CSR8510 or later";
    }
    break;
  default:
    return "Unknown";
  }
}

variable_types:
ver
unsigned short

variable_types:
rev
unsigned short


decompiled_code:
__int64 __fastcall csr_read_varid_uint16(unsigned int a1, __int16 a2, __int16 a3, _WORD *a4)
{
__int64 result; // rax
__int64 v6[6]; // [rsp+0h] [rbp-238h] BYREF
char v7[256]; // [rsp+30h] [rbp-208h] BYREF
char v8[248]; // [rsp+130h] [rbp-108h] BYREF
int v9; // [rsp+228h] [rbp-10h]
__int16 v10; // [rsp+22Ch] [rbp-Ch]

memset(v8, 0, sizeof(v8));
v9 = 0;
v10 = 0;
v8[0] = -62;
v8[3] = 9;
*(_WORD *)&v8[5] = a2;
*(_WORD *)&v8[7] = a3;
v6[0] = 0xFF0000003FLL;
v6[2] = 19LL;
v6[4] = 254LL;
v6[1] = (__int64)v8;
v6[3] = (__int64)v7;
if ( (int)hci_send_req(a1, v6, 2000LL) < 0 )
return 0xFFFFFFFFLL;
if ( v7[0] == -62 )
{
result = (unsigned __int8)v7[9] + ((unsigned __int8)v7[10] << 8);
if ( (_DWORD)result )
{
*_errno_location() = 6;
result = 0xFFFFFFFFLL;
}
else
{
*a4 = (unsigned __int8)v7[11] + ((unsigned __int8)v7[12] << 8);
}
}
else
{
*_errno_location() = 5;
result = 0xFFFFFFFFLL;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func3(unsigned int a1, __int16 a2, __int16 a3, _WORD *a4)
{
__int64 result; // rax
__int64 v6[6]; // [rsp+0h] [rbp-238h] BYREF
char v7[256]; // [rsp+30h] [rbp-208h] BYREF
char v8[248]; // [rsp+130h] [rbp-108h] BYREF
int v9; // [rsp+228h] [rbp-10h]
__int16 v10; // [rsp+22Ch] [rbp-Ch]

memset(v8, 0, sizeof(v8));
v9 = 0;
v10 = 0;
v8[0] = -62;
v8[3] = 9;
*(_WORD *)&v8[5] = a2;
*(_WORD *)&v8[7] = a3;
v6[0] = 0xFF0000003FLL;
v6[2] = 19LL;
v6[4] = 254LL;
v6[1] = (__int64)v8;
v6[3] = (__int64)v7;
if ( (int)hci_send_req(a1, v6, 2000LL) < 0 )
return 0xFFFFFFFFLL;
if ( v7[0] == -62 )
{
result = (unsigned __int8)v7[9] + ((unsigned __int8)v7[10] << 8);
if ( (_DWORD)result )
{
*_errno_location() = 6;
result = 0xFFFFFFFFLL;
}
else
{
*a4 = (unsigned __int8)v7[11] + ((unsigned __int8)v7[12] << 8);
}
}
else
{
*_errno_location() = 5;
result = 0xFFFFFFFFLL;
}
return result;
}

original_code:
int csr_read_varid_uint16(int dd, uint16_t seqnum, uint16_t varid, uint16_t *value)
{
  unsigned char cmd[] = { 0x00, 0x00, 0x09, 0x00,
        seqnum & 0xff, seqnum >> 8, varid & 0xff, varid >> 8, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
  unsigned char cp[254], rp[254];
  struct hci_request rq;
  memset(&cp, 0, sizeof(cp));
  cp[0] = 0xc2;
  memcpy(cp + 1, cmd, sizeof(cmd));
  memset(&rq, 0, sizeof(rq));
  rq.ogf = 0x3f;
  rq.ocf = 0x00;
  rq.event = 0xFF;
  rq.cparam = cp;
  rq.clen = sizeof(cmd) + 1;
  rq.rparam = rp;
  rq.rlen = sizeof(rp);
  if (hci_send_req(dd, &rq, 2000) < 0)
    return -1;
  if (rp[0] != 0xc2) {
    (*__errno_location ()) = 5;
    return -1;
  }
  if ((rp[9] + (rp[10] << 8)) != 0) {
    (*__errno_location ()) = 6;
    return -1;
  }
  *value = rp[11] + (rp[12] << 8);
  return 0;
}

canonical_original_code:
int csr_read_varid_uint16(int dd, unsigned short seqnum, unsigned short varid, unsigned short *value)
{
  unsigned char cmd[] = { 0x00, 0x00, 0x09, 0x00,
        seqnum & 0xff, seqnum >> 8, varid & 0xff, varid >> 8, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
  unsigned char cp[254]; unsigned char rp[254];
  struct hci_request rq;
  memset(&cp, 0, sizeof(cp));
  cp[0] = 0xc2;
  memcpy(cp + 1, cmd, sizeof(cmd));
  memset(&rq, 0, sizeof(rq));
  rq.ogf = 0x3f;
  rq.ocf = 0x00;
  rq.event = 0xFF;
  rq.cparam = cp;
  rq.clen = sizeof(cmd) + 1;
  rq.rparam = rp;
  rq.rlen = sizeof(rp);
  if (hci_send_req(dd, &rq, 2000) < 0)
    return -1;
  if (rp[0] != 0xc2) {
    (*__errno_location ()) = 5;
    return -1;
  }
  if ((rp[9] + (rp[10] << 8)) != 0) {
    (*__errno_location ()) = 6;
    return -1;
  }
  *value = rp[11] + (rp[12] << 8);
  return 0;
}

variable_types:
varid
unsigned short

user_defined_types: struct hci_request { unsigned short ogf; unsigned short ocf; int event; void *cparam; int clen; void *rparam; int rlen; }


main

canonical_name: main

decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
unsigned int v4; // [rsp+0h] [rbp-Ch] BYREF

if ( argc <= 1 )
return 0;
if ( (int)_isoc99_sscanf(argv[1], "hci%d", &v4) > 0 )
cmd_revision(0LL, v4);
return 0;
}

canonical_decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
unsigned int v4; // [rsp+0h] [rbp-Ch] BYREF

if ( argc <= 1 )
return 0;
if ( (int)_isoc99_sscanf(argv[1], "hci%d", &v4) > 0 )
func5(0LL, v4);
return 0;
}

original_code:
int main(int argc, char *argv[])
{
  int i;
  if(argc > 1 && sscanf(argv[1], "hci%d", &i) > 0)
  {
    cmd_revision(0, i, ((void *)0));
  }
  return 0;
}

variable_types: argc int

variable_types:
argv
char *[]

variable_types: i int


decompiled_code:
__int64 l2cap_abs_get()
{
return l2cap_abs[bt_abs_value];
}

canonical_decompiled_code:
__int64 func0()
{
return l2cap_abs[bt_abs_value];
}

original_code:
s_l2cap_abs * l2cap_abs_get()
{
  return l2cap_abs[bt_abs_value];
}

canonical_original_code:
struct s_l2cap_abs *l2cap_abs_get()
{
  return l2cap_abs[bt_abs_value];
}

return_type: struct s_l2cap_abs { int (*connect)(char *bdaddr_src, char *bdaddr_dest, unsigned short psm, int options, void *user, int (*callback)(void *user), int (*close_callback)(void *user)); int (*listen)(void *user, char *bdaddr_adapter, unsigned short psm, int options, int (*read_callback)(int channel, struct bdaddr_t { unsigned char b[6]; } *src), int (*close_callback)(void *user)); int (*send)(int channel, unsigned char *buf, int len, int blocking); int (*recv)(int channel, unsigned char *buf, int len); int (*close)(int channel); void (*add_source)(int channel, void *user, int (*read_callback)(void *user), int (*packet_callback)(void *user, int psm, unsigned char *buf, int len), int (*close_callback)(void *user)); int (*disconnect)(int channel); } *

user_defined_types: struct s_l2cap_abs { int (*connect)(char *bdaddr_src, char *bdaddr_dest, unsigned short psm, int options, void *user, int (*callback)(void *user), int (*close_callback)(void *user)); int (*listen)(void *user, char *bdaddr_adapter, unsigned short psm, int options, int (*read_callback)(int channel, struct bdaddr_t *src), int (*close_callback)(void *user)); int (*send)(int channel, unsigned char *buf, int len, int blocking); int (*recv)(int channel, unsigned char *buf, int len); int (*close)(int channel); void (*add_source)(int channel, void *user, int (*read_callback)(void *user), int (*packet_callback)(void *user, int psm, unsigned char *buf, int len), int (*close_callback)(void *user)); int (*disconnect)(int channel); }


decompiled_code:
void __fastcall l2cap_abs_register(int a1, __int64 a2)
{
l2cap_abs[a1] = a2;
}

canonical_decompiled_code:
void __fastcall func1(int a1, __int64 a2)
{
l2cap_abs[a1] = a2;
}

original_code:
void l2cap_abs_register(e_bt_abs index, s_l2cap_abs * value)
{
  l2cap_abs[index] = value;
}

canonical_original_code:
void l2cap_abs_register(enum e_bt_abs index, struct s_l2cap_abs *value)
{
  l2cap_abs[index] = value;
}

variable_types: enum e_bt_abs { E_BT_ABS_BTSTACK=0, E_BT_ABS_BLUEZ=1, E_BT_ABS_MAX=2 }

variable_types: struct s_l2cap_abs { int (*connect)(char *bdaddr_src, char *bdaddr_dest, unsigned short psm, int options, void *user, int (*callback)(void *user), int (*close_callback)(void *user)); int (*listen)(void *user, char *bdaddr_adapter, unsigned short psm, int options, int (*read_callback)(int channel, struct bdaddr_t { unsigned char b[6]; } *src), int (*close_callback)(void *user)); int (*send)(int channel, unsigned char *buf, int len, int blocking); int (*recv)(int channel, unsigned char *buf, int len); int (*close)(int channel); void (*add_source)(int channel, void *user, int (*read_callback)(void *user), int (*packet_callback)(void *user, int psm, unsigned char *buf, int len), int (*close_callback)(void *user)); int (*disconnect)(int channel); } *


decompiled_code:
__int64 __fastcall is_device_opened(char *s2)
{
const char **v1; // rbx

v1 = (const char **)&unk_988;
do
{
if ( *v1 && !strcmp(*v1, s2) )
return 1LL;
v1 += 6;
}
while ( v1 != (const char **)((char *)&unk_988 + 384) );
return 0LL;
}

canonical_decompiled_code:
__int64 __fastcall func3(char *s2)
{
const char **v1; // rbx

v1 = (const char **)&unk_988;
do
{
if ( *v1 && !strcmp(*v1, s2) )
return 1LL;
v1 += 6;
}
while ( v1 != (const char **)((char *)&unk_988 + 384) );
return 0LL;
}

original_code:
static uint8_t is_device_opened(const char* device)
{
  unsigned int i;
  for(i = 0; i < sizeof(devices) / sizeof(*devices); ++i)
  {
    if(devices[i].path && !strcmp(devices[i].path, device))
    {
      return 1;
    }
  }
  return 0;
}

canonical_original_code:
static unsigned char is_device_opened(char *device)
{
  unsigned int i;
  for(i = 0; i < sizeof(devices) / sizeof(*devices); ++i)
  {
    if(devices[i].path && !strcmp(devices[i].path, device))
    {
      return 1;
    }
  }
  return 0;
}

variable_types:
device
char *

variable_types:
i
unsigned int


decompiled_code:
__int64 __fastcall gpppcprog_send(signed int a1, char a2, __int64 a3, int a4)
{
__int16 v5; // bp
int v7; // edx
__int64 result; // rax
__int64 v9; // rdx
int v10; // ebp
_QWORD *v11; // rbx
int v12; // er13
__int64 dest[8]; // [rsp+0h] [rbp-88h] BYREF
char v14; // [rsp+40h] [rbp-48h]

v5 = a4;
v7 = check_device(a1, "pcprog.c", 0x8Fu, "gpppcprog_send");
result = 0xFFFFFFFFLL;
if ( v7 >= 0 )
{
v9 = 48LL * a1;
result = 0LL;
if ( !*(_DWORD *)((char *)&devices + v9 + 16) )
{
dest[0] = 0x100000000LL;
dest[1] = 0LL;
dest[2] = 0LL;
dest[3] = 0LL;
dest[4] = 0LL;
dest[5] = 0LL;
dest[6] = 0LL;
dest[7] = 0LL;
v14 = 0;
BYTE1(dest[0]) = a2;
WORD1(dest[0]) = v5;
v10 = 0;
v11 = (_QWORD *)((char *)&devices + v9);
while ( 1 )
{
if ( (_WORD)a4 )
{
v12 = a4 - v10;
if ( (unsigned __int64)(unsigned __int16)v10 + 60 < (unsigned __int16)a4 )
v12 = 60;
memcpy((char *)dest + 5, (const void *)(a3 + (unsigned __int16)v10), (unsigned __int16)v12);
v10 += v12;
}
if ( v11[4] )
{
if ( (unsigned int)ghid_write(*v11, dest, 65LL) == -1 )
return 0xFFFFFFFFLL;
++*((_DWORD *)v11 + 4);
}
else if ( (unsigned int)ghid_write_timeout(*v11, dest, 65LL, 1000LL) == -1 )
{
return 0xFFFFFFFFLL;
}
BYTE4(dest[0]) = 0;
if ( (unsigned __int16)v10 >= (unsigned __int16)a4 )
return 1LL;
}
}
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func4(signed int a1, char a2, __int64 a3, int a4)
{
__int16 v5; // bp
int v7; // edx
__int64 result; // rax
__int64 v9; // rdx
int v10; // ebp
_QWORD *v11; // rbx
int v12; // er13
__int64 dest[8]; // [rsp+0h] [rbp-88h] BYREF
char v14; // [rsp+40h] [rbp-48h]

v5 = a4;
v7 = func2(a1, "pcprog.c", 0x8Fu, "gpppcprog_send");
result = 0xFFFFFFFFLL;
if ( v7 >= 0 )
{
v9 = 48LL * a1;
result = 0LL;
if ( !*(_DWORD *)((char *)&devices + v9 + 16) )
{
dest[0] = 0x100000000LL;
dest[1] = 0LL;
dest[2] = 0LL;
dest[3] = 0LL;
dest[4] = 0LL;
dest[5] = 0LL;
dest[6] = 0LL;
dest[7] = 0LL;
v14 = 0;
BYTE1(dest[0]) = a2;
WORD1(dest[0]) = v5;
v10 = 0;
v11 = (_QWORD *)((char *)&devices + v9);
while ( 1 )
{
if ( (_WORD)a4 )
{
v12 = a4 - v10;
if ( (unsigned __int64)(unsigned __int16)v10 + 60 < (unsigned __int16)a4 )
v12 = 60;
memcpy((char *)dest + 5, (const void *)(a3 + (unsigned __int16)v10), (unsigned __int16)v12);
v10 += v12;
}
if ( v11[4] )
{
if ( (unsigned int)ghid_write(*v11, dest, 65LL) == -1 )
return 0xFFFFFFFFLL;
++*((_DWORD *)v11 + 4);
}
else if ( (unsigned int)ghid_write_timeout(*v11, dest, 65LL, 1000LL) == -1 )
{
return 0xFFFFFFFFLL;
}
BYTE4(dest[0]) = 0;
if ( (unsigned __int16)v10 >= (unsigned __int16)a4 )
return 1LL;
}
}
}
return result;
}

original_code:
static int8_t gpppcprog_send(int id, uint8_t type, uint8_t * data, uint16_t length)
{
  if(check_device(id, "pcprog.c", 143, __func__) < 0) { return -1; }
  if (devices[id].pending > 0)
  {
    return 0;
  }
  s_gppReport report =
  {
    .reportId = 0x00,
    .header =
    {
      .type = type,
      .length = length,
      .first = 1
    }
  };
  uint16_t sndLen;
  uint16_t i = 0;
  do
  {
    if (length)
    {
      sndLen = (((i + sizeof(report.data)) < length) ? sizeof(report.data) : (uint16_t)(length - i));
      memcpy(report.data, data + i, sndLen);
      i += sndLen;
    }
    if(devices[id].fp_write) {
      if (ghid_write(devices[id].device, (unsigned char*)&report, sizeof(report)) == -1)
      {
        return -1;
      }
      ++devices[id].pending;
    }
    else {
      if (ghid_write_timeout(devices[id].device, (unsigned char*)&report, sizeof(report), 1000) == -1)
        return -1;
    }
    report.header.first = 0;
  }
  while (i < length);
  return 1;
}

canonical_original_code:
static char gpppcprog_send(int id, unsigned char type, unsigned char *data, unsigned short length)
{
  if(check_device(id, "pcprog.c", 143, __func__) < 0) { return -1; }
  if (devices[id].pending > 0)
  {
    return 0;
  }
  struct s_gppReport report = {
    .reportId = 0x00,
    .header =
    {
      .type = type,
      .length = length,
      .first = 1
    }
  };
  unsigned short sndLen;
  unsigned short i = 0;
  do
  {
    if (length)
    {
      sndLen = (((i + sizeof(report.data)) < length) ? sizeof(report.data) : (unsigned short)(length - i));
      memcpy(report.data, data + i, sndLen);
      i += sndLen;
    }
    if(devices[id].fp_write) {
      if (ghid_write(devices[id].device, (unsigned char *)&report, sizeof(report)) == -1)
      {
        return -1;
      }
      ++devices[id].pending;
    }
    else {
      if (ghid_write_timeout(devices[id].device, (unsigned char *)&report, sizeof(report), 1000) == -1)
        return -1;
    }
    report.header.first = 0;
  }
  while (i < length);
  return 1;
}

variable_types: id int

variable_types:
type
unsigned char

variable_types:
data
unsigned char *

variable_types:
length
unsigned short

variable_types: struct s_gppReport { unsigned char reportId; struct s_gppReportHeader { unsigned char type; unsigned short length; unsigned char first; } header; unsigned char data[-1]; }

variable_types:
sndLen
unsigned short

variable_types:
i
unsigned short

return_type: char

user_defined_types: struct s_gppReport { unsigned char reportId; struct s_gppReportHeader header; unsigned char data[-1]; }


decompiled_code:
__int64 gimxgpp_log_constructor()
{
return glog_register("gimxgpp", gimxgpp_set_log_level);
}

canonical_decompiled_code:
__int64 func6()
{
return glog_register("gimxgpp", gimxgpp_set_log_level);
}

original_code: void gimxgpp_log_constructor(void) { glog_register("gimxgpp", gimxgpp_set_log_level); }

canonical_original_code: void gimxgpp_log_constructor() { glog_register("gimxgpp", gimxgpp_set_log_level); }


decompiled_code:
void *__fastcall gpppcprog_get_ids(_DWORD *a1)
{
*a1 = nb_usb_ids;
return &usb_ids;
}

canonical_decompiled_code:
void *__fastcall func8(_DWORD *a1)
{
*a1 = nb_usb_ids;
return &usb_ids;
}

original_code:
const GCAPI_USB_IDS * gpppcprog_get_ids(unsigned int * nb)
{
  *nb = nb_usb_ids;
  return usb_ids;
}

canonical_original_code:
struct GCAPI_USB_IDS *gpppcprog_get_ids(unsigned int *nb)
{
  *nb = nb_usb_ids;
  return usb_ids;
}

variable_types:
nb
unsigned int *

return_type: struct GCAPI_USB_IDS { unsigned short vid; unsigned short pid; char *name; } *


decompiled_code:
__int64 __fastcall gppcprog_connect(unsigned int a1, char *a2)
{
__int64 v2; // rdx
__int64 result; // rax
__int64 i; // rbp
_WORD *v5; // rbx
char *v6; // r14
__int64 v7; // rax
__int64 v8; // [rsp+8h] [rbp-40h]

if ( (int)check_device(a1, "pcprog.c", 0xCAu, "gppcprog_connect") < 0 )
return 0xFFFFFFFFLL;
if ( !a2 )
{
v8 = ghid_enumerate(0LL, 0LL);
for ( i = v8; i; i = *(_QWORD *)(i + 24) )
{
v5 = &usb_ids;
do
{
if ( *(_WORD *)i == *v5 && *(_WORD *)(i + 2) == v5[1] )
{
v6 = *(char **)(i + 16);
if ( !(unsigned __int8)is_device_opened(v6) )
{
v7 = ghid_open_path(v6);
*((_QWORD *)&devices + 6 * (int)a1) = v7;
if ( v7 )
{
*((_QWORD *)&devices + 6 * (int)a1 + 1) = strdup(*(const char **)(i + 16));
goto LABEL_14;
}
}
}
v5 += 8;
}
while ( v5 != (_WORD *)((char *)&usb_ids + 256) );
if ( *((_QWORD *)&devices + 6 * (int)a1) )
break;
}
LABEL_14:
ghid_free_enumeration(v8);
if ( !*((_QWORD *)&devices + 6 * (int)a1) )
return 0xFFFFFFFFLL;
goto LABEL_15;
}
if ( (unsigned __int8)is_device_opened(a2) )
return 0xFFFFFFFFLL;
v2 = ghid_open_path(a2);
*((_QWORD *)&devices + 6 * (int)a1) = v2;
result = 0xFFFFFFFFLL;
if ( v2 )
{
*((_QWORD *)&devices + 6 * (int)a1 + 1) = strdup(a2);
LABEL_15:
result = gpppcprog_send(a1, 7, 0LL, 0);
if ( (char)result > 0 )
result = 1LL;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func9(unsigned int a1, char *a2)
{
__int64 v2; // rdx
__int64 result; // rax
__int64 i; // rbp
_WORD *v5; // rbx
char *v6; // r14
__int64 v7; // rax
__int64 v8; // [rsp+8h] [rbp-40h]

if ( (int)func2(a1, "pcprog.c", 0xCAu, "gppcprog_connect") < 0 )
return 0xFFFFFFFFLL;
if ( !a2 )
{
v8 = ghid_enumerate(0LL, 0LL);
for ( i = v8; i; i = *(_QWORD *)(i + 24) )
{
v5 = &usb_ids;
do
{
if ( *(_WORD *)i == *v5 && *(_WORD *)(i + 2) == v5[1] )
{
v6 = *(char **)(i + 16);
if ( !(unsigned __int8)func3(v6) )
{
v7 = ghid_open_path(v6);
*((_QWORD *)&devices + 6 * (int)a1) = v7;
if ( v7 )
{
*((_QWORD *)&devices + 6 * (int)a1 + 1) = strdup(*(const char **)(i + 16));
goto LABEL_14;
}
}
}
v5 += 8;
}
while ( v5 != (_WORD *)((char *)&usb_ids + 256) );
if ( *((_QWORD *)&devices + 6 * (int)a1) )
break;
}
LABEL_14:
ghid_free_enumeration(v8);
if ( !*((_QWORD *)&devices + 6 * (int)a1) )
return 0xFFFFFFFFLL;
goto LABEL_15;
}
if ( (unsigned __int8)func3(a2) )
return 0xFFFFFFFFLL;
v2 = ghid_open_path(a2);
*((_QWORD *)&devices + 6 * (int)a1) = v2;
result = 0xFFFFFFFFLL;
if ( v2 )
{
*((_QWORD *)&devices + 6 * (int)a1 + 1) = strdup(a2);
LABEL_15:
result = func4(a1, 7, 0LL, 0);
if ( (char)result > 0 )
result = 1LL;
}
return result;
}

original_code:
int8_t gppcprog_connect(int id, const char * path)
{
  if(check_device(id, "pcprog.c", 202, __func__) < 0) { return -1; }
  int r = 0;
  if(path)
  {
    if(is_device_opened(path))
    {
      return -1;
    }
    devices[id].device = ghid_open_path(path);
    if(devices[id].device != ((void *)0))
    {
      devices[id].path = strdup(path);
    }
  }
  else
  {
    struct ghid_device_info *devs, *cur_dev;
    devs = ghid_enumerate(0x0000, 0x0000);
    for(cur_dev = devs; cur_dev != ((void *)0); cur_dev = cur_dev->next)
    {
      unsigned int i;
      for(i = 0; i < sizeof(usb_ids) / sizeof(*usb_ids); ++i)
      {
        if(cur_dev->vendor_id == usb_ids[i].vid && cur_dev->product_id == usb_ids[i].pid)
        {
          if(!is_device_opened(cur_dev->path))
          {
            if ((devices[id].device = ghid_open_path(cur_dev->path)) != ((void *)0))
            {
              devices[id].path = strdup(cur_dev->path);
              break;
            }
          }
        }
      }
      if(devices[id].device != ((void *)0))
      {
        break;
      }
    }
    ghid_free_enumeration(devs);
  }
  if (devices[id].device == ((void *)0))
  {
    return -1;
  }
  r = gpppcprog_send(id, 0x07, ((void *)0), 0);
  if (r <= 0)
  {
    return r;
  }
  return 1;
}

canonical_original_code:
char gppcprog_connect(int id, char *path)
{
  if(check_device(id, "pcprog.c", 202, __func__) < 0) { return -1; }
  int r = 0;
  if(path)
  {
    if(is_device_opened(path))
    {
      return -1;
    }
    devices[id].device = ghid_open_path(path);
    if(devices[id].device != ((void *)0))
    {
      devices[id].path = strdup(path);
    }
  }
  else
  {
    struct ghid_device_info *devs; struct ghid_device_info *cur_dev;
    devs = ghid_enumerate(0x0000, 0x0000);
    for(cur_dev = devs; cur_dev != ((void *)0); cur_dev = cur_dev->next)
    {
      unsigned int i;
      for(i = 0; i < sizeof(usb_ids) / sizeof(*usb_ids); ++i)
      {
        if(cur_dev->vendor_id == usb_ids[i].vid && cur_dev->product_id == usb_ids[i].pid)
        {
          if(!is_device_opened(cur_dev->path))
          {
            if ((devices[id].device = ghid_open_path(cur_dev->path)) != ((void *)0))
            {
              devices[id].path = strdup(cur_dev->path);
              break;
            }
          }
        }
      }
      if(devices[id].device != ((void *)0))
      {
        break;
      }
    }
    ghid_free_enumeration(devs);
  }
  if (devices[id].device == ((void *)0))
  {
    return -1;
  }
  r = gpppcprog_send(id, 0x07, ((void *)0), 0);
  if (r <= 0)
  {
    return r;
  }
  return 1;
}

variable_types:
path
char *

variable_types: r int

variable_types: struct ghid_device_info { unsigned short vendor_id; unsigned short product_id; unsigned short bcdDevice; int interface_number; char *path; struct ghid_device_info *next; } *


decompiled_code:
void __fastcall gppcprog_disconnect(signed int a1)
{
__int64 v1; // rbp

if ( (int)check_device(a1, "pcprog.c", 0x10Fu, "gppcprog_disconnect") >= 0 )
{
if ( *((_QWORD *)&devices + 6 * a1) )
{
v1 = 2LL * a1;
*((_QWORD *)&devices + 6 * a1 + 4) = 0LL;
*((_DWORD *)&devices + 12 * a1 + 4) = 0;
gpppcprog_send(a1, 8, 0LL, 0);
ghid_close(*((_QWORD *)&devices + 6 * a1));
*((_QWORD *)&devices + 2 * v1 + 2 * a1) = 0LL;
free(*((void **)&devices + 6 * a1 + 1));
*((_QWORD *)&devices + 2 * a1 + 2 * v1 + 1) = 0LL;
}
}
}

canonical_decompiled_code:
void __fastcall func10(signed int a1)
{
__int64 v1; // rbp

if ( (int)func2(a1, "pcprog.c", 0x10Fu, "gppcprog_disconnect") >= 0 )
{
if ( *((_QWORD *)&devices + 6 * a1) )
{
v1 = 2LL * a1;
*((_QWORD *)&devices + 6 * a1 + 4) = 0LL;
*((_DWORD *)&devices + 12 * a1 + 4) = 0;
func4(a1, 8, 0LL, 0);
ghid_close(*((_QWORD *)&devices + 6 * a1));
*((_QWORD *)&devices + 2 * v1 + 2 * a1) = 0LL;
free(*((void **)&devices + 6 * a1 + 1));
*((_QWORD *)&devices + 2 * a1 + 2 * v1 + 1) = 0LL;
}
}
}

original_code:
void gppcprog_disconnect(int id)
{
  if(check_device(id, "pcprog.c", 271, __func__) < 0) { return ; }
  if (devices[id].device != ((void *)0))
  {
    devices[id].fp_write = ((void *)0);
    devices[id].pending = 0;
    gpppcprog_send(id, 0x08, ((void *)0), 0);
    ghid_close(devices[id].device);
    devices[id].device = ((void *)0);
    free(devices[id].path);
    devices[id].path = ((void *)0);
  }
  return;
}


decompiled_code:
__int64 __fastcall gpppcprog_input(unsigned int a1, __m128i *a2, unsigned int a3)
{
int v4; // edx
__int64 result; // rax
__int64 v6; // rdi
int v7; // edx
__int128 v8; // [rsp+0h] [rbp-68h] BYREF
__int128 v9; // [rsp+10h] [rbp-58h] BYREF
__int128 v10; // [rsp+20h] [rbp-48h]
__int64 v11; // [rsp+30h] [rbp-38h]
__int64 v12; // [rsp+38h] [rbp-30h]
char v13; // [rsp+40h] [rbp-28h]

v4 = check_device(a1, "pcprog.c", 0x127u, "gpppcprog_input");
result = 0xFFFFFFFFLL;
if ( v4 >= 0 )
{
v8 = 0uLL;
v9 = 0uLL;
v10 = 0uLL;
v11 = 0LL;
v12 = 0LL;
v13 = 0;
v6 = *((_QWORD *)&devices + 6 * (int)a1);
if ( a2 && v6 )
{
v7 = ghid_read_timeout(v6, &v8, 65LL, a3);
result = 0xFFFFFFFFLL;
if ( v7 >= 0 )
{
result = 0LL;
if ( v7 )
{
if ( (_BYTE)v8 == 1 )
{
*a2 = _mm_loadu_si128((const __m128i *)((char *)&v8 + 7));
a2[1] = _mm_loadu_si128((const __m128i *)((char *)&v9 + 7));
a2[2].m128i_i32[0] = *(_DWORD *)((char *)&v10 + 7);
a2[2].m128i_i16[2] = *(_WORD *)((char *)&v10 + 11);
a2[2].m128i_i8[6] = BYTE13(v10);
result = 1LL;
}
}
}
}
else
{
result = 0xFFFFFFFFLL;
}
}
return result;
}

original_code:
int8_t gpppcprog_input(int id, GCAPI_REPORT *report, int timeout)
{
  if(check_device(id, "pcprog.c", 295, __func__) < 0) { return -1; }
  int bytesReceived;
  uint8_t rcvBuf[65] = {};
  if (devices[id].device == ((void *)0) || report == ((void *)0))
    return (-1);
  bytesReceived = ghid_read_timeout(devices[id].device, rcvBuf, sizeof(rcvBuf), timeout);
  if (bytesReceived < 0)
  {
    return (-1);
  }
  else if (bytesReceived && rcvBuf[0] == 0x01)
  {
    *report = *(GCAPI_REPORT *)(rcvBuf + 7);
    return (1);
  }
  return (0);
}

canonical_original_code:
char gpppcprog_input(int id, struct GCAPI_REPORT *report, int timeout)
{
  if(check_device(id, "pcprog.c", 295, __func__) < 0) { return -1; }
  int bytesReceived;
  unsigned char rcvBuf[65] = {};
  if (devices[id].device == ((void *)0) || report == ((void *)0))
    return (-1);
  bytesReceived = ghid_read_timeout(devices[id].device, rcvBuf, sizeof(rcvBuf), timeout);
  if (bytesReceived < 0)
  {
    return (-1);
  }
  else if (bytesReceived && rcvBuf[0] == 0x01)
  {
    *report = *(struct GCAPI_REPORT *)(rcvBuf + 7);
    return (1);
  }
  return (0);
}

variable_types: struct GCAPI_REPORT { unsigned char controller; unsigned char console; unsigned char led[4]; unsigned char rumble[2]; unsigned char battery_level; struct { char value; } input[30]; } *

variable_types: timeout int

variable_types: bytesReceived int

variable_types:
rcvBuf
unsigned char [65]


decompiled_code:
__int64 __fastcall gpppcprog_start_async(unsigned int a1, _QWORD *a2)
{
__int64 result; // rax
__int64 v3[9]; // [rsp+0h] [rbp-48h] BYREF

if ( (int)check_device(a1, "pcprog.c", 0x168u, "gpppcprog_start_async") < 0 )
return 0xFFFFFFFFLL;
*((_QWORD *)&devices + 6 * (int)a1 + 3) = *a2;
*((_QWORD *)&devices + 6 * (int)a1 + 4) = a2[1];
*((_QWORD *)&devices + 6 * (int)a1 + 5) = a2[2];
v3[0] = (__int64)read_callback;
v3[1] = (__int64)write_callback;
v3[2] = (__int64)close_callback;
v3[3] = a2[3];
v3[4] = a2[4];
if ( (int)ghid_register(*((_QWORD *)&devices + 6 * (int)a1), (char *)&devices + 48 * (int)a1, v3) < 0 )
result = 0xFFFFFFFFLL;
else
result = (unsigned int)((int)ghid_poll(*((_QWORD *)&devices + 6 * (int)a1)) >> 31);
return result;
}

canonical_decompiled_code:
__int64 __fastcall func12(unsigned int a1, _QWORD *a2)
{
__int64 result; // rax
__int64 v3[9]; // [rsp+0h] [rbp-48h] BYREF

if ( (int)func2(a1, "pcprog.c", 0x168u, "gpppcprog_start_async") < 0 )
return 0xFFFFFFFFLL;
*((_QWORD *)&devices + 6 * (int)a1 + 3) = *a2;
*((_QWORD *)&devices + 6 * (int)a1 + 4) = a2[1];
*((_QWORD *)&devices + 6 * (int)a1 + 5) = a2[2];
v3[0] = (__int64)read_callback;
v3[1] = (__int64)write_callback;
v3[2] = (__int64)close_callback;
v3[3] = a2[3];
v3[4] = a2[4];
if ( (int)ghid_register(*((_QWORD *)&devices + 6 * (int)a1), (char *)&devices + 48 * (int)a1, v3) < 0 )
result = 0xFFFFFFFFLL;
else
result = (unsigned int)((int)ghid_poll(*((_QWORD *)&devices + 6 * (int)a1)) >> 31);
return result;
}

original_code:
int8_t gpppcprog_start_async(int id, const GHID_CALLBACKS * callbacks)
{
  if(check_device(id, "pcprog.c", 360, __func__) < 0) { return -1; }
  devices[id].fp_read = callbacks->fp_read;
  devices[id].fp_write = callbacks->fp_write;
  devices[id].fp_close = callbacks->fp_close;
  GHID_CALLBACKS ghid_callbacks = {
          .fp_read = read_callback,
          .fp_write = write_callback,
          .fp_close = close_callback,
          .fp_register = callbacks->fp_register,
          .fp_remove = callbacks->fp_remove,
  };
  int ret = ghid_register(devices[id].device, devices + id, &ghid_callbacks);
  if (ret < 0) {
    return -1;
  }
  ret = ghid_poll(devices[id].device);
  if (ret < 0) {
    return -1;
  }
  return 0;
}

canonical_original_code:
char gpppcprog_start_async(int id, struct GHID_CALLBACKS *callbacks)
{
  if(check_device(id, "pcprog.c", 360, __func__) < 0) { return -1; }
  devices[id].fp_read = callbacks->fp_read;
  devices[id].fp_write = callbacks->fp_write;
  devices[id].fp_close = callbacks->fp_close;
  struct GHID_CALLBACKS ghid_callbacks = {
          .fp_read = read_callback,
          .fp_write = write_callback,
          .fp_close = close_callback,
          .fp_register = callbacks->fp_register,
          .fp_remove = callbacks->fp_remove,
  };
  int ret = ghid_register(devices[id].device, devices + id, &ghid_callbacks);
  if (ret < 0) {
    return -1;
  }
  ret = ghid_poll(devices[id].device);
  if (ret < 0) {
    return -1;
  }
  return 0;
}

variable_types: struct GHID_CALLBACKS { int (*fp_read)(void *user, void *buf, int status); int (*fp_write)(void *user, int status); int (*fp_close)(void *user); int (*fp_register)(int fd, void *user, struct GPOLL_CALLBACKS { int (*fp_read)(void *user); int (*fp_write)(void *user); int (*fp_close)(void *user); } *callbacks); int (*fp_remove)(int fd); } *

variable_types: ret int

user_defined_types: struct GHID_CALLBACKS { int (*fp_read)(void *user, void *buf, int status); int (*fp_write)(void *user, int status); int (*fp_close)(void *user); int (*fp_register)(int fd, void *user, struct GPOLL_CALLBACKS *callbacks); int (*fp_remove)(int fd); }


decompiled_code:
__int64 __fastcall gpppcprog_output(unsigned int a1, __int64 a2)
{
__int64 result; // rax

if ( (int)check_device(a1, "pcprog.c", 0x185u, "gpppcprog_output") < 0 )
result = 0xFFFFFFFFLL;
else
result = gpppcprog_send(a1, 4, a2, 36);
return result;
}

canonical_decompiled_code:
__int64 __fastcall func13(unsigned int a1, __int64 a2)
{
__int64 result; // rax

if ( (int)func2(a1, "pcprog.c", 0x185u, "gpppcprog_output") < 0 )
result = 0xFFFFFFFFLL;
else
result = func4(a1, 4, a2, 36);
return result;
}

original_code:
int8_t gpppcprog_output(int id, int8_t output[36])
{
  if(check_device(id, "pcprog.c", 389, __func__) < 0) { return -1; }
  return gpppcprog_send(id, 0x04, (uint8_t *)output, 36);
}

canonical_original_code:
char gpppcprog_output(int id, char output[36])
{
  if(check_device(id, "pcprog.c", 389, __func__) < 0) { return -1; }
  return gpppcprog_send(id, 0x04, (unsigned char *)output, 36);
}

variable_types: id int

variable_types:
output
char [36]


decompiled_code:
__int64 bt_device_bluez_device_init()
{
return 0LL;
}

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

original_code:
static int bt_device_bluez_device_init()
{
  return 0;
}


decompiled_code:
__int64 __fastcall bt_device_bluez_write_device_class(__int64 a1, unsigned int a2)
{
int v2; // eax
unsigned int v3; // ebx
int v4; // ebp

v2 = hci_open_dev();
if ( v2 < 0 )
{
perror("hci_open_dev");
v4 = -1;
}
else
{
v3 = v2;
v4 = hci_write_class_of_dev((unsigned int)v2, a2, 1000LL);
if ( v4 < 0 )
perror("hci_write_class_of_dev");
hci_close_dev(v3);
}
return (unsigned int)v4;
}

canonical_decompiled_code:
__int64 __fastcall func1(__int64 a1, unsigned int a2)
{
int v2; // eax
unsigned int v3; // ebx
int v4; // ebp

v2 = hci_open_dev();
if ( v2 < 0 )
{
perror("hci_open_dev");
v4 = -1;
}
else
{
v3 = v2;
v4 = hci_write_class_of_dev((unsigned int)v2, a2, 1000LL);
if ( v4 < 0 )
perror("hci_write_class_of_dev");
hci_close_dev(v3);
}
return (unsigned int)v4;
}

original_code:
static int bt_device_bluez_write_device_class(int device_number, uint32_t devclass)
{
  int ret = 0;
  int s = hci_open_dev (device_number);
  if(s >= 0)
  {
    ret = hci_write_class_of_dev(s, devclass, 1000);
    if(ret < 0)
    {
      perror("hci_write_class_of_dev");
    }
    hci_close_dev(s);
  }
  else
  {
    perror("hci_open_dev");
    ret = -1;
  }
  return ret;
}

canonical_original_code:
static int bt_device_bluez_write_device_class(int device_number, unsigned int devclass)
{
  int ret = 0;
  int s = hci_open_dev (device_number);
  if(s >= 0)
  {
    ret = hci_write_class_of_dev(s, devclass, 1000);
    if(ret < 0)
    {
      perror("hci_write_class_of_dev");
    }
    hci_close_dev(s);
  }
  else
  {
    perror("hci_open_dev");
    ret = -1;
  }
  return ret;
}

variable_types:
devclass
unsigned int

variable_types: s int


decompiled_code:
__int64 __fastcall bt_device_bluez_get_device_bdaddr(__int64 a1, __int64 a2)
{
int v2; // eax
unsigned int v3; // ebx
int v4; // ebp

v2 = hci_open_dev();
if ( v2 < 0 )
{
perror("hci_open_dev");
v4 = -1;
}
else
{
v3 = v2;
v4 = hci_read_bd_addr((unsigned int)v2, a2, 1000LL);
if ( v4 < 0 )
perror("hci_read_bd_addr");
hci_close_dev(v3);
}
return (unsigned int)v4;
}

canonical_decompiled_code:
__int64 __fastcall func2(__int64 a1, __int64 a2)
{
int v2; // eax
unsigned int v3; // ebx
int v4; // ebp

v2 = hci_open_dev();
if ( v2 < 0 )
{
perror("hci_open_dev");
v4 = -1;
}
else
{
v3 = v2;
v4 = hci_read_bd_addr((unsigned int)v2, a2, 1000LL);
if ( v4 < 0 )
perror("hci_read_bd_addr");
hci_close_dev(v3);
}
return (unsigned int)v4;
}

original_code:
static int bt_device_bluez_get_device_bdaddr(int device_number, bdaddr_t* ba)
{
  int ret = 0;
  int s = hci_open_dev (device_number);
  if(s >= 0)
  {
    ret = hci_read_bd_addr(s, ba, 1000);
    if(ret < 0)
    {
      perror("hci_read_bd_addr");
    }
    hci_close_dev(s);
  }
  else
  {
    perror("hci_open_dev");
    ret = -1;
  }
  return ret;
}

canonical_original_code:
static int bt_device_bluez_get_device_bdaddr(int device_number, struct bdaddr_t *ba)
{
  int ret = 0;
  int s = hci_open_dev (device_number);
  if(s >= 0)
  {
    ret = hci_read_bd_addr(s, ba, 1000);
    if(ret < 0)
    {
      perror("hci_read_bd_addr");
    }
    hci_close_dev(s);
  }
  else
  {
    perror("hci_open_dev");
    ret = -1;
  }
  return ret;
}

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


decompiled_code:
__int64 bt_device_bluez_init()
{
return bt_device_abs_register(1LL, &bt_device_bluez);
}

canonical_decompiled_code:
__int64 func3()
{
return bt_device_abs_register(1LL, &bt_device_bluez);
}

original_code:
void bt_device_bluez_init(void)
{
  bt_device_abs_register(E_BT_ABS_BLUEZ, &bt_device_bluez);
}

canonical_original_code:
void bt_device_bluez_init()
{
  bt_device_abs_register(E_BT_ABS_BLUEZ, &bt_device_bluez);
}


getANSIColor

decompiled_code:
const char *__fastcall getANSIColor(int a1)
{
const char *result; // rax

switch ( a1 )
{
case 0:
result = "\x1B[22;30m";
break;
case 1:
result = "\x1B[22;34m";
break;
case 2:
result = "\x1B[22;32m";
break;
case 3:
result = "\x1B[22;36m";
break;
case 4:
result = "\x1B[22;31m";
break;
case 5:
result = "\x1B[22;35m";
break;
case 6:
result = "\x1B[22;33m";
break;
case 7:
result = "\x1B[22;37m";
break;
case 8:
result = "\x1B[01;30m";
break;
case 9:
result = "\x1B[01;34m";
break;
case 10:
result = "\x1B[01;32m";
break;
case 11:
result = "\x1B[01;36m";
break;
case 12:
result = "\x1B[01;31m";
break;
case 13:
result = "\x1B[01;35m";
break;
case 14:
result = "\x1B[01;33m";
break;
case 15:
result = "\x1B[01;37m";
break;
default:
result = &locale;
break;
}
return result;
}

canonical_decompiled_code:
const char *__fastcall func0(int a1)
{
const char *result; // rax

switch ( a1 )
{
case 0:
result = "\x1B[22;30m";
break;
case 1:
result = "\x1B[22;34m";
break;
case 2:
result = "\x1B[22;32m";
break;
case 3:
result = "\x1B[22;36m";
break;
case 4:
result = "\x1B[22;31m";
break;
case 5:
result = "\x1B[22;35m";
break;
case 6:
result = "\x1B[22;33m";
break;
case 7:
result = "\x1B[22;37m";
break;
case 8:
result = "\x1B[01;30m";
break;
case 9:
result = "\x1B[01;34m";
break;
case 10:
result = "\x1B[01;32m";
break;
case 11:
result = "\x1B[01;36m";
break;
case 12:
result = "\x1B[01;31m";
break;
case 13:
result = "\x1B[01;35m";
break;
case 14:
result = "\x1B[01;33m";
break;
case 15:
result = "\x1B[01;37m";
break;
default:
result = &locale;
break;
}
return result;
}

original_code:
static inline const char * getANSIColor(const int c) {
    switch (c) {
        case BLACK : return ANSI_BLACK;
        case BLUE : return ANSI_BLUE;
        case GREEN : return ANSI_GREEN;
        case CYAN : return ANSI_CYAN;
        case RED : return ANSI_RED;
        case MAGENTA : return ANSI_MAGENTA;
        case BROWN : return ANSI_BROWN;
        case GREY : return ANSI_GREY;
        case DARKGREY : return ANSI_DARKGREY;
        case LIGHTBLUE : return ANSI_LIGHTBLUE;
        case LIGHTGREEN : return ANSI_LIGHTGREEN;
        case LIGHTCYAN : return ANSI_LIGHTCYAN;
        case LIGHTRED : return ANSI_LIGHTRED;
        case LIGHTMAGENTA: return ANSI_LIGHTMAGENTA;
        case YELLOW : return ANSI_YELLOW;
        case WHITE : return ANSI_WHITE;
        default: return "";
    }
}

canonical_original_code:
static inline char *getANSIColor(int c) {
    switch (c) {
        case BLACK : return ANSI_BLACK;
        case BLUE : return ANSI_BLUE;
        case GREEN : return ANSI_GREEN;
        case CYAN : return ANSI_CYAN;
        case RED : return ANSI_RED;
        case MAGENTA : return ANSI_MAGENTA;
        case BROWN : return ANSI_BROWN;
        case GREY : return ANSI_GREY;
        case DARKGREY : return ANSI_DARKGREY;
        case LIGHTBLUE : return ANSI_LIGHTBLUE;
        case LIGHTGREEN : return ANSI_LIGHTGREEN;
        case LIGHTCYAN : return ANSI_LIGHTCYAN;
        case LIGHTRED : return ANSI_LIGHTRED;
        case LIGHTMAGENTA: return ANSI_LIGHTMAGENTA;
        case YELLOW : return ANSI_YELLOW;
        case WHITE : return ANSI_WHITE;
        default: return "";
    }
}

variable_types: c int


decompiled_code:
__int64 ignore_event()
{
return 0LL;
}

canonical_decompiled_code:
__int64 func1()
{
return 0LL;
}

original_code:
int ignore_event(GE_Event* event __attribute__((unused)))
{
  return 0;
}

canonical_original_code:
int ignore_event(union GE_Event *event)
{
  return 0;
}

variable_types: 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; } *


terminate

decompiled_code:
void terminate()
{
set_done();
}

canonical_decompiled_code:
void func2()
{
set_done();
}

original_code:
void terminate(int sig __attribute__((unused)))
{
  set_done();
}

canonical_original_code:
void terminate(int sig)
{
  set_done();
}

variable_types: sig int


resetColorStdout

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

canonical_decompiled_code:
int func5()
{
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);
}


resetColorStderr

decompiled_code:
size_t resetColorStderr()
{
return fwrite("\x1B[0m", 1uLL, 4uLL, stderr);
}

canonical_decompiled_code:
size_t func7()
{
return fwrite("\x1B[0m", 1uLL, 4uLL, stderr);
}

original_code:
static inline void resetColorStderr(void) {
    fprintf(stderr, "%s", ANSI_ATTRIBUTE_RESET);
}

canonical_original_code:
static inline void resetColorStderr() {
    fprintf(stderr, "%s", ANSI_ATTRIBUTE_RESET);
}


grab

decompiled_code:
__int64 grab()
{
__int64 result; // rax

if ( *((_DWORD *)&gimx_params + 6) )
result = ginput_grab();
return result;
}

canonical_decompiled_code:
__int64 func8()
{
__int64 result; // rax

if ( *((_DWORD *)&gimx_params + 6) )
result = ginput_grab();
return result;
}

original_code:
void grab()
{
  if(gimx_params.grab)
  {
    ginput_grab();
  }
}


decompiled_code:
int show_devices()
{
unsigned int i; // ebx
const char *v1; // rbp
unsigned int v2; // eax
unsigned int j; // ebx
const char *v4; // rbp
unsigned int v5; // eax
unsigned int k; // ebx
__int64 v7; // rax
const char *v8; // rbp
unsigned int v9; // eax

for ( i = 0; i != 256; ++i )
{
v1 = (const char *)ginput_mouse_name(i);
if ( !v1 )
break;
v2 = ginput_mouse_virtual_id(i);
printf("mouse %d has name '%s' and virtual id %d\n", i, v1, v2);
}
for ( j = 0; j != 256; ++j )
{
v4 = (const char *)ginput_keyboard_name(j);
if ( !v4 )
break;
v5 = ginput_keyboard_virtual_id(j);
printf("keyboard %d has name '%s' and virtual id %d\n", j, v4, v5);
}
for ( k = 0; k != 256; ++k )
{
v7 = ginput_joystick_name(k);
v8 = (const char *)v7;
if ( !v7 )
break;
v9 = ginput_joystick_virtual_id(k);
LODWORD(v7) = printf("joystick %d has name '%s' and virtual id %d\n", k, v8, v9);
}
return v7;
}

canonical_decompiled_code:
int func9()
{
unsigned int i; // ebx
const char *v1; // rbp
unsigned int v2; // eax
unsigned int j; // ebx
const char *v4; // rbp
unsigned int v5; // eax
unsigned int k; // ebx
__int64 v7; // rax
const char *v8; // rbp
unsigned int v9; // eax

for ( i = 0; i != 256; ++i )
{
v1 = (const char *)ginput_mouse_name(i);
if ( !v1 )
break;
v2 = ginput_mouse_virtual_id(i);
printf("mouse %d has name '%s' and virtual id %d\n", i, v1, v2);
}
for ( j = 0; j != 256; ++j )
{
v4 = (const char *)ginput_keyboard_name(j);
if ( !v4 )
break;
v5 = ginput_keyboard_virtual_id(j);
printf("keyboard %d has name '%s' and virtual id %d\n", j, v4, v5);
}
for ( k = 0; k != 256; ++k )
{
v7 = ginput_joystick_name(k);
v8 = (const char *)v7;
if ( !v7 )
break;
v9 = ginput_joystick_virtual_id(k);
LODWORD(v7) = printf("joystick %d has name '%s' and virtual id %d\n", k, v8, v9);
}
return v7;
}

original_code:
void show_devices()
{
  const char * name;
  int i;
  for (i = 0; i < 256 && (name = ginput_mouse_name(i)) != ((void *)0); ++i)
  {
    printf("mouse %d has name '%s' and virtual id %d\n", i, name, ginput_mouse_virtual_id(i));
  }
  for (i = 0; i < 256 && (name = ginput_keyboard_name(i)) != ((void *)0); ++i)
  {
    printf("keyboard %d has name '%s' and virtual id %d\n", i, name, ginput_keyboard_virtual_id(i));
  }
  for (i = 0; i < 256 && (name = ginput_joystick_name(i)) != ((void *)0); ++i)
  {
    printf("joystick %d has name '%s' and virtual id %d\n", i, name, ginput_joystick_virtual_id(i));
  }
}

canonical_original_code:
void show_devices()
{
  char *name;
  int i;
  for (i = 0; i < 256 && (name = ginput_mouse_name(i)) != ((void *)0); ++i)
  {
    printf("mouse %d has name '%s' and virtual id %d\n", i, name, ginput_mouse_virtual_id(i));
  }
  for (i = 0; i < 256 && (name = ginput_keyboard_name(i)) != ((void *)0); ++i)
  {
    printf("keyboard %d has name '%s' and virtual id %d\n", i, name, ginput_keyboard_virtual_id(i));
  }
  for (i = 0; i < 256 && (name = ginput_joystick_name(i)) != ((void *)0); ++i)
  {
    printf("joystick %d has name '%s' and virtual id %d\n", i, name, ginput_joystick_virtual_id(i));
  }
}

variable_types:
name
char *

variable_types: i int