/** * @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 wiiuse_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; } WIIUSE_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); WIIUSE_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; }
/** * @brief Clean up wiimote_t array created by wiiuse_init() */ void wiiuse_cleanup(struct wiimote_t** wm, int wiimotes) { int i = 0; if (!wm) { return; } WIIUSE_INFO("wiiuse clean up..."); for (; i < wiimotes; ++i) { wiiuse_disconnect(wm[i]); wiiuse_cleanup_platform_fields(wm[i]); free(wm[i]); } free(wm); return; }
/** * @brief The wiimote disconnected. * * @param wm Pointer to a wiimote_t structure. */ void wiiuse_disconnected(struct wiimote_t* wm) { if (!wm) { return; } WIIUSE_INFO("Wiimote disconnected [id %i].", wm->unid); /* disable the connected flag */ WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_CONNECTED); /* reset a bunch of stuff */ wm->leds = 0; wm->state = WIIMOTE_INIT_STATES; wm->read_req = NULL; #ifndef WIIUSE_SYNC_HANDSHAKE wm->handshake_state = 0; #endif wm->btns = 0; wm->btns_held = 0; wm->btns_released = 0; wm->event = WIIUSE_DISCONNECT; }
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; }
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; }