static void wiiuse_disable_motion_plus2(struct wiimote_t *wm, byte *data, unsigned short len) { WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_EXP_FAILED); WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_EXP_HANDSHAKE); wiiuse_set_ir_mode(wm); wm->handshake_state++; wiiuse_handshake(wm, NULL, 0); }
/** * @brief Try to resync with the wiimote by starting a new handshake. * * @param wm Pointer to a wiimote_t structure. */ void wiiuse_resync(struct wiimote_t* wm) { if (!wm) { return; } #ifndef WIIUSE_SYNC_HANDSHAKE wm->handshake_state = 0; #endif wiiuse_handshake(wm, NULL, 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; }
/** * @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; 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; } 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; }