GCC Code Coverage Report


Directory: main/
File: bluetooth/hidp/hidp.c
Date: 2025-10-04 14:03:00
Exec Total Coverage
Lines: 32 32 100.0%
Functions: 5 5 100.0%
Branches: 10 16 62.5%

Line Branch Exec Source
1 /*
2 * Copyright (c) 2019-2025, Jacques Gagnon
3 * SPDX-License-Identifier: Apache-2.0
4 */
5
6 #include "bluetooth/host.h"
7 #include "bluetooth/hci.h"
8 #include "tools/util.h"
9 #include "generic.h"
10 #include "ps3.h"
11 #include "wii.h"
12 #include "ps.h"
13 #include "sw.h"
14 #include "sw2.h"
15
16 typedef void (*bt_hid_init_t)(struct bt_dev *device);
17 typedef void (*bt_hid_hdlr_t)(struct bt_dev *device, struct bt_hci_pkt *bt_hci_acl_pkt, uint32_t len);
18 typedef void (*bt_hid_cmd_t)(struct bt_dev *device, void *report);
19
20 const uint8_t bt_hid_led_dev_id_map[] = {
21 0x1, 0x2, 0x4, 0x8, 0x3, 0x6, 0xC
22 };
23
24 static const struct bt_name_type bt_name_type[] = {
25 #ifndef CONFIG_BLUERETRO_GENERIC_HID_DEBUG
26 {"PLAYSTATION(R)3", BT_PS3, BT_SUBTYPE_DEFAULT, 0},
27 {"Xbox Wireless Controller", BT_HID_GENERIC, BT_SUBTYPE_DEFAULT, 0},
28 {"DualSense Wireless Controller", BT_PS, BT_PS5_DS, 0},
29 {"Wireless Controller", BT_PS, BT_SUBTYPE_DEFAULT, 0},
30 {"Nintendo RVL-CNT-01-UC", BT_WII, BT_WIIU_PRO, 0}, /* Must be before WII */
31 {"Nintendo RVL-CNT-01", BT_WII, BT_SUBTYPE_DEFAULT, 0},
32 {"Pro Controller", BT_SW, BT_SUBTYPE_DEFAULT, 0},
33 {"Joy-Con (L)", BT_SW, BT_SW_LEFT_JOYCON, 0},
34 {"Joy-Con (R)", BT_SW, BT_SW_RIGHT_JOYCON, 0},
35 {"SNES Controller", BT_SW, BT_SW_SNES, BIT(BT_QUIRK_TRIGGER_PRI_SEC_INVERT)},
36 {"HVC Controller", BT_SW, BT_SW_NES, BIT(BT_QUIRK_FACE_BTNS_ROTATE_RIGHT) | BIT(BT_QUIRK_TRIGGER_PRI_SEC_INVERT)},
37 {"NES Controller", BT_SW, BT_SW_NES, BIT(BT_QUIRK_FACE_BTNS_ROTATE_RIGHT) | BIT(BT_QUIRK_TRIGGER_PRI_SEC_INVERT)},
38 {"N64 Controller", BT_SW, BT_SW_N64, 0},
39 {"MD/Gen Control Pad", BT_SW, BT_SW_MD_GEN, 0},
40 {"8Bitdo NES30 Arcade", BT_HID_GENERIC, BT_SUBTYPE_DEFAULT, BIT(BT_QUIRK_FACE_BTNS_TRIGGER_TO_8BUTTONS)},
41 {"8BitDo Arcade Stick", BT_HID_GENERIC, BT_SUBTYPE_DEFAULT, BIT(BT_QUIRK_FACE_BTNS_TRIGGER_TO_8BUTTONS)},
42 {"8BitDo NGC Modkit", BT_HID_GENERIC, BT_SUBTYPE_DEFAULT, BIT(BT_QUIRK_8BITDO_GC)},
43 {"8BitDo N30 Modkit", BT_HID_GENERIC, BT_SUBTYPE_DEFAULT, BIT(BT_QUIRK_FACE_BTNS_ROTATE_RIGHT)},
44 {"8BitDo GBros Adapter", BT_HID_GENERIC, BT_SUBTYPE_DEFAULT, BIT(BT_QUIRK_8BITDO_GBROS)},
45 {"8Bitdo N64 GamePad", BT_HID_GENERIC, BT_SUBTYPE_DEFAULT, BIT(BT_QUIRK_8BITDO_N64)},
46 {"8BitDo N64 Modkit", BT_HID_GENERIC, BT_SUBTYPE_DEFAULT, BIT(BT_QUIRK_8BITDO_N64_MK)},
47 {"8BitDo NEOGEO GP", BT_HID_GENERIC, BT_SUBTYPE_DEFAULT, BIT(BT_QUIRK_TRIGGER_PRI_SEC_INVERT)},
48 {"8BitDo M30 gamepad", BT_HID_GENERIC, BT_SUBTYPE_DEFAULT, BIT(BT_QUIRK_8BITDO_M30)},
49 {"8BitDo M30 Modkit", BT_HID_GENERIC, BT_SUBTYPE_DEFAULT, BIT(BT_QUIRK_8BITDO_M30_MODKIT)},
50 {"8BitDo S30 Modkit", BT_HID_GENERIC, BT_SUBTYPE_DEFAULT, BIT(BT_QUIRK_8BITDO_SATURN)},
51 {"Retro Bit Bluetooth Controller", BT_HID_GENERIC, BT_SUBTYPE_DEFAULT, BIT(BT_QUIRK_FACE_BTNS_TRIGGER_TO_6BUTTONS) | BIT(BT_QUIRK_TRIGGER_PRI_SEC_INVERT)},
52 {"Joy Controller", BT_HID_GENERIC, BT_SUBTYPE_DEFAULT, BIT(BT_QUIRK_RF_WARRIOR)},
53 {"BlueN64 Gamepad", BT_HID_GENERIC, BT_SUBTYPE_DEFAULT, BIT(BT_QUIRK_BLUEN64_N64)},
54 {"Hyperkin Pad", BT_SW, BT_SW_HYPERKIN_ADMIRAL, 0},
55 {"OUYA Game Controller", BT_HID_GENERIC, BT_SUBTYPE_DEFAULT, BIT(BT_QUIRK_OUYA)},
56 {"DeviceName", BT_SW2, BT_SUBTYPE_DEFAULT, 0},
57 #endif
58 };
59
60 static const bt_hid_init_t bt_hid_init_list[BT_TYPE_MAX] = {
61 bt_hid_generic_init, /* BT_HID_GENERIC */
62 bt_hid_ps3_init, /* BT_PS3 */
63 bt_hid_wii_init, /* BT_WII */
64 bt_hid_ps_init, /* BT_PS */
65 bt_hid_sw_init, /* BT_SW */
66 bt_hid_sw2_init, /* BT_SW2 */
67 };
68
69 static const bt_hid_hdlr_t bt_hid_hdlr_list[BT_TYPE_MAX] = {
70 bt_hid_generic_hdlr, /* BT_HID_GENERIC */
71 bt_hid_ps3_hdlr, /* BT_PS3 */
72 bt_hid_wii_hdlr, /* BT_WII */
73 bt_hid_ps_hdlr, /* BT_PS */
74 bt_hid_sw_hdlr, /* BT_SW */
75 NULL, /* BT_SW2 */
76 };
77
78 static const bt_hid_cmd_t bt_hid_feedback_list[BT_TYPE_MAX] = {
79 bt_hid_cmd_generic_rumble, /* BT_HID_GENERIC */
80 bt_hid_cmd_ps3_set_conf, /* BT_PS3 */
81 bt_hid_cmd_wii_set_feedback, /* BT_WII */
82 bt_hid_cmd_ps_set_conf, /* BT_PS */
83 bt_hid_cmd_sw_set_conf, /* BT_SW */
84 bt_hid_cmd_sw2_out, /* BT_SW2 */
85 };
86
87 92 void bt_hid_set_type_flags_from_name(struct bt_dev *device, const char* name) {
88
2/2
✓ Branch 0 (8→3) taken 1231 times.
✓ Branch 1 (8→9) taken 21 times.
1252 for (uint32_t i = 0; i < sizeof(bt_name_type)/sizeof(*bt_name_type); i++) {
89
2/2
✓ Branch 0 (4→5) taken 71 times.
✓ Branch 1 (4→7) taken 1160 times.
1231 if (strcasestr(name, bt_name_type[i].name) != NULL) {
90 71 struct bt_data *bt_data = &bt_adapter.data[device->ids.id];
91
92 71 bt_type_update(device->ids.id, bt_name_type[i].type, bt_name_type[i].subtype);
93 71 bt_data->base.flags[PAD] = bt_name_type[i].hid_flags;
94 71 device->name = &bt_name_type[i];
95 71 break;
96 }
97 }
98 92 }
99
100 92 void bt_hid_init(struct bt_dev *device) {
101
2/4
✓ Branch 0 (2→3) taken 92 times.
✗ Branch 1 (2→5) not taken.
✓ Branch 2 (3→4) taken 92 times.
✗ Branch 3 (3→5) not taken.
92 if (device->ids.type > BT_NONE && bt_hid_init_list[device->ids.type]) {
102 92 bt_hid_init_list[device->ids.type](device);
103 }
104 92 }
105
106 1469 void bt_hid_hdlr(struct bt_dev *device, struct bt_hci_pkt *bt_hci_acl_pkt, uint32_t len) {
107
2/4
✓ Branch 0 (2→3) taken 1469 times.
✗ Branch 1 (2→5) not taken.
✓ Branch 2 (3→4) taken 1469 times.
✗ Branch 3 (3→5) not taken.
1469 if (device->ids.type > BT_NONE && bt_hid_hdlr_list[device->ids.type]) {
108 1469 bt_hid_hdlr_list[device->ids.type](device, bt_hci_acl_pkt, len);
109 }
110 1469 }
111
112 27 void bt_hid_feedback(struct bt_dev *device, void *report) {
113
2/4
✓ Branch 0 (2→3) taken 27 times.
✗ Branch 1 (2→5) not taken.
✓ Branch 2 (3→4) taken 27 times.
✗ Branch 3 (3→5) not taken.
27 if (device->ids.type > BT_NONE && bt_hid_feedback_list[device->ids.type]) {
114 27 bt_hid_feedback_list[device->ids.type](device, report);
115 }
116 27 }
117
118 196 void bt_hid_cmd(uint16_t handle, uint16_t cid, uint8_t hidp_hdr, uint8_t protocol, uint16_t len) {
119 196 uint16_t packet_len = (BT_HCI_H4_HDR_SIZE + BT_HCI_ACL_HDR_SIZE
120 + sizeof(struct bt_l2cap_hdr) + sizeof(struct bt_hidp_hdr) + len);
121
122 196 bt_hci_pkt_tmp.h4_hdr.type = BT_HCI_H4_TYPE_ACL;
123
124 196 bt_hci_pkt_tmp.acl_hdr.handle = bt_acl_handle_pack(handle, 0x2);
125 196 bt_hci_pkt_tmp.acl_hdr.len = packet_len - BT_HCI_H4_HDR_SIZE - BT_HCI_ACL_HDR_SIZE;
126
127 196 bt_hci_pkt_tmp.l2cap_hdr.len = bt_hci_pkt_tmp.acl_hdr.len - sizeof(bt_hci_pkt_tmp.l2cap_hdr);
128 196 bt_hci_pkt_tmp.l2cap_hdr.cid = cid;
129
130 196 bt_hci_pkt_tmp.hidp_hdr.hdr = hidp_hdr;
131 196 bt_hci_pkt_tmp.hidp_hdr.protocol = protocol;
132
133 196 bt_host_txq_add((uint8_t *)&bt_hci_pkt_tmp, packet_len);
134 196 }
135