mirror of
https://github.com/CTCaer/hekate
synced 2024-12-22 11:21:23 +00:00
bdk: joycon: add packet size checks
Pass the real received data size and do the proper checks for minimum info.
This commit is contained in:
parent
b744f82942
commit
93296c2c38
1 changed files with 25 additions and 10 deletions
|
@ -234,7 +234,7 @@ typedef struct _jc_hid_in_rpt_t
|
||||||
u8 stick_h_right;
|
u8 stick_h_right;
|
||||||
u8 stick_m_right;
|
u8 stick_m_right;
|
||||||
u8 stick_v_right;
|
u8 stick_v_right;
|
||||||
u8 vib_decider; // right:8, left:8. (bit3 en, bit2-0 buffer avail).
|
u8 vib_decider; // right:4, left:4 (bit3 en, bit2-0 buffer avail).
|
||||||
u8 submcd_ack;
|
u8 submcd_ack;
|
||||||
u8 subcmd;
|
u8 subcmd;
|
||||||
u8 subcmd_data[];
|
u8 subcmd_data[];
|
||||||
|
@ -606,7 +606,7 @@ static void _jc_charging_decider(u8 batt, u8 uart)
|
||||||
_jc_power_supply(uart, false);
|
_jc_power_supply(uart, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _jc_parse_wired_hid(joycon_ctxt_t *jc, const u8* packet, u32 size)
|
static void _jc_parse_wired_hid(joycon_ctxt_t *jc, const u8 *packet, int size)
|
||||||
{
|
{
|
||||||
u32 btn_tmp;
|
u32 btn_tmp;
|
||||||
jc_hid_in_rpt_t *hid_pkt = (jc_hid_in_rpt_t *)packet;
|
jc_hid_in_rpt_t *hid_pkt = (jc_hid_in_rpt_t *)packet;
|
||||||
|
@ -614,7 +614,14 @@ static void _jc_parse_wired_hid(joycon_ctxt_t *jc, const u8* packet, u32 size)
|
||||||
switch (hid_pkt->cmd)
|
switch (hid_pkt->cmd)
|
||||||
{
|
{
|
||||||
case JC_HORI_INPUT_RPT:
|
case JC_HORI_INPUT_RPT:
|
||||||
|
if (!(jc->type & JC_ID_HORI))
|
||||||
|
return;
|
||||||
|
|
||||||
case JC_HID_INPUT_RPT:
|
case JC_HID_INPUT_RPT:
|
||||||
|
// Discard incomplete hid packets.
|
||||||
|
if (size < 12)
|
||||||
|
break;
|
||||||
|
|
||||||
btn_tmp = hid_pkt->btn_right | hid_pkt->btn_shared << 8 | hid_pkt->btn_left << 16;
|
btn_tmp = hid_pkt->btn_right | hid_pkt->btn_shared << 8 | hid_pkt->btn_left << 16;
|
||||||
|
|
||||||
if (jc->type & JC_ID_L)
|
if (jc->type & JC_ID_L)
|
||||||
|
@ -674,8 +681,12 @@ static void _jc_parse_wired_hid(joycon_ctxt_t *jc, const u8* packet, u32 size)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _jc_parse_wired_init(joycon_ctxt_t *jc, const u8* data, u32 size)
|
static void _jc_parse_wired_init(joycon_ctxt_t *jc, const u8 *data, int size)
|
||||||
{
|
{
|
||||||
|
// Discard empty packets.
|
||||||
|
if (size <= 0)
|
||||||
|
return;
|
||||||
|
|
||||||
switch (data[0])
|
switch (data[0])
|
||||||
{
|
{
|
||||||
case JC_WIRED_CMD_GET_INFO:
|
case JC_WIRED_CMD_GET_INFO:
|
||||||
|
@ -698,13 +709,13 @@ static void _jc_parse_wired_init(joycon_ctxt_t *jc, const u8* data, u32 size)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _jc_uart_pkt_parse(joycon_ctxt_t *jc, const jc_wired_hdr_t *pkt, size_t size)
|
static void _jc_uart_pkt_parse(joycon_ctxt_t *jc, const jc_wired_hdr_t *pkt, int size)
|
||||||
{
|
{
|
||||||
switch (pkt->cmd)
|
switch (pkt->cmd)
|
||||||
{
|
{
|
||||||
case JC_HORI_INPUT_RPT_CMD:
|
case JC_HORI_INPUT_RPT_CMD:
|
||||||
case JC_WIRED_HID:
|
case JC_WIRED_HID:
|
||||||
_jc_parse_wired_hid(jc, pkt->payload, (pkt->data[0] << 8) | pkt->data[1]);
|
_jc_parse_wired_hid(jc, pkt->payload, size - sizeof(jc_wired_hdr_t));
|
||||||
break;
|
break;
|
||||||
case JC_WIRED_INIT_REPLY:
|
case JC_WIRED_INIT_REPLY:
|
||||||
_jc_parse_wired_init(jc, pkt->data, size - sizeof(jc_uart_hdr_t) - 1);
|
_jc_parse_wired_init(jc, pkt->data, size - sizeof(jc_uart_hdr_t) - 1);
|
||||||
|
@ -719,11 +730,15 @@ static void _jc_uart_pkt_parse(joycon_ctxt_t *jc, const jc_wired_hdr_t *pkt, siz
|
||||||
jc->last_received_time = get_tmr_ms();
|
jc->last_received_time = get_tmr_ms();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _jc_sio_parse_payload(joycon_ctxt_t *jc, u8 cmd, const u8* payload, u32 size)
|
static void _jc_sio_parse_payload(joycon_ctxt_t *jc, u8 cmd, const u8 *payload, int size)
|
||||||
{
|
{
|
||||||
switch (cmd)
|
switch (cmd)
|
||||||
{
|
{
|
||||||
case JC_SIO_CMD_STATUS:
|
case JC_SIO_CMD_STATUS:
|
||||||
|
// Discard incomplete packets.
|
||||||
|
if (size < 12)
|
||||||
|
break;
|
||||||
|
|
||||||
jc_sio_hid_in_rpt_t *hid_pkt = (jc_sio_hid_in_rpt_t *)payload;
|
jc_sio_hid_in_rpt_t *hid_pkt = (jc_sio_hid_in_rpt_t *)payload;
|
||||||
jc_gamepad.buttons = hid_pkt->btn_right | hid_pkt->btn_shared << 8 | hid_pkt->btn_left << 16;
|
jc_gamepad.buttons = hid_pkt->btn_right | hid_pkt->btn_shared << 8 | hid_pkt->btn_left << 16;
|
||||||
jc_gamepad.home = !gpio_read(GPIO_PORT_V, GPIO_PIN_3);
|
jc_gamepad.home = !gpio_read(GPIO_PORT_V, GPIO_PIN_3);
|
||||||
|
@ -744,7 +759,7 @@ static void _jc_sio_parse_payload(joycon_ctxt_t *jc, u8 cmd, const u8* payload,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _jc_sio_uart_pkt_parse(joycon_ctxt_t *jc, const jc_sio_in_rpt_t *pkt, u32 size)
|
static void _jc_sio_uart_pkt_parse(joycon_ctxt_t *jc, const jc_sio_in_rpt_t *pkt, int size)
|
||||||
{
|
{
|
||||||
if (pkt->crc_hdr != _jc_crc((u8 *)pkt, sizeof(jc_sio_in_rpt_t) - 1, 0))
|
if (pkt->crc_hdr != _jc_crc((u8 *)pkt, sizeof(jc_sio_in_rpt_t) - 1, 0))
|
||||||
return;
|
return;
|
||||||
|
@ -761,7 +776,7 @@ static void _jc_sio_uart_pkt_parse(joycon_ctxt_t *jc, const jc_sio_in_rpt_t *pkt
|
||||||
break;
|
break;
|
||||||
case JC_SIO_CMD_IAP_VER:
|
case JC_SIO_CMD_IAP_VER:
|
||||||
case JC_SIO_CMD_STATUS:
|
case JC_SIO_CMD_STATUS:
|
||||||
_jc_sio_parse_payload(jc, cmd, pkt->payload, pkt->payload_size);
|
_jc_sio_parse_payload(jc, cmd, pkt->payload, size - sizeof(jc_sio_in_rpt_t));
|
||||||
break;
|
break;
|
||||||
case JC_SIO_CMD_UNK02:
|
case JC_SIO_CMD_UNK02:
|
||||||
case JC_SIO_CMD_UNK20:
|
case JC_SIO_CMD_UNK20:
|
||||||
|
@ -788,7 +803,7 @@ static void _jc_rcv_pkt(joycon_ctxt_t *jc)
|
||||||
jc_wired_hdr_t *jc_pkt = (jc_wired_hdr_t *)jc->buf;
|
jc_wired_hdr_t *jc_pkt = (jc_wired_hdr_t *)jc->buf;
|
||||||
if (!jc->sio_mode && !memcmp(jc_pkt->uart_hdr.magic, "\x19\x81\x03", 3))
|
if (!jc->sio_mode && !memcmp(jc_pkt->uart_hdr.magic, "\x19\x81\x03", 3))
|
||||||
{
|
{
|
||||||
_jc_uart_pkt_parse(jc, jc_pkt, jc_pkt->uart_hdr.total_size_lsb + sizeof(jc_uart_hdr_t));
|
_jc_uart_pkt_parse(jc, jc_pkt, len);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -797,7 +812,7 @@ static void _jc_rcv_pkt(joycon_ctxt_t *jc)
|
||||||
jc_sio_in_rpt_t *sio_pkt = (jc_sio_in_rpt_t *)(jc->buf);
|
jc_sio_in_rpt_t *sio_pkt = (jc_sio_in_rpt_t *)(jc->buf);
|
||||||
if (jc->sio_mode && sio_pkt->cmd == JC_SIO_INPUT_RPT && (sio_pkt->ack & JC_SIO_CMD_ACK) == JC_SIO_CMD_ACK)
|
if (jc->sio_mode && sio_pkt->cmd == JC_SIO_INPUT_RPT && (sio_pkt->ack & JC_SIO_CMD_ACK) == JC_SIO_CMD_ACK)
|
||||||
{
|
{
|
||||||
_jc_sio_uart_pkt_parse(jc, sio_pkt, sio_pkt->payload_size + sizeof(jc_sio_in_rpt_t));
|
_jc_sio_uart_pkt_parse(jc, sio_pkt, len);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue