moved_client_list * moved_client_list_open() { moved_client_list *result = NULL; char hostname[255]; FILE *fp; char *filename = psmove_util_get_file_path(MOVED_HOSTS_LIST_FILE); fp = fopen(filename, "r"); if (fp != NULL) { while (fgets(hostname, sizeof(hostname), fp) != NULL) { char *end = hostname + strlen(hostname) - 1; if (*end == '\n' || *end == '\r') { *end = '\0'; } printf("Using remote host '%s' (from %s)\n", hostname, MOVED_HOSTS_LIST_FILE); result = moved_client_list_insert(result, moved_client_create(hostname)); } fclose(fp); } free(filename); /* XXX: Read from config file */ //result = moved_client_list_insert(result, moved_client_create("localhost")); return result; }
static moved_client_list * moved_client_list_discover(moved_client_list *result) { int fd = (int)socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); if (fd == -1) { return nullptr; } psmove_port_set_socket_timeout_ms(fd, 10); int enabled = 1; setsockopt(fd, SOL_SOCKET, SO_BROADCAST, (const char *)&enabled, sizeof(enabled)); struct sockaddr_in addr; addr.sin_family = AF_INET; addr.sin_port = htons(MOVED_UDP_PORT); addr.sin_addr.s_addr = INADDR_BROADCAST; union PSMoveMovedRequest request; union PSMoveMovedRequest response; memset(&request, 0, sizeof(request)); request.header.request_sequence = 0x47110000; request.header.command_id = MOVED_REQ_DISCOVER; request.header.controller_id = 0; for (int i=0; i<5; i++) { request.header.request_sequence++; int res = sendto(fd, (const char *)&request, sizeof(request), /*flags=*/0, (struct sockaddr *)&addr, sizeof(addr)); if (res == -1) { psmove_WARNING("Could not send discovery request"); } psmove_port_sleep_ms(20); } psmove_port_sleep_ms(50); std::map<std::string, bool> discovered; int failures = 0; while (failures < 10) { struct sockaddr_in addr_server; socklen_t addr_server_len = sizeof(addr_server); memset(&addr_server, 0, sizeof(addr_server)); addr_server.sin_family = AF_INET; int res = recvfrom(fd, (char *)&response, sizeof(response), /*flags=*/0, (struct sockaddr *)&addr_server, &addr_server_len); if (res == sizeof(response)) { char temp[1024]; inet_ntop(addr.sin_family, &addr_server.sin_addr, temp, sizeof(temp)); std::string hostname(temp); discovered[hostname] = true; psmove_DEBUG("Discovered daemon: '%s' (seq=0x%08x)\n", temp, response.header.request_sequence); failures = 0; } else { failures++; } } psmove_port_close_socket(fd); for (auto it: discovered) { const char *hostname = it.first.c_str(); printf("Using remote host '%s' (from auto-discovery)\n", hostname); moved_client *client = moved_client_create(hostname); result = moved_client_list_insert(result, client); if (moved_client_send(client, MOVED_REQ_GET_HOST_BTADDR, 0, nullptr, 0)) { char *serial = _psmove_btaddr_to_string(*((PSMove_Data_BTAddr *)client->response_buf.get_host_btaddr.btaddr)); printf("Bluetooth host address of '%s' is '%s'\n", hostname, serial); free(serial); } } return result; }