static inline void remote_version_information(int dev, bdaddr_t *sba, void *ptr) { evt_read_remote_version_complete *evt = ptr; bdaddr_t dba; if (evt->status) return; if (get_bdaddr(dev, sba, btohs(evt->handle), &dba) < 0) return; write_version_info(sba, &dba, btohs(evt->manufacturer), evt->lmp_ver, btohs(evt->lmp_subver)); }
static void connectNative(JNIEnv *env, jobject obj) { #ifdef HAVE_BLUETOOTH ALOGV("%s", __FUNCTION__); int ret; jint type; const char *c_address; jstring address; bdaddr_t bdaddress; socklen_t addr_sz; struct sockaddr *addr; struct asocket *s = get_socketData(env, obj); int retry = 0; if (!s) return; type = env->GetIntField(obj, field_mType); /* parse address into bdaddress */ address = (jstring) env->GetObjectField(obj, field_mAddress); c_address = env->GetStringUTFChars(address, NULL); if (get_bdaddr(c_address, &bdaddress)) { env->ReleaseStringUTFChars(address, c_address); jniThrowIOException(env, EINVAL); return; } env->ReleaseStringUTFChars(address, c_address); switch (type) { case TYPE_RFCOMM: struct sockaddr_rc addr_rc; addr = (struct sockaddr *)&addr_rc; addr_sz = sizeof(addr_rc); memset(addr, 0, addr_sz); addr_rc.rc_family = AF_BLUETOOTH; addr_rc.rc_channel = env->GetIntField(obj, field_mPort); memcpy(&addr_rc.rc_bdaddr, &bdaddress, sizeof(bdaddr_t)); break; case TYPE_SCO_WBS: case TYPE_SCO: struct sockaddr_sco addr_sco; addr = (struct sockaddr *)&addr_sco; addr_sz = sizeof(addr_sco); memset(addr, 0, addr_sz); addr_sco.sco_family = AF_BLUETOOTH; addr_sco.is_wbs = (type == TYPE_SCO_WBS); memcpy(&addr_sco.sco_bdaddr, &bdaddress, sizeof(bdaddr_t)); break; case TYPE_L2CAP: case TYPE_EL2CAP: struct sockaddr_l2 addr_l2; addr = (struct sockaddr *)&addr_l2; addr_sz = sizeof(addr_l2); memset(addr, 0, addr_sz); addr_l2.l2_family = AF_BLUETOOTH; addr_l2.l2_psm = env->GetIntField(obj, field_mPort); memcpy(&addr_l2.l2_bdaddr, &bdaddress, sizeof(bdaddr_t)); break; default: jniThrowIOException(env, ENOSYS); return; } connect: ret = asocket_connect(s, addr, addr_sz, -1); ALOGV("...connect(%d, %s) = %d (errno %d)", s->fd, TYPE_AS_STR(type), ret, errno); if (ret && errno == EALREADY && retry < 2) { /* workaround for bug 5082381 (EALREADY on ACL collision): * retry the connect. Unfortunately we have to create a new fd. * It's not ideal to switch the fd underneath the object, but * is currently safe */ ALOGD("Hit bug 5082381 (EALREADY on ACL collision), trying workaround"); usleep(100000); retry++; abortNative(env, obj); destroyNative(env, obj); initSocketNative(env, obj); if (env->ExceptionOccurred()) { return; } s = get_socketData(env, obj); //Due to init socket ptr would be updated goto connect; } if (!ret && retry > 0) ALOGD("...workaround ok"); if (ret) jniThrowIOException(env, errno); return; #endif jniThrowIOException(env, ENOSYS); }
static void connectNative(JNIEnv *env, jobject obj) { #ifdef HAVE_BLUETOOTH LOGV(__FUNCTION__); int ret; jint type; const char *c_address; jstring address; bdaddr_t bdaddress; socklen_t addr_sz; struct sockaddr *addr; struct asocket *s = get_socketData(env, obj); if (!s) return; type = env->GetIntField(obj, field_mType); /* parse address into bdaddress */ address = (jstring) env->GetObjectField(obj, field_mAddress); c_address = env->GetStringUTFChars(address, NULL); if (get_bdaddr(c_address, &bdaddress)) { env->ReleaseStringUTFChars(address, c_address); jniThrowIOException(env, EINVAL); return; } env->ReleaseStringUTFChars(address, c_address); switch (type) { case TYPE_RFCOMM: struct sockaddr_rc addr_rc; addr = (struct sockaddr *)&addr_rc; addr_sz = sizeof(addr_rc); memset(addr, 0, addr_sz); addr_rc.rc_family = AF_BLUETOOTH; addr_rc.rc_channel = env->GetIntField(obj, field_mPort); memcpy(&addr_rc.rc_bdaddr, &bdaddress, sizeof(bdaddr_t)); break; case TYPE_SCO: struct sockaddr_sco addr_sco; addr = (struct sockaddr *)&addr_sco; addr_sz = sizeof(addr_sco); memset(addr, 0, addr_sz); addr_sco.sco_family = AF_BLUETOOTH; memcpy(&addr_sco.sco_bdaddr, &bdaddress, sizeof(bdaddr_t)); break; case TYPE_L2CAP: struct sockaddr_l2 addr_l2; addr = (struct sockaddr *)&addr_l2; addr_sz = sizeof(addr_l2); memset(addr, 0, addr_sz); addr_l2.l2_family = AF_BLUETOOTH; addr_l2.l2_psm = env->GetIntField(obj, field_mPort); memcpy(&addr_l2.l2_bdaddr, &bdaddress, sizeof(bdaddr_t)); break; default: jniThrowIOException(env, ENOSYS); return; } ret = asocket_connect(s, addr, addr_sz, -1); LOGV("...connect(%d, %s) = %d (errno %d)", s->fd, TYPE_AS_STR(type), ret, errno); if (ret) jniThrowIOException(env, errno); return; #endif jniThrowIOException(env, ENOSYS); }
static int handle_device (libusb_device *dev, struct libusb_config_descriptor *cfg, int itfnum, const struct libusb_interface_descriptor *alt) { libusb_device_handle *devh; int res, retval; retval = -1; if (libusb_open (dev, &devh) < 0) { g_warning ("Can't open device"); goto bail; } libusb_detach_kernel_driver (devh, itfnum); res = libusb_claim_interface (devh, itfnum); if (res < 0) { g_warning ("Can't claim interface %d", itfnum); goto bail; } if (option_get_master != FALSE) { if (show_master (devh, itfnum) == FALSE) goto bail; retval = 0; } if (option_master != NULL) { if (strcmp (option_master, "auto") == 0) { g_free (option_master); option_master = get_host_bdaddr (); if (option_master == NULL) { g_warning ("Can't get bdaddr from default device"); retval = -1; goto bail; } } } else { option_master = get_host_bdaddr (); if (option_master == NULL) { g_warning ("Can't get bdaddr from default device"); retval = -1; goto bail; } } if (option_store_info != FALSE) { sdp_record_t *rec; char *device; bdaddr_t dst, src; device = get_bdaddr (devh, itfnum); if (device == NULL) { retval = -1; goto bail; } rec = record_from_string (PS3_PNP_RECORD); store_record(option_master, device, rec); write_trust(option_master, device, "[all]", TRUE); store_device_id(option_master, device, 0xffff, 0x054c, 0x0268, 0); str2ba(option_master, &src); str2ba(device, &dst); write_device_profiles(&src, &dst, ""); write_device_name(&src, &dst, "PLAYSTATION(R)3 Controller"); sdp_record_free(rec); if (set_master_bdaddr (devh, itfnum, option_master) == FALSE) { retval = -1; goto bail; } } bail: libusb_release_interface (devh, itfnum); res = libusb_attach_kernel_driver(devh, itfnum); if (res < 0) { //FIXME sometimes the kernel tells us ENOENT, but succeeds anyway... g_warning ("Reattaching the driver failed: %d", res); } if (devh != NULL) libusb_close (devh); return retval; }