static void connect_cb(GIOChannel *chan, GError *err, gpointer user_data)
{
	struct hid_device *dev;
	bdaddr_t src, dst;
	char address[18];
	uint16_t psm;
	GError *gerr = NULL;
	GSList *l;
	uuid_t uuid;

	if (err) {
		error("%s", err->message);
		return;
	}

	bt_io_get(chan, &gerr,
			BT_IO_OPT_SOURCE_BDADDR, &src,
			BT_IO_OPT_DEST_BDADDR, &dst,
			BT_IO_OPT_PSM, &psm,
			BT_IO_OPT_INVALID);
	if (gerr) {
		error("%s", gerr->message);
		g_io_channel_shutdown(chan, TRUE, NULL);
		g_error_free(gerr);
		return;
	}

	ba2str(&dst, address);
	DBG("Incoming connection from %s on PSM %d", address, psm);

	switch (psm) {
	case L2CAP_PSM_HIDP_CTRL:
		l = g_slist_find_custom(devices, &dst, device_cmp);
		if (l)
			return;

		dev = g_new0(struct hid_device, 1);
		bacpy(&dev->dst, &dst);
		dev->ctrl_io = g_io_channel_ref(chan);
		dev->uhid_fd = -1;

		bt_string2uuid(&uuid, HID_UUID);
		if (bt_search_service(&src, &dev->dst, &uuid,
					hid_sdp_search_cb, dev, NULL, 0) < 0) {
			error("failed to search sdp details");
			hid_device_free(dev);
			return;
		}

		devices = g_slist_append(devices, dev);

		dev->ctrl_watch = g_io_add_watch(dev->ctrl_io,
					G_IO_HUP | G_IO_ERR | G_IO_NVAL,
					ctrl_watch_cb, dev);
		bt_hid_notify_state(dev, HAL_HIDHOST_STATE_CONNECTING);
		break;

	case L2CAP_PSM_HIDP_INTR:
		l = g_slist_find_custom(devices, &dst, device_cmp);
		if (!l)
			return;

		dev = l->data;
		dev->intr_io = g_io_channel_ref(chan);
		dev->intr_watch = g_io_add_watch(dev->intr_io,
				G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
				intr_watch_cb, dev);
		bt_hid_notify_state(dev, HAL_HIDHOST_STATE_CONNECTED);
		break;
	}
}
Beispiel #2
0
static void handle_uuid(const char *uuidstr, struct audio_device *device)
{
	uuid_t uuid;
	uint16_t uuid16;

	if (bt_string2uuid(&uuid, uuidstr) < 0) {
		error("%s not detected as an UUID-128", uuidstr);
		return;
	}

	if (!sdp_uuid128_to_uuid(&uuid) && uuid.type != SDP_UUID16) {
		error("Could not convert %s to a UUID-16", uuidstr);
		return;
	}

	uuid16 = uuid.value.uuid16;

	if (!server_is_enabled(&device->src, uuid16)) {
		DBG("server not enabled for %s (0x%04x)", uuidstr, uuid16);
		return;
	}

	switch (uuid16) {
	case HEADSET_SVCLASS_ID:
		DBG("Found Headset record");
		if (device->headset)
			headset_update(device, uuid16, uuidstr);
		else
			device->headset = headset_init(device, uuid16,
							uuidstr);
		break;
	case HEADSET_AGW_SVCLASS_ID:
		DBG("Found Headset AG record");
		break;
	case HANDSFREE_SVCLASS_ID:
		DBG("Found Handsfree record");
		if (device->headset)
			headset_update(device, uuid16, uuidstr);
		else
			device->headset = headset_init(device, uuid16,
								uuidstr);
		break;
	case HANDSFREE_AGW_SVCLASS_ID:
		DBG("Found Handsfree AG record");
		if (enabled.gateway && (device->gateway == NULL))
			device->gateway = gateway_init(device);
		break;
	case AUDIO_SINK_SVCLASS_ID:
		DBG("Found Audio Sink");
		if (device->sink == NULL)
			device->sink = sink_init(device);
		break;
	case AUDIO_SOURCE_SVCLASS_ID:
		DBG("Found Audio Source");
		if (device->source == NULL)
			device->source = source_init(device);
		break;
	case AV_REMOTE_SVCLASS_ID:
	case AV_REMOTE_TARGET_SVCLASS_ID:
		DBG("Found AV %s", uuid16 == AV_REMOTE_SVCLASS_ID ?
							"Remote" : "Target");
		if (device->control)
			control_update(device, uuid16);
		else
			device->control = control_init(device, uuid16);
		/* SS_Bluetooth(sunjo4.kim) 2012.2.16 - add for a2dp connect fail */
		//if (device->sink && sink_is_active(device))
		//	avrcp_connect(device);
                /* SS_Bluetooth(sunjo4.kim) End */
		break;
	default:
		DBG("Unrecognized UUID: 0x%04X", uuid16);
		break;
	}
}