Skip to content

Commit ca84f9d

Browse files
ZarithyaDacoTaco
andauthored
Wiimote: Add wireless controller syncing functionality (#197)
* Add remote syncing * replicating Wii menu pairing functionality * Properly wait for USB to close * Implement Guest mode pairing * General disconnect CB * Disambiguate front panel power button from auth'd Wiimote power button --------- Co-authored-by: DacoTaco <daco_65@hotmail.com>
1 parent 7868add commit ca84f9d

22 files changed

Lines changed: 2701 additions & 859 deletions

gc/bte/bd_addr.h

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,12 +39,12 @@
3939
extern "C" {
4040
#endif /* __cplusplus */
4141

42+
#define BD_ADDR_LEN 6
43+
4244
struct bd_addr {
43-
u8 addr[6];
45+
u8 addr[BD_ADDR_LEN];
4446
};
4547

46-
#define BD_ADDR_LEN 6
47-
4848
#define BD_ADDR_ANY (&(struct bd_addr){{0,0,0,0,0,0}})
4949
#define BD_ADDR_LOCAL (&(struct bd_addr){{0,0,0,0xff,0xff,0xff}})
5050

@@ -55,6 +55,23 @@ struct bd_addr {
5555
(bdaddr)->addr[3] = d; \
5656
(bdaddr)->addr[4] = e; \
5757
(bdaddr)->addr[5] = f; }while(0)
58+
59+
#define BD_ADDR_FROM_BYTES(bdaddr, bytes) do{ \
60+
(bdaddr)->addr[0] = bytes[5]; \
61+
(bdaddr)->addr[1] = bytes[4]; \
62+
(bdaddr)->addr[2] = bytes[3]; \
63+
(bdaddr)->addr[3] = bytes[2]; \
64+
(bdaddr)->addr[4] = bytes[1]; \
65+
(bdaddr)->addr[5] = bytes[0]; }while(0)
66+
67+
#define BYTES_FROM_BD_ADDR(bytes, bdaddr) do{ \
68+
bytes[0] = (bdaddr)->addr[5]; \
69+
bytes[1] = (bdaddr)->addr[4]; \
70+
bytes[2] = (bdaddr)->addr[3]; \
71+
bytes[3] = (bdaddr)->addr[2]; \
72+
bytes[4] = (bdaddr)->addr[1]; \
73+
bytes[5] = (bdaddr)->addr[0]; }while(0)
74+
5875
//TODO: USE memcmp????
5976
#define bd_addr_cmp(addr1, addr2) (((addr1)->addr[0] == (addr2)->addr[0]) && \
6077
((addr1)->addr[1] == (addr2)->addr[1]) && \

gc/bte/bte.h

Lines changed: 52 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -56,18 +56,27 @@
5656
#define HIDP_CTRL_VC_UNPLUG 0x05
5757

5858
/* HIDP data transaction headers */
59-
#define HIDP_DATA_RTYPE_MASK 0x03
60-
#define HIDP_DATA_RSRVD_MASK 0x0c
61-
#define HIDP_DATA_RTYPE_OTHER 0x00
62-
#define HIDP_DATA_RTYPE_INPUT 0x01
63-
#define HIDP_DATA_RTYPE_OUPUT 0x02
64-
#define HIDP_DATA_RTYPE_FEATURE 0x03
59+
#define HIDP_DATA_RTYPE_MASK 0x03
60+
#define HIDP_DATA_RSRVD_MASK 0x0c
61+
#define HIDP_DATA_RTYPE_OTHER 0x00
62+
#define HIDP_DATA_RTYPE_INPUT 0x01
63+
#define HIDP_DATA_RTYPE_OUPUT 0x02
64+
#define HIDP_DATA_RTYPE_FEATURE 0x03
6565

6666
#define HIDP_PROTO_BOOT 0x00
6767
#define HIDP_PROTO_REPORT 0x01
6868

69+
#define BD_LINK_KEY_LEN 16
70+
#define BD_NAME_LEN 248
71+
#define BD_MAX_INQUIRY_DEVS 255
72+
73+
enum pair_mode {
74+
PAIR_MODE_NORMAL,
75+
PAIR_MODE_TEMPORARY
76+
};
77+
6978
#ifdef __cplusplus
70-
extern "C" {
79+
extern "C" {
7180
#endif /* __cplusplus */
7281

7382
struct l2cap_pcb;
@@ -88,10 +97,22 @@ struct inquiry_info_ex
8897
u16 co;
8998
};
9099

100+
struct bte_inquiry_res
101+
{
102+
u8 count;
103+
struct inquiry_info_ex *info;
104+
};
105+
91106
struct linkkey_info
92107
{
93108
struct bd_addr bdaddr;
94-
u8 key[16];
109+
u8 key[BD_LINK_KEY_LEN];
110+
};
111+
112+
struct pad_name_info
113+
{
114+
struct bd_addr bdaddr;
115+
u8 name[BD_NAME_LEN];
95116
};
96117

97118
struct bte_pcb
@@ -112,6 +133,7 @@ struct bte_pcb
112133

113134

114135
s32 (*recv)(void *arg,void *buffer,u16 len);
136+
s32 (*conn_req)(void *arg,struct bte_pcb *pcb,struct bd_addr *bdaddr,u8 *cod,u8 link_type,u8 err);
115137
s32 (*conn_cfm)(void *arg,struct bte_pcb *pcb,u8 err);
116138
s32 (*disconn_cfm)(void *arg,struct bte_pcb *pcb,u8 err);
117139
};
@@ -120,34 +142,47 @@ typedef s32 (*btecallback)(s32 result,void *userdata);
120142

121143
void BTE_Init(void);
122144
void BTE_Shutdown(void);
145+
void BTE_Close(void);
123146
s32 BTE_InitCore(btecallback cb);
124147
s32 BTE_ApplyPatch(btecallback cb);
125148
s32 BTE_InitSub(btecallback cb);
126149
s32 BTE_ReadStoredLinkKey(struct linkkey_info *keys,u8 max_cnt,btecallback cb);
127150
s32 BTE_ReadBdAddr(struct bd_addr *bdaddr, btecallback cb);
151+
s32 BTE_SetEvtFilter(u8 filter_type,u8 filter_cond_type,u8 *cond, btecallback cb);
152+
s32 BTE_ReadRemoteName(struct pad_name_info *padinfo, btecallback cb);
153+
s32 BTE_Inquiry(u8 max_cnt,u8 flush, btecallback cb);
154+
s32 BTE_PeriodicInquiry(u8 max_cnt,u8 flush,btecallback cb);
155+
s32 BTE_ExitPeriodicInquiry(void);
156+
s32 BTE_LinkKeyRequestReply(struct bd_addr *bdaddr,u8 *key);
157+
s32 BTE_LinkKeyRequestNegativeReply(struct bd_addr *bdaddr);
128158
void (*BTE_SetDisconnectCallback(void (*callback)(struct bd_addr *bdaddr,u8 reason)))(struct bd_addr *bdaddr,u8 reason);
159+
void BTE_SetHostSyncButtonCallback(void (*callback)(u32 held));
160+
void BTE_SetConnectionRequestCallback(s8 (*callback)(void *arg,struct bd_addr *bdaddr,u8 *cod,u8 link_type));
161+
void BTE_SetLinkKeyRequestCallback(s8 (*callback)(void *arg,struct bd_addr *bdaddr));
162+
void BTE_SetLinkKeyNotificationCallback(s8 (*callback)(void *arg,struct bd_addr *bdaddr,u8 *key));
163+
u8 BTE_GetPairMode(void);
164+
s32 BTE_WriteStoredLinkKey(struct bd_addr *bdaddr,u8 *key);
165+
s32 BTE_ClearStoredLinkKeys(void);
166+
s32 BTE_DeleteStoredLinkKey(struct bd_addr *bdaddr);
129167

130168
struct bte_pcb* bte_new(void);
169+
void bte_free(struct bte_pcb *pcb);
131170
void bte_arg(struct bte_pcb *pcb,void *arg);
132171
void bte_received(struct bte_pcb *pcb, s32 (*recv)(void *arg,void *buffer,u16 len));
133172
void bte_disconnected(struct bte_pcb *pcb,s32 (disconn_cfm)(void *arg,struct bte_pcb *pcb,u8 err));
134173

135-
s32 bte_registerdeviceasync(struct bte_pcb *pcb,struct bd_addr *bdaddr,s32 (*conn_cfm)(void *arg,struct bte_pcb *pcb,u8 err));
136-
137174
s32 bte_disconnect(struct bte_pcb *pcb);
138175

139-
//s32 bte_listen(struct bte_pcb *pcb,struct bd_addr *bdaddr,u8 psm);
140-
//s32 bte_accept(struct bte_pcb *pcb,s32 (*recv)(void *arg,void *buffer,u16 len));
141-
s32 bte_inquiry(struct inquiry_info *info,u8 max_cnt,u8 flush);
142-
s32 bte_inquiry_ex(struct inquiry_info_ex *info,u8 max_cnt,u8 flush);
143-
//s32 bte_connect(struct bte_pcb *pcb,struct bd_addr *bdaddr,u8 psm,s32 (*recv)(void *arg,void *buffer,u16 len));
144-
//s32 bte_connect_ex(struct bte_pcb *pcb,struct inquiry_info_ex *info,u8 psm,s32 (*recv)(void *arg,void *buffer,u16 len));
176+
s32 bte_listenasync(struct bte_pcb *pcb,struct bd_addr *bdaddr,s32 (*conn_cfm)(void *arg,struct bte_pcb *pcb,u8 err));
177+
s32 bte_listenasync_step2(struct bte_pcb *pcb,s32 (*conn_cfm)(void *arg,struct bte_pcb *pcb,u8 err));
178+
s32 bte_connectasync(struct bte_pcb *pcb,struct bd_addr *bdaddr,s32 (*conn_cfm)(void *arg,struct bte_pcb *pcb,u8 err));
179+
s32 bte_connectasync_step2(struct bte_pcb *pcb,s32 (*conn_cfm)(void *arg,struct bte_pcb *pcb,u8 err));
145180
s32 bte_senddata(struct bte_pcb *pcb,void *message,u16 len);
146181
s32 bte_sendmessage(struct bte_pcb *pcb,void *message,u16 len);
147182
s32 bte_sendmessageasync(struct bte_pcb *pcb,void *message,u16 len,s32 (*sent)(void *arg,struct bte_pcb *pcb,u8 err));
148183

149184
#ifdef __cplusplus
150-
}
185+
}
151186
#endif /* __cplusplus */
152187

153188
#endif

gc/ogc/conf.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,8 @@ enum {
128128

129129
#define CONF_PAD_MAX_REGISTERED 10
130130
#define CONF_PAD_MAX_ACTIVE 4
131+
#define CONF_PAD_ACTIVE_AND_OTHER (CONF_PAD_MAX_ACTIVE + 2)
132+
#define CONF_PAD_TOTAL (CONF_PAD_MAX_REGISTERED + CONF_PAD_ACTIVE_AND_OTHER)
131133

132134
typedef struct _conf_pad_device conf_pad_device;
133135

@@ -146,7 +148,24 @@ struct _conf_pads {
146148
conf_pad_device unknown;
147149
} ATTRIBUTE_PACKED;
148150

151+
typedef struct _conf_pad_guest_device conf_pad_guest_device;
152+
153+
struct _conf_pad_guest_device {
154+
u8 bdaddr[6];
155+
char name[0x40];
156+
u8 link_key[16];
157+
} ATTRIBUTE_PACKED;
158+
159+
typedef struct _conf_pad_guests conf_pad_guests;
160+
161+
struct _conf_pad_guests {
162+
u8 num_guests;
163+
conf_pad_guest_device guests[CONF_PAD_MAX_ACTIVE];
164+
conf_pad_guest_device unknown[2]; // Balance Board can't be set as guest...
165+
} ATTRIBUTE_PACKED;
166+
149167
s32 CONF_Init(void);
168+
s32 CONF_SaveChanges(void);
150169
s32 CONF_GetLength(const char *name);
151170
s32 CONF_GetType(const char *name);
152171
s32 CONF_Get(const char *name, void *buffer, u32 length);
@@ -164,6 +183,9 @@ s32 CONF_GetCounterBias(u32 *bias);
164183
s32 CONF_GetScreenSaverMode(void);
165184
s32 CONF_GetDisplayOffsetH(s8 *offset);
166185
s32 CONF_GetPadDevices(conf_pads *pads);
186+
s32 CONF_SetPadDevices(const conf_pads *pads);
187+
s32 CONF_GetPadGuestDevices(conf_pad_guests *pads);
188+
s32 CONF_SetPadGuestDevices(const conf_pad_guests *pads);
167189
s32 CONF_GetNickName(u8 *nickname);
168190
s32 CONF_GetAspectRatio(void);
169191
s32 CONF_GetEULA(void);

gc/ogc/system.h

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -288,7 +288,7 @@ void SYS_ResetPMC(void);
288288
\brief Create/initialize sysalarm structure
289289
\param[in] thealarm pointer to the handle to store the created alarm context identifier
290290
291-
\return 0 on succuess, non-zero on error
291+
\return 0 on success, non-zero on error
292292
*/
293293
s32 SYS_CreateAlarm(syswd_t *thealarm);
294294

@@ -299,19 +299,19 @@ s32 SYS_CreateAlarm(syswd_t *thealarm);
299299
\param[in] tp pointer to timespec structure holding the time to fire the alarm
300300
\param[in] cb pointer to callback which is called when the alarm fires.
301301
302-
\return 0 on succuess, non-zero on error
302+
\return 0 on success, non-zero on error
303303
*/
304304
s32 SYS_SetAlarm(syswd_t thealarm,const struct timespec *tp,alarmcallback cb,void *cbarg);
305305

306306

307307
/*! \fn s32 SYS_SetPeriodicAlarm(syswd_t thealarm,const struct timespec *tp_start,const struct timespec *tp_period,alarmcallback cb)
308308
\brief Set the alarm parameters for a periodioc alarm, add to the list of alarms and start. The alarm and interval persists as long as SYS_CancelAlarm() isn't called.
309309
\param[in] thealarm identifier to the alarm context to be initialized for a periodic alarm
310-
\param[in] tp_start pointer to timespec structure holding the time to fire first time the alarm
310+
\param[in] tp_start pointer to timespec structure holding the time to fire the alarm for first time
311311
\param[in] tp_period pointer to timespec structure holding the interval for all following alarm triggers.
312312
\param[in] cb pointer to callback which is called when the alarm fires.
313313
314-
\return 0 on succuess, non-zero on error
314+
\return 0 on success, non-zero on error
315315
*/
316316
s32 SYS_SetPeriodicAlarm(syswd_t thealarm,const struct timespec *tp_start,const struct timespec *tp_period,alarmcallback cb,void *cbarg);
317317

@@ -320,15 +320,15 @@ s32 SYS_SetPeriodicAlarm(syswd_t thealarm,const struct timespec *tp_start,const
320320
\brief Remove the given alarm context from the list of contexts and destroy it
321321
\param[in] thealarm identifier to the alarm context to be removed and destroyed
322322
323-
\return 0 on succuess, non-zero on error
323+
\return 0 on success, non-zero on error
324324
*/
325325
s32 SYS_RemoveAlarm(syswd_t thealarm);
326326

327327
/*! \fn s32 SYS_CancelAlarm(syswd_t thealarm)
328328
\brief Cancel the alarm, but do not remove from the list of contexts.
329-
\param[in] thealarm identifier to the alram context to be canceled
329+
\param[in] thealarm identifier to the alarm context to be cancelled
330330
331-
\return 0 on succuess, non-zero on error
331+
\return 0 on success, non-zero on error
332332
*/
333333
s32 SYS_CancelAlarm(syswd_t thealarm);
334334

@@ -393,6 +393,7 @@ void* SYS_GetArena2Hi(void);
393393
void SYS_SetArena2Hi(void *newHi);
394394
u32 SYS_GetArena2Size(void);
395395
powercallback SYS_SetPowerCallback(powercallback cb);
396+
void SYS_DoPowerCB(void);
396397
#endif
397398

398399
/* \fn u64 SYS_Time(void)

gc/wiiuse/wiiuse.h

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,8 @@ typedef enum cmd_blk_s
242242
{
243243
CMD_READY = 0,
244244
CMD_SENT,
245-
CMD_DONE
245+
CMD_DONE,
246+
CMD_FAILED
246247
} cmd_blk_s;
247248

248249
struct cmd_blk_t
@@ -660,9 +661,10 @@ typedef struct wiimote_t {
660661
* @brief Wiimote listen structure.
661662
*/
662663
typedef struct wiimote_listen_t {
664+
WCONST u8 name[0x40];
663665
WCONST struct bd_addr bdaddr;
664666
WCONST struct bte_pcb *sock;
665-
WCONST struct wiimote_t *(*assign_cb)(struct bd_addr *bdaddr);
667+
WCONST struct wiimote_t *(*assign_cb)(struct wiimote_listen_t *wml, u8 err);
666668
WCONST struct wiimote_t *wm;
667669
} wiimote_listen;
668670
#endif
@@ -697,7 +699,8 @@ WIIUSE_EXPORT extern const char* wiiuse_version();
697699
#ifndef GEKKO
698700
WIIUSE_EXPORT extern struct wiimote_t** wiiuse_init(int wiimotes);
699701
#else
700-
WIIUSE_EXPORT extern int wiiuse_register(struct wiimote_listen_t *wml, struct bd_addr *bdaddr, struct wiimote_t *(*assign_cb)(struct bd_addr *bdaddr));
702+
WIIUSE_EXPORT extern int wiiuse_accept(struct wiimote_listen_t *wml, struct bd_addr *bdaddr, u8 *name, struct wiimote_t *(*assign_cb)(wiimote_listen *wml, u8 err));
703+
WIIUSE_EXPORT extern int wiiuse_connect(struct wiimote_listen_t *wml, struct bd_addr *bdaddr, u8 *name, struct wiimote_t *(*assign_cb)(wiimote_listen *wml, u8 err));
701704
WIIUSE_EXPORT extern struct wiimote_t** wiiuse_init(int wiimotes, wii_event_cb event_cb);
702705
WIIUSE_EXPORT extern void wiiuse_sensorbar_enable(int enable);
703706
#endif
@@ -721,7 +724,6 @@ WIIUSE_EXPORT extern int wiiuse_write_streamdata(struct wiimote_t *wm,ubyte *dat
721724

722725
/* connect.c */
723726
WIIUSE_EXPORT extern int wiiuse_find(struct wiimote_t** wm, int max_wiimotes, int timeout);
724-
WIIUSE_EXPORT extern int wiiuse_connect(struct wiimote_t** wm, int wiimotes);
725727
WIIUSE_EXPORT extern void wiiuse_disconnect(struct wiimote_t* wm);
726728

727729
/* events.c */

gc/wiiuse/wpad.h

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,12 @@ enum {
4343
WPAD_CHAN_2,
4444
WPAD_CHAN_3,
4545
WPAD_BALANCE_BOARD,
46-
WPAD_MAX_WIIMOTES,
46+
WPAD_CHAN_UNKNOWN,
47+
WPAD_MAX_DEVICES,
4748
};
49+
50+
// Compatibility with old apps
51+
#define WPAD_MAX_WIIMOTES WPAD_MAX_DEVICES
4852

4953
#define WPAD_BUTTON_2 0x0001
5054
#define WPAD_BUTTON_1 0x0002
@@ -136,6 +140,14 @@ enum {
136140
#define WPAD_THRESH_DEFAULT_BALANCEBOARD 60
137141
#define WPAD_THRESH_DEFAULT_MOTION_PLUS 100
138142

143+
#define WPAD_DISCON_AUTH_FAILURE 0x05 /* HCI_AUTHENTICATION_FAILURE */
144+
#define WPAD_DISCON_TIMEOUT 0x08 /* HCI_CONN_TIMEOUT */
145+
#define WPAD_DISCON_SYNC_PRESSED 0x13 /* HCI_OTHER_END_TERMINATED_CONN_USER_ENDED */
146+
#define WPAD_DISCON_BATTERY_DIED 0x14 /* HCI_OTHER_END_TERMINATED_CONN_LOW_RESOURCES */
147+
#define WPAD_DISCON_POWER_OFF 0x15 /* HCI_OTHER_END_TERMINATED_CONN_ABOUT_TO_POWER_OFF */
148+
#define WPAD_DISCON_IDLE_TIMEOUT 0x16 /* HCI_CONN_TERMINATED_BY_LOCAL_HOST */
149+
#define WPAD_DISCON_REPEATED_ATTEMPTS 0x17 /* HCI_REPEATED_ATTEMPTS */
150+
139151
#ifdef __cplusplus
140152
extern "C" {
141153
#endif /* __cplusplus */
@@ -166,6 +178,9 @@ typedef struct _wpad_encstatus
166178

167179
typedef void (*WPADDataCallback)(s32 chan, const WPADData *data);
168180
typedef void (*WPADShutdownCallback)(s32 chan);
181+
typedef void (*WPADDisconnectCallback)(s32 chan, u8 reason);
182+
typedef void (*WPADStatusCallback)(s32 chan);
183+
typedef void (*WPADHostSyncBtnCallback)(u32 held);
169184

170185
s32 WPAD_Init(void);
171186
s32 WPAD_ControlSpeaker(s32 chan,s32 enable);
@@ -182,10 +197,17 @@ s32 WPAD_SetEventBufs(s32 chan, WPADData *bufs, u32 cnt);
182197
s32 WPAD_Disconnect(s32 chan);
183198
s32 WPAD_IsSpeakerEnabled(s32 chan);
184199
s32 WPAD_SendStreamData(s32 chan,void *buf,u32 len);
185-
void WPAD_Shutdown(void);
200+
s32 WPAD_Search(void);
201+
s32 WPAD_StopSearch(void);
202+
s32 WPAD_StartPairing(void);
203+
s32 WPAD_WipeSavedControllers(void);
204+
s32 WPAD_Shutdown(void);
186205
void WPAD_SetIdleTimeout(u32 seconds);
187206
void WPAD_SetPowerButtonCallback(WPADShutdownCallback cb);
188207
void WPAD_SetBatteryDeadCallback(WPADShutdownCallback cb);
208+
void WPAD_SetDisconnectCallback(WPADDisconnectCallback cb);
209+
void WPAD_SetHostSyncButtonCallback(WPADHostSyncBtnCallback cb);
210+
void WPAD_SetStatusCallback(WPADStatusCallback cb);
189211
s32 WPAD_ScanPads(void);
190212
s32 WPAD_Rumble(s32 chan, int status);
191213
s32 WPAD_SetIdleThresholds(s32 chan, s32 btns, s32 ir, s32 accel, s32 js, s32 wb, s32 mp);
@@ -200,6 +222,8 @@ void WPAD_Orientation(int chan, struct orient_t *orient);
200222
void WPAD_GForce(int chan, struct gforce_t *gforce);
201223
void WPAD_Accel(int chan, struct vec3w_t *accel);
202224
void WPAD_Expansion(int chan, struct expansion_t *exp);
225+
void WPAD_PadStatus(int chan);
226+
bool WPAD_IsBatteryCritical(int chan);
203227

204228
#ifdef __cplusplus
205229
}

0 commit comments

Comments
 (0)