From WiiBrew
< /dev‎ | net‎ | wd
Jump to navigation Jump to search

This device in the wd driver is responsible for managing configuration of the driver, probably mostly to handle communications with the Nintendo DS (e.g. downloading demos).

Ioctl Inputs Outputs Function
0x1001 0 0 WD_GetState
0x1002 1 0 WD_SetLinkState
0x1003 0 0 WD_GetStatus
0x1004 3 0 WD_SetConfig
0x1005 3 0 WD_GetConfig
0x1006 2 0 WD_SendBeacon
0x1007 1 0 ?
0x1008 2 0 WD_SendWMBData
0x1009 1 0 send frame?
0x100A 1 1 WD_Scan
0x100B ? ? ?
0x100C ? ? switch to raw mode?
0x100D 0 1 WD_GetWLStatus
0x100E 0 1 (0x90 bytes) GetInfo ?
0x100F 1 0 WD_SetBeacon
0x1010 1 0 ?
0x8000 0 1 ? someting with WDi_AcceptReceiveRequest
0x8001 0 1 ? someting with WDi_AcceptReceiveRequest

WD_Scan input buffer:

typedef struct _wd_scanparam//size 0x60 bytes
	u16 channelBitmap;
	u16 maxChannelTime;
	u16 unk4;
	u16 unk6;
	u16 unk8;
	u16 scanType;//only 0/1 permitted.
	u16 ssidLength;
	char ssid[32];//?
       u8 unk[32];
} wd_scanparam;

s32 WD_SetConfig(wd_config *config, u32 flags1, u32 flags0); flags0 | flags1 must be non-zero. Each bit in the flags corresponds to a field or struct in config. The associated bits and fields/structs are listed in the below wd_config struct. If clear, nothing is done for that field/struct, otherwise the field/struct may be verified; not all are verified. All bits and their associated fields/structs are verified,(if they have verification code) before updating the internal configuration. WD_GetConfig is similar to WD_SetConfig, except the configuration from the internal config is copied to the input wd_config structure based on the flags.

WD_GetState always returns a value less than 7 and greater than 1. WD_GetState should always return state 3, any other states are illegal states. Frames can't be sent with ioctl 0x1009 in illegal states. WD_GetStatus returns 0 or 1, depending on different flags for each state. For state 3, this returns 0 when wireless is disabled, 1 when enabled. Ioctl 0x1009 input is a buffer/len pair.

WD_SendBeacon second input is the Nintendo tag code 0xDD data, starting after the timestamp. First input might be a u16* for the Nintendo tag timestamp?

WD_SetLinkState might change which "mode"/"state" is used; 0 for Infrastructure, 1 for master mode?

WD_SendWMBData first input buffer is the WMB data to send. In the frame, this is copied to the offset after the 06 02 01 00 bytes. First two bytes are byte-swapped, thus flags are first, size second. Input two buffer is unknown.

WD_GetWLStatus copies the internal wd_wlstatus struct to outbuf. After WD_GetWLStatus copies the internal wlstatus struct to outbuf, the status field in the internal struct is set to zero. WD_GetWLStatus returns the internal wlstatus struct unka field.

WD_SetBeacon sets the beacon broadcasted by hw? Perhaps this is used to have hw broadcast static beacons for example in games with local wireless DS communications, and perhaps WD_SendBeacon is for protocols that require beacon data constantly changed by software such as WMB.

The state is set to the mode, upon the initial open. For Infrastructure mode, mode should be 3, while for master mode this should be 1? Initial open meaning the first open after the device is closed, or after a IOS_Reload, without net_init being called.

Configuration, info, and wd_sendwmbdata_param structs:

//wd_privacy and wd_config fields are big-endian, but they are byte swapped when checking the values and copying to/from internal config.
typedef struct _wd_privacy//When verified, only the mode and keyId/keyLen are verified. Size 72 bytes.
	u16 mode;//0 = None, 1 = WEP40, 2 = WEP104, 3 = invalid mode, 4 = WPA-PSK(TKIP), 5 = WPA2-PSK(AES), 6 = WPA-PSK(AES)
	u16 unk;

	union//mode and keyId/keyLen are verified when flags0 bit 20 is set.
		//mode 0 is none.
		struct//mode 1
			u16 keyId;//Must be less than 4.

		struct//mode 2
			u16 keyId;//Must be less than 4.

		//mode 3 is an invalid mode.
		struct//mode 5/6
			u16 keyLen;//Must be in range 8-64.

		struct//mode 4
			u16 keyLen;//Must be in range 8-64.

	u8 unkpriva1[66];
} wd_privacy;

typedef struct _wd_config//size 384 bytes.
	u16 diversityMode;//flags0 bit 0. Antenna diversity. Can't be greater than 1. Debug for 0: "OFF, use a antenna MAIN", debug for 1: "OFF, use a antenna SUB".
	u16 useAntenna;//flags0 bit 1. Must be less than 2; 0 or 1.
	u16 shortRetryLimit;//flags0 bit 2. Must be no larger than 255.
	u16 longRetryLimit;//flags0 bit 3. Must be no larger than 255.
	u16 unk4;//flags0 bit 4.
	u16 rtsThreshold;//flags0 bit 5. Must be greater than 0.
	u16 fragThreshold;//flags0 bit 6. Must be greater than 0.
	u16 supportRateSet;//flags0 bit 7. First 20 bits must not be all zero.
	u16 basicRateSet;//flags0 bit 8. First 20 bits must not be all zero.
	u16 enable_channel;//? flags0 bit 9. Current channel?

	        wd_privacy essSta_privacy;//flags0 bit 20.

	        char ssid[32];//? flags0 bit 16.
	        u8 unka2[32];//flags0 bit 17.
	        u8 ssidLength;//flags0 bit 18. must be less than 33.
	        u8 unka;//flags0 bit 21, not checked.
	        u16 maxChannelTime;//flags0 bit 19. Must not be less than 1000.
	        u8 bssid[6];//?
	        u8 somemac[6];//?
        } essSta;//Infrastructure?

	        u16 connectionTimeout;//flags 1 fields start here. Must be larger than 0.
	        u16 beaconPeriod;//Must be greater than 1000.
	        u8 maxNodes;//Must be less than 16.
	        u8 authAlgorithm;//Must be less than 2. 0 = Open, 1 = Shared.
	        u16 beacon_nintagtimestamp;//? bit 4 of flags 1 fields.
	        u8 channel;//Not verified if 0, but when non-zero, must be an available Nitro Allowed Channel. See _wd_info.ntr_allowed_channels.
	        u8 unka4[3];
		u8 beacon_nintagdata[128];
              wd_privacy mpParent_privacy;//Mode 3, tkip, and aes crypto modes are removed, leaving only modes none, WEP40, and WEP104.
        } mpParent;//Master mode?
} wd_config;

typedef struct _wd_info
        u8 mac[6];
        u16 ntr_allowed_channels;//Bit 0 is unused. Bit 1 means channel 1 is available, and so on.
        u16 unk8;
        char country[2];//Text country code.
        u32 unkc;
        char wlversion[0x50];//IOSVersion tag from WL.
        u8 unk[0x30];
} wd_info;

typedef struct _wd_sendwmbdata_param
	u16 unk0;
	u16 unk2;
	u16 unk4;
	u16 unk6;
	u16 unk8;
	u16 unka;
	u16 unkc;
} wd_sendwmbdata_param;

typedef struct _wd_wlstatus
        u32 status;//When a WL error occurs, 1 is written here. After WD_GetWLStatus copies the internal wlstatus struct to outbuf, this field in the internal struct is set to zero.
        u32 num;//Number of errors? Internal struct num field is incremented when WL errors occur.
        u16 unk8;
        u16 unka;
} wd_wlstatus;

WD Errors

Error code POSIX equivalent Notes
-0x8000 ? Invalid fd
-0x8001 EINVAL Invalid input
-0x8002 ? Invalid state or invalid ioctl number
-0x8003 ? WL error
-0x8005 ENOMEM Memory allocation error