Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
2b918cd
Add remote syncing
Zarithya Mar 16, 2025
60df481
Async
Zarithya Mar 18, 2025
b1b84fd
Almost finished replicating Wii menu pairing functionality
Zarithya Mar 19, 2025
ccfe267
Final pairing implementation (cleanup WIP)
Zarithya Mar 25, 2025
e096919
Cleanup
Zarithya Mar 26, 2025
d0d0191
Fix some race conditions
Zarithya Apr 2, 2025
57f2921
Stop sharing sockets!
Zarithya Apr 2, 2025
3cb9d09
Properly wait for USB to close
Zarithya Apr 2, 2025
4d5665a
Remove listen PCB when opening new connection
Zarithya Apr 2, 2025
56bda29
Correctly free socket on wiimote disconnect
Zarithya May 7, 2025
eea5f61
Start making it act like SM
Zarithya May 8, 2025
86704a6
TRs work
Zarithya May 24, 2025
7e34671
Reconnect after pair works
Zarithya May 24, 2025
545eeeb
TRs can reconnect after pairing
Zarithya May 28, 2025
4406038
Fix balance board
Zarithya Jun 2, 2025
caedcc1
Begin final cleanup
Zarithya Jun 9, 2025
aa35f0e
Guest mode pairing works
Zarithya Jun 10, 2025
46a5496
Continue cleanup
Zarithya Jun 10, 2025
ad5b3d7
Cleanup from review
Zarithya Jun 13, 2025
6fed5dc
Move bte_free calls to more logical places
Zarithya Jun 14, 2025
2322b93
General disconnect CB
Zarithya Jun 17, 2025
b7cd820
Clear critical battery state on disconnect
Zarithya Jun 24, 2025
ddb380d
Clear sock on shutdown
Zarithya Jun 24, 2025
4f8f311
Cleanup
Zarithya Jun 25, 2025
d10c65b
Disambiguate front panel power button from auth'd Wiimote power button
Zarithya Aug 3, 2025
9590478
Improve power button disable/throttle code
Zarithya Aug 3, 2025
5221304
rename inquiry_res
DacoTaco Aug 8, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 20 additions & 3 deletions gc/bte/bd_addr.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,12 @@
extern "C" {
#endif /* __cplusplus */

#define BD_ADDR_LEN 6

struct bd_addr {
u8 addr[6];
u8 addr[BD_ADDR_LEN];
};

#define BD_ADDR_LEN 6

#define BD_ADDR_ANY (&(struct bd_addr){{0,0,0,0,0,0}})
#define BD_ADDR_LOCAL (&(struct bd_addr){{0,0,0,0xff,0xff,0xff}})

Expand All @@ -55,6 +55,23 @@ struct bd_addr {
(bdaddr)->addr[3] = d; \
(bdaddr)->addr[4] = e; \
(bdaddr)->addr[5] = f; }while(0)

#define BD_ADDR_FROM_BYTES(bdaddr, bytes) do{ \
(bdaddr)->addr[0] = bytes[5]; \
(bdaddr)->addr[1] = bytes[4]; \
(bdaddr)->addr[2] = bytes[3]; \
(bdaddr)->addr[3] = bytes[2]; \
(bdaddr)->addr[4] = bytes[1]; \
(bdaddr)->addr[5] = bytes[0]; }while(0)

#define BYTES_FROM_BD_ADDR(bytes, bdaddr) do{ \
bytes[0] = (bdaddr)->addr[5]; \
bytes[1] = (bdaddr)->addr[4]; \
bytes[2] = (bdaddr)->addr[3]; \
bytes[3] = (bdaddr)->addr[2]; \
bytes[4] = (bdaddr)->addr[1]; \
bytes[5] = (bdaddr)->addr[0]; }while(0)

//TODO: USE memcmp????
#define bd_addr_cmp(addr1, addr2) (((addr1)->addr[0] == (addr2)->addr[0]) && \
((addr1)->addr[1] == (addr2)->addr[1]) && \
Expand Down
69 changes: 52 additions & 17 deletions gc/bte/bte.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,18 +56,27 @@
#define HIDP_CTRL_VC_UNPLUG 0x05

/* HIDP data transaction headers */
#define HIDP_DATA_RTYPE_MASK 0x03
#define HIDP_DATA_RSRVD_MASK 0x0c
#define HIDP_DATA_RTYPE_OTHER 0x00
#define HIDP_DATA_RTYPE_INPUT 0x01
#define HIDP_DATA_RTYPE_OUPUT 0x02
#define HIDP_DATA_RTYPE_FEATURE 0x03
#define HIDP_DATA_RTYPE_MASK 0x03
#define HIDP_DATA_RSRVD_MASK 0x0c
#define HIDP_DATA_RTYPE_OTHER 0x00
#define HIDP_DATA_RTYPE_INPUT 0x01
#define HIDP_DATA_RTYPE_OUPUT 0x02
#define HIDP_DATA_RTYPE_FEATURE 0x03

#define HIDP_PROTO_BOOT 0x00
#define HIDP_PROTO_REPORT 0x01

#define BD_LINK_KEY_LEN 16
#define BD_NAME_LEN 248
#define BD_MAX_INQUIRY_DEVS 255

enum pair_mode {
PAIR_MODE_NORMAL,
PAIR_MODE_TEMPORARY
};

#ifdef __cplusplus
extern "C" {
extern "C" {
#endif /* __cplusplus */

struct l2cap_pcb;
Expand All @@ -88,10 +97,22 @@ struct inquiry_info_ex
u16 co;
};

struct bte_inquiry_res
{
u8 count;
struct inquiry_info_ex *info;
};

struct linkkey_info
{
struct bd_addr bdaddr;
u8 key[16];
u8 key[BD_LINK_KEY_LEN];
};

struct pad_name_info
{
struct bd_addr bdaddr;
u8 name[BD_NAME_LEN];
};

struct bte_pcb
Expand All @@ -112,6 +133,7 @@ struct bte_pcb


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

void BTE_Init(void);
void BTE_Shutdown(void);
void BTE_Close(void);
s32 BTE_InitCore(btecallback cb);
s32 BTE_ApplyPatch(btecallback cb);
s32 BTE_InitSub(btecallback cb);
s32 BTE_ReadStoredLinkKey(struct linkkey_info *keys,u8 max_cnt,btecallback cb);
s32 BTE_ReadBdAddr(struct bd_addr *bdaddr, btecallback cb);
s32 BTE_SetEvtFilter(u8 filter_type,u8 filter_cond_type,u8 *cond, btecallback cb);
s32 BTE_ReadRemoteName(struct pad_name_info *padinfo, btecallback cb);
s32 BTE_Inquiry(u8 max_cnt,u8 flush, btecallback cb);
s32 BTE_PeriodicInquiry(u8 max_cnt,u8 flush,btecallback cb);
s32 BTE_ExitPeriodicInquiry(void);
s32 BTE_LinkKeyRequestReply(struct bd_addr *bdaddr,u8 *key);
s32 BTE_LinkKeyRequestNegativeReply(struct bd_addr *bdaddr);
void (*BTE_SetDisconnectCallback(void (*callback)(struct bd_addr *bdaddr,u8 reason)))(struct bd_addr *bdaddr,u8 reason);
void BTE_SetHostSyncButtonCallback(void (*callback)(u32 held));
void BTE_SetConnectionRequestCallback(s8 (*callback)(void *arg,struct bd_addr *bdaddr,u8 *cod,u8 link_type));
void BTE_SetLinkKeyRequestCallback(s8 (*callback)(void *arg,struct bd_addr *bdaddr));
void BTE_SetLinkKeyNotificationCallback(s8 (*callback)(void *arg,struct bd_addr *bdaddr,u8 *key));
u8 BTE_GetPairMode(void);
s32 BTE_WriteStoredLinkKey(struct bd_addr *bdaddr,u8 *key);
s32 BTE_ClearStoredLinkKeys(void);
s32 BTE_DeleteStoredLinkKey(struct bd_addr *bdaddr);

struct bte_pcb* bte_new(void);
void bte_free(struct bte_pcb *pcb);
void bte_arg(struct bte_pcb *pcb,void *arg);
void bte_received(struct bte_pcb *pcb, s32 (*recv)(void *arg,void *buffer,u16 len));
void bte_disconnected(struct bte_pcb *pcb,s32 (disconn_cfm)(void *arg,struct bte_pcb *pcb,u8 err));

s32 bte_registerdeviceasync(struct bte_pcb *pcb,struct bd_addr *bdaddr,s32 (*conn_cfm)(void *arg,struct bte_pcb *pcb,u8 err));

s32 bte_disconnect(struct bte_pcb *pcb);

//s32 bte_listen(struct bte_pcb *pcb,struct bd_addr *bdaddr,u8 psm);
//s32 bte_accept(struct bte_pcb *pcb,s32 (*recv)(void *arg,void *buffer,u16 len));
s32 bte_inquiry(struct inquiry_info *info,u8 max_cnt,u8 flush);
s32 bte_inquiry_ex(struct inquiry_info_ex *info,u8 max_cnt,u8 flush);
//s32 bte_connect(struct bte_pcb *pcb,struct bd_addr *bdaddr,u8 psm,s32 (*recv)(void *arg,void *buffer,u16 len));
//s32 bte_connect_ex(struct bte_pcb *pcb,struct inquiry_info_ex *info,u8 psm,s32 (*recv)(void *arg,void *buffer,u16 len));
s32 bte_listenasync(struct bte_pcb *pcb,struct bd_addr *bdaddr,s32 (*conn_cfm)(void *arg,struct bte_pcb *pcb,u8 err));
s32 bte_listenasync_step2(struct bte_pcb *pcb,s32 (*conn_cfm)(void *arg,struct bte_pcb *pcb,u8 err));
s32 bte_connectasync(struct bte_pcb *pcb,struct bd_addr *bdaddr,s32 (*conn_cfm)(void *arg,struct bte_pcb *pcb,u8 err));
s32 bte_connectasync_step2(struct bte_pcb *pcb,s32 (*conn_cfm)(void *arg,struct bte_pcb *pcb,u8 err));
s32 bte_senddata(struct bte_pcb *pcb,void *message,u16 len);
s32 bte_sendmessage(struct bte_pcb *pcb,void *message,u16 len);
s32 bte_sendmessageasync(struct bte_pcb *pcb,void *message,u16 len,s32 (*sent)(void *arg,struct bte_pcb *pcb,u8 err));

#ifdef __cplusplus
}
}
#endif /* __cplusplus */

#endif
Expand Down
22 changes: 22 additions & 0 deletions gc/ogc/conf.h
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,8 @@ enum {

#define CONF_PAD_MAX_REGISTERED 10
#define CONF_PAD_MAX_ACTIVE 4
#define CONF_PAD_ACTIVE_AND_OTHER (CONF_PAD_MAX_ACTIVE + 2)
#define CONF_PAD_TOTAL (CONF_PAD_MAX_REGISTERED + CONF_PAD_ACTIVE_AND_OTHER)

typedef struct _conf_pad_device conf_pad_device;

Expand All @@ -146,7 +148,24 @@ struct _conf_pads {
conf_pad_device unknown;
} ATTRIBUTE_PACKED;

typedef struct _conf_pad_guest_device conf_pad_guest_device;

struct _conf_pad_guest_device {
u8 bdaddr[6];
char name[0x40];
u8 link_key[16];
} ATTRIBUTE_PACKED;

typedef struct _conf_pad_guests conf_pad_guests;

struct _conf_pad_guests {
u8 num_guests;
conf_pad_guest_device guests[CONF_PAD_MAX_ACTIVE];
conf_pad_guest_device unknown[2]; // Balance Board can't be set as guest...
} ATTRIBUTE_PACKED;

s32 CONF_Init(void);
s32 CONF_SaveChanges(void);
s32 CONF_GetLength(const char *name);
s32 CONF_GetType(const char *name);
s32 CONF_Get(const char *name, void *buffer, u32 length);
Expand All @@ -164,6 +183,9 @@ s32 CONF_GetCounterBias(u32 *bias);
s32 CONF_GetScreenSaverMode(void);
s32 CONF_GetDisplayOffsetH(s8 *offset);
s32 CONF_GetPadDevices(conf_pads *pads);
s32 CONF_SetPadDevices(const conf_pads *pads);
s32 CONF_GetPadGuestDevices(conf_pad_guests *pads);
s32 CONF_SetPadGuestDevices(const conf_pad_guests *pads);
s32 CONF_GetNickName(u8 *nickname);
s32 CONF_GetAspectRatio(void);
s32 CONF_GetEULA(void);
Expand Down
15 changes: 8 additions & 7 deletions gc/ogc/system.h
Original file line number Diff line number Diff line change
Expand Up @@ -286,7 +286,7 @@ void SYS_ResetPMC(void);
\brief Create/initialize sysalarm structure
\param[in] thealarm pointer to the handle to store the created alarm context identifier

\return 0 on succuess, non-zero on error
\return 0 on success, non-zero on error
*/
s32 SYS_CreateAlarm(syswd_t *thealarm);

Expand All @@ -297,19 +297,19 @@ s32 SYS_CreateAlarm(syswd_t *thealarm);
\param[in] tp pointer to timespec structure holding the time to fire the alarm
\param[in] cb pointer to callback which is called when the alarm fires.

\return 0 on succuess, non-zero on error
\return 0 on success, non-zero on error
*/
s32 SYS_SetAlarm(syswd_t thealarm,const struct timespec *tp,alarmcallback cb,void *cbarg);


/*! \fn s32 SYS_SetPeriodicAlarm(syswd_t thealarm,const struct timespec *tp_start,const struct timespec *tp_period,alarmcallback cb)
\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.
\param[in] thealarm identifier to the alarm context to be initialized for a periodic alarm
\param[in] tp_start pointer to timespec structure holding the time to fire first time the alarm
\param[in] tp_start pointer to timespec structure holding the time to fire the alarm for first time
\param[in] tp_period pointer to timespec structure holding the interval for all following alarm triggers.
\param[in] cb pointer to callback which is called when the alarm fires.

\return 0 on succuess, non-zero on error
\return 0 on success, non-zero on error
*/
s32 SYS_SetPeriodicAlarm(syswd_t thealarm,const struct timespec *tp_start,const struct timespec *tp_period,alarmcallback cb,void *cbarg);

Expand All @@ -318,15 +318,15 @@ s32 SYS_SetPeriodicAlarm(syswd_t thealarm,const struct timespec *tp_start,const
\brief Remove the given alarm context from the list of contexts and destroy it
\param[in] thealarm identifier to the alarm context to be removed and destroyed

\return 0 on succuess, non-zero on error
\return 0 on success, non-zero on error
*/
s32 SYS_RemoveAlarm(syswd_t thealarm);

/*! \fn s32 SYS_CancelAlarm(syswd_t thealarm)
\brief Cancel the alarm, but do not remove from the list of contexts.
\param[in] thealarm identifier to the alram context to be canceled
\param[in] thealarm identifier to the alarm context to be cancelled

\return 0 on succuess, non-zero on error
\return 0 on success, non-zero on error
*/
s32 SYS_CancelAlarm(syswd_t thealarm);

Expand Down Expand Up @@ -391,6 +391,7 @@ void* SYS_GetArena2Hi(void);
void SYS_SetArena2Hi(void *newHi);
u32 SYS_GetArena2Size(void);
powercallback SYS_SetPowerCallback(powercallback cb);
void SYS_DoPowerCB(void);
#endif

/* \fn u64 SYS_Time(void)
Expand Down
10 changes: 6 additions & 4 deletions gc/wiiuse/wiiuse.h
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,8 @@ typedef enum cmd_blk_s
{
CMD_READY = 0,
CMD_SENT,
CMD_DONE
CMD_DONE,
CMD_FAILED
} cmd_blk_s;

struct cmd_blk_t
Expand Down Expand Up @@ -660,9 +661,10 @@ typedef struct wiimote_t {
* @brief Wiimote listen structure.
*/
typedef struct wiimote_listen_t {
WCONST u8 name[0x40];
WCONST struct bd_addr bdaddr;
WCONST struct bte_pcb *sock;
WCONST struct wiimote_t *(*assign_cb)(struct bd_addr *bdaddr);
WCONST struct wiimote_t *(*assign_cb)(struct wiimote_listen_t *wml, u8 err);
WCONST struct wiimote_t *wm;
} wiimote_listen;
#endif
Expand Down Expand Up @@ -697,7 +699,8 @@ WIIUSE_EXPORT extern const char* wiiuse_version();
#ifndef GEKKO
WIIUSE_EXPORT extern struct wiimote_t** wiiuse_init(int wiimotes);
#else
WIIUSE_EXPORT extern int wiiuse_register(struct wiimote_listen_t *wml, struct bd_addr *bdaddr, struct wiimote_t *(*assign_cb)(struct bd_addr *bdaddr));
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));
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));
WIIUSE_EXPORT extern struct wiimote_t** wiiuse_init(int wiimotes, wii_event_cb event_cb);
WIIUSE_EXPORT extern void wiiuse_sensorbar_enable(int enable);
#endif
Expand All @@ -721,7 +724,6 @@ WIIUSE_EXPORT extern int wiiuse_write_streamdata(struct wiimote_t *wm,ubyte *dat

/* connect.c */
WIIUSE_EXPORT extern int wiiuse_find(struct wiimote_t** wm, int max_wiimotes, int timeout);
WIIUSE_EXPORT extern int wiiuse_connect(struct wiimote_t** wm, int wiimotes);
WIIUSE_EXPORT extern void wiiuse_disconnect(struct wiimote_t* wm);

/* events.c */
Expand Down
28 changes: 26 additions & 2 deletions gc/wiiuse/wpad.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,12 @@ enum {
WPAD_CHAN_2,
WPAD_CHAN_3,
WPAD_BALANCE_BOARD,
WPAD_MAX_WIIMOTES,
WPAD_CHAN_UNKNOWN,
WPAD_MAX_DEVICES,
};

// Compatibility with old apps
#define WPAD_MAX_WIIMOTES WPAD_MAX_DEVICES

#define WPAD_BUTTON_2 0x0001
#define WPAD_BUTTON_1 0x0002
Expand Down Expand Up @@ -136,6 +140,14 @@ enum {
#define WPAD_THRESH_DEFAULT_BALANCEBOARD 60
#define WPAD_THRESH_DEFAULT_MOTION_PLUS 100

#define WPAD_DISCON_AUTH_FAILURE 0x05 /* HCI_AUTHENTICATION_FAILURE */
#define WPAD_DISCON_TIMEOUT 0x08 /* HCI_CONN_TIMEOUT */
#define WPAD_DISCON_SYNC_PRESSED 0x13 /* HCI_OTHER_END_TERMINATED_CONN_USER_ENDED */
#define WPAD_DISCON_BATTERY_DIED 0x14 /* HCI_OTHER_END_TERMINATED_CONN_LOW_RESOURCES */
#define WPAD_DISCON_POWER_OFF 0x15 /* HCI_OTHER_END_TERMINATED_CONN_ABOUT_TO_POWER_OFF */
#define WPAD_DISCON_IDLE_TIMEOUT 0x16 /* HCI_CONN_TERMINATED_BY_LOCAL_HOST */
#define WPAD_DISCON_REPEATED_ATTEMPTS 0x17 /* HCI_REPEATED_ATTEMPTS */

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
Expand Down Expand Up @@ -166,6 +178,9 @@ typedef struct _wpad_encstatus

typedef void (*WPADDataCallback)(s32 chan, const WPADData *data);
typedef void (*WPADShutdownCallback)(s32 chan);
typedef void (*WPADDisconnectCallback)(s32 chan, u8 reason);
typedef void (*WPADStatusCallback)(s32 chan);
typedef void (*WPADHostSyncBtnCallback)(u32 held);

s32 WPAD_Init(void);
s32 WPAD_ControlSpeaker(s32 chan,s32 enable);
Expand All @@ -182,10 +197,17 @@ s32 WPAD_SetEventBufs(s32 chan, WPADData *bufs, u32 cnt);
s32 WPAD_Disconnect(s32 chan);
s32 WPAD_IsSpeakerEnabled(s32 chan);
s32 WPAD_SendStreamData(s32 chan,void *buf,u32 len);
void WPAD_Shutdown(void);
s32 WPAD_Search(void);
s32 WPAD_StopSearch(void);
s32 WPAD_StartPairing(void);
s32 WPAD_WipeSavedControllers(void);
s32 WPAD_Shutdown(void);
void WPAD_SetIdleTimeout(u32 seconds);
void WPAD_SetPowerButtonCallback(WPADShutdownCallback cb);
void WPAD_SetBatteryDeadCallback(WPADShutdownCallback cb);
void WPAD_SetDisconnectCallback(WPADDisconnectCallback cb);
void WPAD_SetHostSyncButtonCallback(WPADHostSyncBtnCallback cb);
void WPAD_SetStatusCallback(WPADStatusCallback cb);
s32 WPAD_ScanPads(void);
s32 WPAD_Rumble(s32 chan, int status);
s32 WPAD_SetIdleThresholds(s32 chan, s32 btns, s32 ir, s32 accel, s32 js, s32 wb, s32 mp);
Expand All @@ -200,6 +222,8 @@ void WPAD_Orientation(int chan, struct orient_t *orient);
void WPAD_GForce(int chan, struct gforce_t *gforce);
void WPAD_Accel(int chan, struct vec3w_t *accel);
void WPAD_Expansion(int chan, struct expansion_t *exp);
void WPAD_PadStatus(int chan);
bool WPAD_IsBatteryCritical(int chan);

#ifdef __cplusplus
}
Expand Down
Loading