Пример #1
0
void wiiuse_handshake(struct wiimote_t* wm, byte* data, uint16_t len) {
	/* send request to wiimote for accelerometer calibration */
	byte buf[MAX_PAYLOAD];

	/* step 0 - Reset wiimote */
	{
		//wiiuse_set_leds(wm, WIIMOTE_LED_NONE);

		WIIMOTE_ENABLE_STATE(wm, WIIMOTE_STATE_HANDSHAKE);
		WIIMOTE_ENABLE_STATE(wm, WIIMOTE_STATE_CONNECTED);
		WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_ACC);
		WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_IR);
		WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_RUMBLE);
		WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_EXP);
		WIIMOTE_DISABLE_FLAG(wm, WIIUSE_CONTINUOUS);

		wiiuse_set_report_type(wm);
		wiiuse_millisleep(500);

		WIIUSE_DEBUG("Wiimote reset!\n");
	}

	/* step 1 - calibration of accelerometers */
	if(wm->type != WIIUSE_WIIMOTE_MOTION_PLUS_INSIDE)
	{
		struct accel_t* accel = &wm->accel_calib;

		wiiuse_read_data_sync(wm, 1, WM_MEM_OFFSET_CALIBRATION, 8, buf);

		/* received read data */
		accel->cal_zero.x = buf[0];
		accel->cal_zero.y = buf[1];
		accel->cal_zero.z = buf[2];

		accel->cal_g.x = buf[4] - accel->cal_zero.x;
		accel->cal_g.y = buf[5] - accel->cal_zero.y;
		accel->cal_g.z = buf[6] - accel->cal_zero.z;

		WIIUSE_DEBUG("Calibrated wiimote acc\n");
	}

	/* step 2 - re-enable IR and ask for status */
	{
		WIIMOTE_ENABLE_STATE(wm, WIIMOTE_STATE_HANDSHAKE_COMPLETE);
		WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_HANDSHAKE);

		/* now enable IR if it was set before the handshake completed */
		if (WIIMOTE_IS_SET(wm, WIIMOTE_STATE_IR)) {
			WIIUSE_DEBUG("Handshake finished, enabling IR.");
			WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_IR);
			wiiuse_set_ir(wm, 1);
		}

		WIIUSE_DEBUG("Asking for status ...\n");
		wm->event = WIIUSE_CONNECT;
		wiiuse_status(wm);
	}
}
Пример #2
0
void wiiuse_handshake_expansion(struct wiimote_t *wm,ubyte *data,uword len)
{
	int id;
	ubyte val;
	ubyte *buf = NULL;

	switch(wm->expansion_state) {
		/* These two initialization writes disable the encryption */
		case 0:
			wm->expansion_state = 1;
			val = 0x55;
			wiiuse_write_data(wm,WM_EXP_MEM_ENABLE1,&val,1,wiiuse_handshake_expansion);
			break;
		case 1:
			wm->expansion_state = 2;
			val = 0x00;
			wiiuse_write_data(wm,WM_EXP_MEM_ENABLE2,&val,1,wiiuse_handshake_expansion);
			break;
		case 2:
			wm->expansion_state = 3;
			buf = __lwp_wkspace_allocate(sizeof(ubyte)*EXP_HANDSHAKE_LEN);
			wiiuse_read_data(wm,buf,WM_EXP_MEM_CALIBR,EXP_HANDSHAKE_LEN,wiiuse_handshake_expansion);
			break;
		case 3:
			if(!data || !len) return;
			id = BIG_ENDIAN_LONG(*(int*)(&data[220]));
			switch(id) {
				case EXP_ID_CODE_NUNCHUK:
					if(!nunchuk_handshake(wm,&wm->exp.nunchuk,data,len)) return;
					break;
				case EXP_ID_CODE_CLASSIC_CONTROLLER:
					if(!classic_ctrl_handshake(wm,&wm->exp.classic,data,len)) return;
					break;
				case EXP_ID_CODE_GUITAR:
					if(!guitar_hero_3_handshake(wm,&wm->exp.gh3,data,len)) return;
					break;
				case EXP_ID_CODE_WIIBOARD:
					if(!wii_board_handshake(wm,&wm->exp.wb,data,len)) return;
					break;
				default:
					WIIMOTE_DISABLE_STATE(wm,WIIMOTE_STATE_EXP_HANDSHAKE);
					WIIMOTE_ENABLE_STATE(wm,WIIMOTE_STATE_EXP_FAILED);
					__lwp_wkspace_free(data);
					wiiuse_status(wm,NULL);
					return;
			}
			__lwp_wkspace_free(data);

			WIIMOTE_DISABLE_STATE(wm,WIIMOTE_STATE_EXP_HANDSHAKE);
			WIIMOTE_ENABLE_STATE(wm,WIIMOTE_STATE_EXP);
			wiiuse_set_ir_mode(wm);
			wiiuse_status(wm,NULL);
			break;
	}
}
Пример #3
0
void wiiuse_handshake(struct wiimote_t *wm,ubyte *data,uword len)
{
	ubyte *buf = NULL;
	struct accel_t *accel = &wm->accel_calib;

	//printf("wiiuse_handshake(%d,%p,%d)\n",wm->handshake_state,data,len);

	switch(wm->handshake_state) {
		case 0:
			wm->handshake_state++;

			wiiuse_set_leds(wm,WIIMOTE_LED_NONE,NULL);
			wiiuse_status(wm,wiiuse_handshake);
			return;

		case 1:
			wm->handshake_state++;
			buf = __lwp_wkspace_allocate(sizeof(ubyte)*8);

			if (len > 2 && data[2]&WM_CTRL_STATUS_BYTE1_ATTACHMENT) {
				wiiuse_read_data(wm,buf,WM_EXP_ID,6,wiiuse_handshake);
				return;

		case 2:
				if (BIG_ENDIAN_LONG(*(int*)(&data[2])) == EXP_ID_CODE_CLASSIC_WIIU_PRO) {
					memset(data, 0, 8);
					WIIMOTE_ENABLE_STATE(wm, WIIMOTE_STATE_WIIU_PRO);
					break;
				}
				buf = data;
			}

			wm->handshake_state++;
			wiiuse_read_data(wm,buf,WM_MEM_OFFSET_CALIBRATION,7,wiiuse_handshake);
			return;
	}

	accel->cal_zero.x = ((data[0]<<2)|((data[3]>>4)&3));
	accel->cal_zero.y = ((data[1]<<2)|((data[3]>>2)&3));
	accel->cal_zero.z = ((data[2]<<2)|(data[3]&3));

	accel->cal_g.x = (((data[4]<<2)|((data[7]>>4)&3)) - accel->cal_zero.x);
	accel->cal_g.y = (((data[5]<<2)|((data[7]>>2)&3)) - accel->cal_zero.y);
	accel->cal_g.z = (((data[6]<<2)|(data[7]&3)) - accel->cal_zero.z);
	__lwp_wkspace_free(data);

	WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_HANDSHAKE);
	WIIMOTE_ENABLE_STATE(wm, WIIMOTE_STATE_HANDSHAKE_COMPLETE);

	wm->event = WIIUSE_CONNECT;
	wiiuse_status(wm,NULL);
}
Пример #4
0
/**
 *	@brief	Enable or disable the rumble.
 *
 *	@param wm		Pointer to a wiimote_t structure.
 *	@param status	1 to enable, 0 to disable.
 */
void wiiuse_rumble(struct wiimote_t* wm, int status) {
	byte buf;

	if (!wm || !WIIMOTE_IS_CONNECTED(wm)) {
		return;
	}

	/* make sure to keep the current lit leds */
	buf = wm->leds;

	if (status) {
		WIIUSE_DEBUG("Starting rumble...");
		WIIMOTE_ENABLE_STATE(wm, WIIMOTE_STATE_RUMBLE);
		buf |= 0x01;
	} else {
		WIIUSE_DEBUG("Stopping rumble...");
		WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_RUMBLE);
		buf &= ~(0x01);
	}

	/* preserve IR state */
	if (WIIMOTE_IS_SET(wm, WIIMOTE_STATE_IR)) {
		buf |= 0x04;
	}

	wiiuse_send(wm, WM_CMD_RUMBLE, &buf, 1);
}
Пример #5
0
/**
 *	@brief Find a wiimote or wiimotes.
 *
 *	@param wm			An array of wiimote_t structures.
 *	@param max_wiimotes	The number of wiimote structures in \a wm.
 *	@param timeout		The number of seconds before the search times out.
 *
 *	@return The number of wiimotes found.
 *
 *	@see wiimote_connect()
 *
 *	This function will only look for wiimote devices.						\n
 *	When a device is found the address in the structures will be set.		\n
 *	You can then call wiimote_connect() to connect to the found				\n
 *	devices.
 */
int wiic_find(struct wiimote_t** wm, int max_wiimotes, int timeout) {
    int device_id;
    int device_sock;
    int found_devices;
    int found_wiimotes;

    /* reset all wiimote bluetooth device addresses */
    for (found_wiimotes = 0; found_wiimotes < max_wiimotes; ++found_wiimotes)
        wm[found_wiimotes]->bdaddr = *BDADDR_ANY;
    found_wiimotes = 0;

    /* get the id of the first bluetooth device. */
    device_id = hci_get_route(NULL);
    if (device_id < 0) {
        perror("hci_get_route");
        return 0;
    }

    /* create a socket to the device */
    device_sock = hci_open_dev(device_id);
    if (device_sock < 0) {
        perror("hci_open_dev");
        return 0;
    }

    inquiry_info scan_info_arr[128];
    inquiry_info* scan_info = scan_info_arr;
    memset(&scan_info_arr, 0, sizeof(scan_info_arr));

    /* scan for bluetooth devices for 'timeout' seconds */
    found_devices = hci_inquiry(device_id, timeout, 128, NULL, &scan_info, IREQ_CACHE_FLUSH);
    if (found_devices < 0) {
        perror("hci_inquiry");
        return 0;
    }

    WIIC_INFO("Found %i bluetooth device(s).", found_devices);

    int i = 0;

    /* display discovered devices */
    for (; (i < found_devices) && (found_wiimotes < max_wiimotes); ++i) {
        if ((scan_info[i].dev_class[0] == WM_DEV_CLASS_0) &&
                (scan_info[i].dev_class[1] == WM_DEV_CLASS_1) &&
                (scan_info[i].dev_class[2] == WM_DEV_CLASS_2))
        {
            /* found a device */
            ba2str(&scan_info[i].bdaddr, wm[found_wiimotes]->bdaddr_str);

            WIIC_INFO("Found wiimote (%s) [id %i].", wm[found_wiimotes]->bdaddr_str, wm[found_wiimotes]->unid);

            wm[found_wiimotes]->bdaddr = scan_info[i].bdaddr;
            WIIMOTE_ENABLE_STATE(wm[found_wiimotes], WIIMOTE_STATE_DEV_FOUND);
            ++found_wiimotes;
        }
    }

    close(device_sock);
    return found_wiimotes;
}
Пример #6
0
void wiiuse_handshake_expansion_start(struct wiimote_t *wm)
{
	if(WIIMOTE_IS_SET(wm,WIIMOTE_STATE_EXP) || WIIMOTE_IS_SET(wm,WIIMOTE_STATE_EXP_FAILED) || WIIMOTE_IS_SET(wm,WIIMOTE_STATE_EXP_HANDSHAKE))
		return;

	wm->expansion_state = 0;
	WIIMOTE_ENABLE_STATE(wm, WIIMOTE_STATE_EXP_HANDSHAKE);
	wiiuse_handshake_expansion(wm, NULL, 0);
}
Пример #7
0
/**
 *	@brief	Set if the wiimote should report motion sensing.
 *
 *	@param wm		Pointer to a wiimote_t structure.
 *	@param status	1 to enable, 0 to disable.
 *
 *	Since reporting motion sensing sends a lot of data,
 *	the wiimote saves power by not transmitting it
 *	by default.
 */
void wiiuse_motion_sensing(struct wiimote_t* wm, int status) {
	if (status) {
		WIIMOTE_ENABLE_STATE(wm, WIIMOTE_STATE_ACC);
	} else {
		WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_ACC);
	}

	wiiuse_set_report_type(wm);
}
Пример #8
0
/**
 *	@brief	Set the IR sensitivity.
 *
 *	@param wm		Pointer to a wiimote_t structure.
 *	@param level	1-5, same as Wii system sensitivity setting.
 *
 *	If the level is < 1, then level will be set to 1.
 *	If the level is > 5, then level will be set to 5.
 */
void wiiuse_set_ir_sensitivity(struct wiimote_t* wm, int level) {
	char* block1 = NULL;
	char* block2 = NULL;

	if (!wm)	return;

	if (level > 5)		level = 5;
	if (level < 1)		level = 1;

	WIIMOTE_DISABLE_STATE(wm, (WIIMOTE_STATE_IR_SENS_LVL1 |
								WIIMOTE_STATE_IR_SENS_LVL2 |
								WIIMOTE_STATE_IR_SENS_LVL3 |
								WIIMOTE_STATE_IR_SENS_LVL4 |
								WIIMOTE_STATE_IR_SENS_LVL5));

	switch (level) {
		case 1:
			WIIMOTE_ENABLE_STATE(wm, WIIMOTE_STATE_IR_SENS_LVL1);
			break;
		case 2:
			WIIMOTE_ENABLE_STATE(wm, WIIMOTE_STATE_IR_SENS_LVL2);
			break;
		case 3:
			WIIMOTE_ENABLE_STATE(wm, WIIMOTE_STATE_IR_SENS_LVL3);
			break;
		case 4:
			WIIMOTE_ENABLE_STATE(wm, WIIMOTE_STATE_IR_SENS_LVL4);
			break;
		case 5:
			WIIMOTE_ENABLE_STATE(wm, WIIMOTE_STATE_IR_SENS_LVL5);
			break;
		default:
			return;
	}

	/* set the new sensitivity */
	get_ir_sens(wm, &block1, &block2);

	wiiuse_write_data(wm, WM_REG_IR_BLOCK1, (byte*)block1, 9);
	wiiuse_write_data(wm, WM_REG_IR_BLOCK2, (byte*)block2, 2);

	WIIUSE_DEBUG("Set IR sensitivity to level %i (unid %i)", level, wm->unid);
}
Пример #9
0
/**
 *	@brief	Set if the wiimote should report motion sensing.
 *
 *	@param wm		Pointer to a wiimote_t structure.
 *	@param status	1 to enable, 0 to disable.
 *
 *	Since reporting motion sensing sends a lot of data,
 *	the wiimote saves power by not transmitting it
 *	by default.
 */
void wiiuse_motion_sensing(struct wiimote_t* wm, int status) 
{
	if (status) {
		if(WIIMOTE_IS_SET(wm,WIIMOTE_STATE_ACC)) return;
		WIIMOTE_ENABLE_STATE(wm, WIIMOTE_STATE_ACC);
	} else {
		if(!WIIMOTE_IS_SET(wm,WIIMOTE_STATE_ACC)) return;
		WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_ACC);
	}

	if(!WIIMOTE_IS_SET(wm,WIIMOTE_STATE_HANDSHAKE_COMPLETE)) return;

	wiiuse_status(wm,NULL);
}
Пример #10
0
void wiic_mute_speaker( struct wiimote_t* wm, int status ) {
  
  if ( status ) {
    // if already enabled then stop
    if ( WIIMOTE_IS_SET(wm, WIIMOTE_STATE_SPEAKER_MUTE) ) return;
    
    WIIMOTE_ENABLE_STATE( wm, WIIMOTE_STATE_SPEAKER_MUTE );
    WIIC_DEBUG("Speaker unmuted");
    byte buf = 0x00;
    wiic_send( wm, WM_CMD_SPEAKER_MUTE, &buf, 1 );
  } else {
    // if already disabled then stop
    if ( !WIIMOTE_IS_SET(wm, WIIMOTE_STATE_SPEAKER_MUTE) ) return;
    
    WIIMOTE_DISABLE_STATE( wm, WIIMOTE_STATE_SPEAKER_MUTE );
    WIIC_DEBUG("Speaker muted");
    byte buf = 0x04;
    wiic_send( wm, WM_CMD_SPEAKER_MUTE, &buf, 1 );
  }
}
Пример #11
0
void wiiuse_set_motion_plus(struct wiimote_t *wm, int status)
{
	ubyte val;
	
	if(WIIMOTE_IS_SET(wm,WIIMOTE_STATE_EXP_HANDSHAKE))
		return;
	
	WIIMOTE_ENABLE_STATE(wm, WIIMOTE_STATE_EXP_HANDSHAKE);
	if(status)
	{
		val = 0x04;
		wiiuse_write_data(wm,WM_EXP_MOTION_PLUS_ENABLE,&val,1,wiiuse_motion_plus_check);
	}
	else
	{
		wiiuse_disable_expansion(wm);
		val = 0x55;
		wiiuse_write_data(wm,WM_EXP_MEM_ENABLE1,&val,1,wiiuse_set_motion_plus_clear1);
	}
}
Пример #12
0
/**
 *	@brief Load Wii devices registered in the wiimotes.config file.
 *
 *	@param wm			An array of wiimote_t structures.
 *
 *	@return The number of wiimotes successfully loaded.
 *
 *	@see wiic_find()
 *  @see wiic_connect()
 *	@see wiic_connect_single()
 *	@see wiic_disconnect()
 *
 *	Up to version 0.53, it is possible to register the MAC address of your
 *  Wii devices. This allows to automatically load them, without waiting for any
 *  search timeout. To register a new device, go to: <HOME_DIR>/.wiic/ and
 *  edit the file wiimotes.config, by adding the MAC address of the device
 *  you want to register (one line per MAC address).
 */
int wiic_load(struct wiimote_t** wm)
{
    int loaded = 0;
    int i = 0;
    char str[200];
    char* str_ptr = 0;
    char configPath[100];
    char* tmp = 0;

    // Retrieve the HOME environment variable
    tmp = getenv("HOME");
    strcpy(configPath,tmp);
    strncat(configPath,"/.wiic/wiimotes.config",22);

    // Open the config file
    FILE* fd = 0;
    fd = fopen(configPath,"r");
    if(!fd)
        return loaded;

    // Read line by line
    while(fgets(str,sizeof(str),fd) != NULL && loaded < 1) {
        int len = strlen(str)-1;
        if(str[len] == '\n')
            str[len] = 0;
        loaded++;
    }

    // We initialize the device structure
    for (; i < loaded; ++i) {
        /* found a device */
        strncpy(wm[i]->bdaddr_str,str,18);
        str_ptr = str;
        str2ba(str_ptr,&(wm[i]->bdaddr));
        WIIMOTE_ENABLE_STATE(wm[i], WIIMOTE_STATE_DEV_FOUND);
        WIIC_INFO("Loaded Wiimote (%s) [id %i].",wm[i]->bdaddr_str,wm[i]->unid);
    }

    return loaded;
}
Пример #13
0
void wiiuse_handshake(struct wiimote_t *wm,ubyte *data,uword len)
{
	ubyte *buf = NULL;
	struct accel_t *accel = &wm->accel_calib;

	//printf("wiiuse_handshake(%d,%p,%d)\n",wm->handshake_state,data,len);

	switch(wm->handshake_state) {
		case 0:
			wm->handshake_state++;

			wiiuse_set_leds(wm,WIIMOTE_LED_NONE,NULL);

			buf = __lwp_wkspace_allocate(sizeof(ubyte)*8);
			wiiuse_read_data(wm,buf,WM_MEM_OFFSET_CALIBRATION,7,wiiuse_handshake);
			break;
		case 1:
			wm->handshake_state++;

			accel->cal_zero.x = ((data[0]<<2)|((data[3]>>4)&3));
			accel->cal_zero.y = ((data[1]<<2)|((data[3]>>2)&3));
			accel->cal_zero.z = ((data[2]<<2)|(data[3]&3));

			accel->cal_g.x = (((data[4]<<2)|((data[7]>>4)&3)) - accel->cal_zero.x);
			accel->cal_g.y = (((data[5]<<2)|((data[7]>>2)&3)) - accel->cal_zero.y);
			accel->cal_g.z = (((data[6]<<2)|(data[7]&3)) - accel->cal_zero.z);
			__lwp_wkspace_free(data);
			
			WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_HANDSHAKE);
			WIIMOTE_ENABLE_STATE(wm, WIIMOTE_STATE_HANDSHAKE_COMPLETE);

			wm->event = WIIUSE_CONNECT;
			wiiuse_status(wm,NULL);
			break;
		default:
			break;

	}
}
Пример #14
0
void wiiuse_motion_plus_check(struct wiimote_t *wm,ubyte *data,uword len)
{
	u32 val;
	if(data == NULL)
	{
		wiiuse_read_data(wm, wm->motion_plus_id, WM_EXP_ID, 6, wiiuse_motion_plus_check);
	}
	else
	{
		WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_EXP);
		WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_EXP_FAILED);
		WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_EXP_HANDSHAKE);
		val = (data[3] << 16) | (data[2] << 24) | (data[4] << 8) | data[5];
		if(val == EXP_ID_CODE_MOTION_PLUS)
		{
			/* handshake done */
			wm->event = WIIUSE_MOTION_PLUS_ACTIVATED;
			wm->exp.type = EXP_MOTION_PLUS;
			
			WIIMOTE_ENABLE_STATE(wm,WIIMOTE_STATE_EXP);
			wiiuse_set_ir_mode(wm);
		}
	}
}
Пример #15
0
void wiic_set_speaker( struct wiimote_t* wm, int status ) {
  
  if ( status ) {
    // if already enabled then stop
    if ( WIIMOTE_IS_SET(wm, WIIMOTE_STATE_SPEAKER) ) return;
    
    WIIMOTE_ENABLE_STATE( wm, WIIMOTE_STATE_SPEAKER );
    WIIMOTE_ENABLE_STATE( wm, WIIMOTE_STATE_SPEAKER_MUTE );
    
    byte buf;
    
    /* Initialization Protocol */

    // Enable Speaker
    buf = 0x04;
    wiic_send( wm, WM_CMD_SPEAKER_ENABLE, &buf, 1 );
    
    // Mute Speaker
    buf = 0x04;
    wiic_send( wm, WM_CMD_SPEAKER_MUTE, &buf, 1 );
    
    // Write 0x01 to register 0xa20009
    buf = 0x01;
    wiic_write_data( wm, 0x04a20009, &buf, 1 );
    
    // Write 0x08 to register 0xa20001
    buf = 0x08;
    wiic_write_data( wm, 0x04a20001, &buf, 1 );
    
    // 1st byte for configuration 
    buf = 0x00;
    wiic_write_data( wm, 0x04a20001, &buf, 1 );
    // 2nd byte for configuration
    buf = 0x00;
    wiic_write_data( wm, 0x04a20002, &buf, 1 );
    // 3rd byte for configuration
    buf = 0xD0;
    wiic_write_data( wm, 0x04a20003, &buf, 1 );
    // 4th byte for configuration
    buf = 0x07;
    wiic_write_data( wm, 0x04a20004, &buf, 1 );
    // 5th byte for configuration
    buf = 40;
    wiic_write_data( wm, 0x04a20005, &buf, 1 );
    // 6th byte for configuration
    buf = 0x00;
    wiic_write_data( wm, 0x04a20006, &buf, 1 );
    // 7th byte for configuration
    buf = 0x00;
    wiic_write_data( wm, 0x04a20007, &buf, 1 );
    
    // Write 0x01 to register 0xa20008
    buf = 0x01;
    wiic_write_data( wm, 0x04a20008, &buf, 1 );
    
    // Unmute Speaker
    buf = 0x00;
    wiic_send( wm, WM_CMD_SPEAKER_MUTE, &buf, 1 );
    
    WIIC_DEBUG("Speaker enabled");
  } else {
    // if already disabled then stop 
    if ( !WIIMOTE_IS_SET(wm, WIIMOTE_STATE_SPEAKER) ) return;
    
    WIIMOTE_DISABLE_STATE( wm, WIIMOTE_STATE_SPEAKER );
    WIIMOTE_DISABLE_STATE( wm, WIIMOTE_STATE_SPEAKER_MUTE );
    WIIC_DEBUG("Speaker disabled");
    byte buf = 0x00;
    wiic_send( wm, WM_CMD_SPEAKER_ENABLE, &buf, 1 );
  }
  
  /* set the wiimote report type */
  wiic_set_report_type( wm );
  
  /* wait for the wiimote to catch up */
  usleep( 50000 );
}
Пример #16
0
/**
 *	@brief Connect to a wiimote with a known address.
 *
 *	@param wm		Pointer to a wiimote_t structure.
 *	@param address	The address of the device to connect to.
 *					If NULL, use the address in the struct set by wiic_find().
 *
 *	@return 1 on success, 0 on failure
 */
static int wiic_connect_single(struct wiimote_t* wm, char* address) {
    struct sockaddr_l2 addr;
    memset(&addr, 0, sizeof(addr));

    if (!wm || WIIMOTE_IS_CONNECTED(wm))
        return 0;

    addr.l2_family = AF_BLUETOOTH;

    if (address)
        /* use provided address */
        str2ba(address, &addr.l2_bdaddr);
    else
        /* use address of device discovered */
        addr.l2_bdaddr = wm->bdaddr;

    /*
     *	OUTPUT CHANNEL
     */
    wm->out_sock = socket(AF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP);
    if (wm->out_sock == -1)
        return 0;

    addr.l2_psm = htobs(WM_OUTPUT_CHANNEL);

    /* connect to wiimote */
    if (connect(wm->out_sock, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
        perror("connect() output sock");
        return 0;
    }

    /*
     *	INPUT CHANNEL
     */
    wm->in_sock = socket(AF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP);
    if (wm->in_sock == -1) {
        close(wm->out_sock);
        wm->out_sock = -1;
        return 0;
    }

    addr.l2_psm = htobs(WM_INPUT_CHANNEL);

    /* connect to wiimote */
    if (connect(wm->in_sock, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
        perror("connect() interrupt sock");
        close(wm->out_sock);
        wm->out_sock = -1;
        return 0;
    }

    WIIC_INFO("Connected to wiimote [id %i].", wm->unid);

    /* do the handshake */
    WIIMOTE_ENABLE_STATE(wm, WIIMOTE_STATE_CONNECTED);
    wiic_handshake(wm, NULL, 0);

    wiic_set_report_type(wm);

    return 1;
}
Пример #17
0
int wiiuse_os_find(struct wiimote_t** wm, int max_wiimotes, int timeout) {
	GUID device_id;
	HANDLE dev;
	HDEVINFO device_info;
	int i, index;
	DWORD len;
	SP_DEVICE_INTERFACE_DATA device_data;
	PSP_DEVICE_INTERFACE_DETAIL_DATA detail_data = NULL;
	HIDD_ATTRIBUTES	attr;
	int found = 0;

	(void) timeout; /* unused */

	device_data.cbSize = sizeof(device_data);
	index = 0;

	/* get the device id */
	HidD_GetHidGuid(&device_id);

	/* get all hid devices connected */
	device_info = SetupDiGetClassDevs(&device_id, NULL, NULL, (DIGCF_DEVICEINTERFACE | DIGCF_PRESENT));

	for (;; ++index) {

		if (detail_data) {
			free(detail_data);
			detail_data = NULL;
		}

		/* query the next hid device info */
		if (!SetupDiEnumDeviceInterfaces(device_info, NULL, &device_id, index, &device_data)) {
			break;
		}

		/* get the size of the data block required */
		i = SetupDiGetDeviceInterfaceDetail(device_info, &device_data, NULL, 0, &len, NULL);
		detail_data = (SP_DEVICE_INTERFACE_DETAIL_DATA_A*)malloc(len);
		detail_data->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);

		/* query the data for this device */
		if (!SetupDiGetDeviceInterfaceDetail(device_info, &device_data, detail_data, len, NULL, NULL)) {
			continue;
		}

		/* open the device */
		dev = CreateFile(detail_data->DevicePath,
		                 (GENERIC_READ | GENERIC_WRITE),
		                 (FILE_SHARE_READ | FILE_SHARE_WRITE),
		                 NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
		if (dev == INVALID_HANDLE_VALUE) {
			continue;
		}

		/* get device attributes */
		attr.Size = sizeof(attr);
		i = HidD_GetAttributes(dev, &attr);

		if ((attr.VendorID == WM_VENDOR_ID) && (attr.ProductID == WM_PRODUCT_ID)) {
			/* this is a wiimote */
			wm[found]->dev_handle = dev;

			wm[found]->hid_overlap.hEvent = CreateEvent(NULL, 1, 1, "");
			wm[found]->hid_overlap.Offset = 0;
			wm[found]->hid_overlap.OffsetHigh = 0;

			WIIMOTE_ENABLE_STATE(wm[found], WIIMOTE_STATE_DEV_FOUND);
			WIIMOTE_ENABLE_STATE(wm[found], WIIMOTE_STATE_CONNECTED);

			/* try to set the output report to see if the device is actually connected */
			if (!wiiuse_set_report_type(wm[found])) {
				WIIMOTE_DISABLE_STATE(wm[found], WIIMOTE_STATE_CONNECTED);
				continue;
			}

			/* do the handshake */
			wiiuse_handshake(wm[found], NULL, 0);

			WIIUSE_INFO("Connected to wiimote [id %i].", wm[found]->unid);

			++found;
			if (found >= max_wiimotes) {
				break;
			}
		} else {
			/* not a wiimote */
			CloseHandle(dev);
		}
	}

	if (detail_data) {
		free(detail_data);
	}

	SetupDiDestroyDeviceInfoList(device_info);

	return found;
}
Пример #18
0
int wiiuse_os_find(struct wiimote_t** wm, int max_wiimotes, int timeout) {
	int device_id;
	int device_sock;
	inquiry_info scan_info_arr[128];
	inquiry_info* scan_info = scan_info_arr;
	int found_devices;
	int found_wiimotes;
	int i = 0;

	/* reset all wiimote bluetooth device addresses */
	for (found_wiimotes = 0; found_wiimotes < max_wiimotes; ++found_wiimotes) {
		/* bacpy(&(wm[found_wiimotes]->bdaddr), BDADDR_ANY); */
		memset(&(wm[found_wiimotes]->bdaddr), 0, sizeof(bdaddr_t));
	}
	found_wiimotes = 0;

	/* get the id of the first bluetooth device. */
	device_id = hci_get_route(NULL);
	if (device_id < 0) {
		if (errno == ENODEV) {
			WIIUSE_ERROR("Could not detect a Bluetooth adapter!");
		} else {
			perror("hci_get_route");
		}
		return 0;
	}

	/* create a socket to the device */
	device_sock = hci_open_dev(device_id);
	if (device_sock < 0) {
		perror("hci_open_dev");
		return 0;
	}

	memset(&scan_info_arr, 0, sizeof(scan_info_arr));

	/* scan for bluetooth devices for 'timeout' seconds */
	found_devices = hci_inquiry(device_id, timeout, 128, NULL, &scan_info, IREQ_CACHE_FLUSH);
	if (found_devices < 0) {
		perror("hci_inquiry");
		close(device_sock);
		return 0;
	}

	WIIUSE_INFO("Found %i bluetooth device(s).", found_devices);

	/* display discovered devices */
	for (i = 0; (i < found_devices) && (found_wiimotes < max_wiimotes); ++i) {
		bool is_wiimote_regular =   (scan_info[i].dev_class[0] == WM_DEV_CLASS_0) &&
									(scan_info[i].dev_class[1] == WM_DEV_CLASS_1) &&
									(scan_info[i].dev_class[2] == WM_DEV_CLASS_2);
		
		bool is_wiimote_plus =      (scan_info[i].dev_class[0] == WM_PLUS_DEV_CLASS_0) &&
									(scan_info[i].dev_class[1] == WM_PLUS_DEV_CLASS_1) &&
									(scan_info[i].dev_class[2] == WM_PLUS_DEV_CLASS_2);
		if (is_wiimote_regular || is_wiimote_plus) {
			/* found a device */
			ba2str(&scan_info[i].bdaddr, wm[found_wiimotes]->bdaddr_str);
			
			const char* str_type;
			if(is_wiimote_regular)
			{
				wm[found_wiimotes]->type = WIIUSE_WIIMOTE_REGULAR;
				str_type = " (regular wiimote)";
			}
			else if(is_wiimote_plus)
			{
				wm[found_wiimotes]->type = WIIUSE_WIIMOTE_MOTION_PLUS_INSIDE;
				str_type = " (motion plus inside)";
			}

			WIIUSE_INFO("Found wiimote (type: %s) (%s) [id %i].", str_type, wm[found_wiimotes]->bdaddr_str, wm[found_wiimotes]->unid);

			wm[found_wiimotes]->bdaddr = scan_info[i].bdaddr;
			WIIMOTE_ENABLE_STATE(wm[found_wiimotes], WIIMOTE_STATE_DEV_FOUND);
			++found_wiimotes;
		}
	}

	close(device_sock);
	return found_wiimotes;
}
Пример #19
0
/**
 *	@brief	Set if the wiimote should track IR targets.
 *
 *	@param wm		Pointer to a wiimote_t structure.
 *	@param status	1 to enable, 0 to disable.
 */
void wiiuse_set_ir(struct wiimote_t* wm, int status) {
	byte buf;
	char* block1 = NULL;
	char* block2 = NULL;
	int ir_level;

	if (!wm)
		return;

	/*
	 *	Wait for the handshake to finish first.
	 *	When it handshake finishes and sees that
	 *	IR is enabled, it will call this function
	 *	again to actually enable IR.
	 */
	if (!WIIMOTE_IS_SET(wm, WIIMOTE_STATE_HANDSHAKE_COMPLETE)) {
		if(status) {
			WIIUSE_DEBUG("Tried to enable IR, will wait until handshake finishes.");
			WIIMOTE_ENABLE_STATE(wm, WIIMOTE_STATE_IR);
		} // else ignoring request to turn off, since it's turned off by default
		return;
	}

	/*
	 *	Check to make sure a sensitivity setting is selected.
	 */
	ir_level = get_ir_sens(wm, &block1, &block2);
	if (!ir_level) {
		WIIUSE_ERROR("No IR sensitivity setting selected.");
		return;
	}

	if (status) {
		/* if already enabled then stop */
		if (WIIMOTE_IS_SET(wm, WIIMOTE_STATE_IR))
			return;
		WIIMOTE_ENABLE_STATE(wm, WIIMOTE_STATE_IR);
	} else {
		/* if already disabled then stop */
		if (!WIIMOTE_IS_SET(wm, WIIMOTE_STATE_IR))
			return;
		WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_IR);
	}

	/* set camera 1 and 2 */
	buf = (status ? 0x04 : 0x00);
	wiiuse_send(wm, WM_CMD_IR, &buf, 1);
	wiiuse_send(wm, WM_CMD_IR_2, &buf, 1);

	if (!status) {
		WIIUSE_DEBUG("Disabled IR cameras for wiimote id %i.", wm->unid);
		wiiuse_set_report_type(wm);
		return;
	}

	/* enable IR, set sensitivity */
	buf = 0x08;
	wiiuse_write_data(wm, WM_REG_IR, &buf, 1);

	/* wait for the wiimote to catch up */
	#ifndef WIN32
		usleep(50000);
	#else
		Sleep(50);
	#endif

	/* write sensitivity blocks */
	wiiuse_write_data(wm, WM_REG_IR_BLOCK1, (byte*)block1, 9);
	wiiuse_write_data(wm, WM_REG_IR_BLOCK2, (byte*)block2, 2);

	/* set the IR mode */
	if (WIIMOTE_IS_SET(wm, WIIMOTE_STATE_EXP))
		buf = WM_IR_TYPE_BASIC;
	else
		buf = WM_IR_TYPE_EXTENDED;
	wiiuse_write_data(wm, WM_REG_IR_MODENUM, &buf, 1);

	#ifndef WIN32
		usleep(50000);
	#else
		Sleep(50);
	#endif

	/* set the wiimote report type */
	wiiuse_set_report_type(wm);

	WIIUSE_DEBUG("Enabled IR camera for wiimote id %i (sensitivity level %i).", wm->unid, ir_level);
}
Пример #20
0
 /**
 *	@brief Get initialization data from the wiimote.
 *
 *	@param wm		Pointer to a wiimote_t structure.
 *	@param data		unused
 *	@param len		unused
 *
 *	When first called for a wiimote_t structure, a request
 *	is sent to the wiimote for initialization information.
 *	This includes factory set accelerometer data.
 *	The handshake will be concluded when the wiimote responds
 *	with this data.
 */
void wiiuse_handshake(struct wiimote_t* wm, byte* data, uint16_t len) {
	if (!wm)	return;

	switch (wm->handshake_state) {
		case 0:
		{
			/* send request to wiimote for accelerometer calibration */
			byte* buf;

			WIIMOTE_ENABLE_STATE(wm, WIIMOTE_STATE_HANDSHAKE);
			wiiuse_set_leds(wm, WIIMOTE_LED_NONE);

			buf = (byte*)malloc(sizeof(byte) * 8);
			wiiuse_read_data_cb(wm, wiiuse_handshake, buf, WM_MEM_OFFSET_CALIBRATION, 7);
			wm->handshake_state++;

			wiiuse_set_leds(wm, WIIMOTE_LED_NONE);

			break;
		}
		case 1:
		{
			struct read_req_t* req = wm->read_req;
			struct accel_t* accel = &wm->accel_calib;

			/* received read data */
			accel->cal_zero.x = req->buf[0];
			accel->cal_zero.y = req->buf[1];
			accel->cal_zero.z = req->buf[2];

			accel->cal_g.x = req->buf[4] - accel->cal_zero.x;
			accel->cal_g.y = req->buf[5] - accel->cal_zero.y;
			accel->cal_g.z = req->buf[6] - accel->cal_zero.z;

			/* done with the buffer */
			free(req->buf);

			/* handshake is done */
			WIIUSE_DEBUG("Handshake finished. Calibration: Idle: X=%x Y=%x Z=%x\t+1g: X=%x Y=%x Z=%x",
					accel->cal_zero.x, accel->cal_zero.y, accel->cal_zero.z,
					accel->cal_g.x, accel->cal_g.y, accel->cal_g.z);


			/* request the status of the wiimote to see if there is an expansion */
			wiiuse_status(wm);

			WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_HANDSHAKE);
			WIIMOTE_ENABLE_STATE(wm, WIIMOTE_STATE_HANDSHAKE_COMPLETE);
			wm->handshake_state++;

			/* now enable IR if it was set before the handshake completed */
			if (WIIMOTE_IS_SET(wm, WIIMOTE_STATE_IR)) {
				WIIUSE_DEBUG("Handshake finished, enabling IR.");
				WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_IR);
				wiiuse_set_ir(wm, 1);
			}

			break;
		}
		default:
		{
			break;
		}
	}
}
Пример #21
0
void wiiuse_handshake(struct wiimote_t* wm, byte* data, uint16_t len) {
	if (!wm)	{
		return;
	}

	switch (wm->handshake_state) {
		case 0: {
				byte* buf;

				/* continuous reporting off, report to buttons only */
				WIIMOTE_ENABLE_STATE(wm, WIIMOTE_STATE_HANDSHAKE);
				wiiuse_set_leds(wm, WIIMOTE_LED_NONE);

				WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_ACC);
				WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_IR);
				WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_RUMBLE);
				WIIMOTE_DISABLE_FLAG(wm, WIIUSE_CONTINUOUS);

				wiiuse_set_report_type(wm);

				/* send request to wiimote for accelerometer calibration */
				buf = (byte*)malloc(sizeof(byte) * 8);
				wiiuse_read_data_cb(wm, wiiuse_handshake, buf, WM_MEM_OFFSET_CALIBRATION, 7);
				wm->handshake_state++;

				wiiuse_set_leds(wm, WIIMOTE_LED_NONE);

				break;
			}

		case 1: {
				struct read_req_t* req = wm->read_req;
				struct accel_t* accel = &wm->accel_calib;
				byte val;

				/* received read data */
				accel->cal_zero.x = req->buf[0];
				accel->cal_zero.y = req->buf[1];
				accel->cal_zero.z = req->buf[2];

				accel->cal_g.x = req->buf[4] - accel->cal_zero.x;
				accel->cal_g.y = req->buf[5] - accel->cal_zero.y;
				accel->cal_g.z = req->buf[6] - accel->cal_zero.z;

				/* done with the buffer */
				free(req->buf);

				/* handshake is done */
				WIIUSE_DEBUG("Handshake finished. Calibration: Idle: X=%x Y=%x Z=%x\t+1g: X=%x Y=%x Z=%x",
				             accel->cal_zero.x, accel->cal_zero.y, accel->cal_zero.z,
				             accel->cal_g.x, accel->cal_g.y, accel->cal_g.z);

				/* M+ off */
				val = 0x55;
				wiiuse_write_data_cb(wm, WM_EXP_MEM_ENABLE1, &val, 1, wiiuse_disable_motion_plus1);

				break;
			}

		case 2: {
				/* request the status of the wiimote to check for any expansion */
				WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_HANDSHAKE);
				WIIMOTE_ENABLE_STATE(wm, WIIMOTE_STATE_HANDSHAKE_COMPLETE);
				wm->handshake_state++;

				/* now enable IR if it was set before the handshake completed */
				if (WIIMOTE_IS_SET(wm, WIIMOTE_STATE_IR)) {
					WIIUSE_DEBUG("Handshake finished, enabling IR.");
					WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_IR);
					wiiuse_set_ir(wm, 1);
				}

				wm->event = WIIUSE_CONNECT;
				wiiuse_status(wm);

				break;
			}

		default: {
				break;
			}
	}
}
Пример #22
0
/**
 *	@brief Connect to a wiimote with a known address.
 *
 *	@param wm		Pointer to a wiimote_t structure.
 *	@param address	The address of the device to connect to.
 *					If NULL, use the address in the struct set by wiiuse_find().
 *
 *	@return 1 on success, 0 on failure
 */
static int wiiuse_connect_single(struct wiimote_t* wm, char* address)
{
	struct sockaddr_l2 addr={0} ;
  //char dest[18]="00:25:A0:B0:96:8A" ;

	if (!wm || WIIMOTE_IS_CONNECTED(wm))
		return 0;

	wm->out_sock = socket(AF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP);
	if (wm->out_sock == -1)
		return 0;

	addr.l2_family = AF_BLUETOOTH;
	addr.l2_psm = htobs(WM_OUTPUT_CHANNEL); // =0x11, le port -> Wiimote.
	//str2ba(dest, &addr.l2_bdaddr) ;

	if( address )
		// Use provided address.
		str2ba(address, &addr.l2_bdaddr) ;
	else
		// Use address of device discovered.
		str2ba(wm->bdaddr_str, &addr.l2_bdaddr) ;

	/*
	 *	OUTPUT CHANNEL
	 */
	
	/* connect to wiimote */
  if( connect(wm->out_sock, (struct sockaddr*)&addr, sizeof(addr)) < 0 )
	{
		perror("connect() output sock");
		return 0;
	}

	/*
	 *	INPUT CHANNEL
	 */
	wm->in_sock = socket(AF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP);
	if (wm->in_sock == -1)
  {
		close(wm->out_sock);
		wm->out_sock = -1;
		return 0;
	}

	addr.l2_psm = htobs(WM_INPUT_CHANNEL);

	/* connect to wiimote */
	if ( connect(wm->in_sock, (struct sockaddr*)&addr, sizeof(addr)) < 0)
	{
		perror("connect() interrupt sock");
		close(wm->out_sock);
		wm->out_sock = -1;
		return 0;
	}

	WIIUSE_INFO("Connected to wiimote [id %i].", wm->unid);

	/* do the handshake */
	WIIMOTE_ENABLE_STATE(wm, WIIMOTE_STATE_CONNECTED);
	wiiuse_handshake(wm, NULL, 0);

	wiiuse_set_report_type(wm);

	return 1;
}