Пример #1
0
int connection_register(struct btd_service *service)
{
	struct btd_device *device = btd_service_get_device(service);
	struct network_peer *peer;
	struct network_conn *nc;
	uint16_t id = get_service_id(service);

	DBG("%s id %u", device_get_path(device), id);

	peer = find_peer(peers, device);
	if (!peer) {
		peer = create_peer(device);
		if (!peer)
			return -1;
		peers = g_slist_append(peers, peer);
	}

	nc = g_new0(struct network_conn, 1);
	nc->id = id;
	nc->service = btd_service_ref(service);
	nc->state = DISCONNECTED;
	nc->peer = peer;

	btd_service_set_user_data(service, nc);

	DBG("id %u registered", id);

	peer->connections = g_slist_append(peer->connections, nc);

	return 0;
}
Пример #2
0
static void source_set_state(struct source *source, source_state_t new_state)
{
	struct btd_device *dev = btd_service_get_device(source->service);
	source_state_t old_state = source->state;
	GSList *l;

	source->state = new_state;

	DBG("State changed %s: %s -> %s", device_get_path(dev),
				str_state[old_state], str_state[new_state]);

	for (l = source_callbacks; l != NULL; l = l->next) {
		struct source_state_callback *cb = l->data;

		if (cb->service != source->service)
			continue;

		cb->cb(source->service, old_state, new_state, cb->user_data);
	}

	if (new_state != SOURCE_STATE_DISCONNECTED)
		return;

	if (source->session) {
		avdtp_unref(source->session);
		source->session = NULL;
	}
}
Пример #3
0
static int gap_accept(struct btd_service *service)
{
	struct btd_device *device = btd_service_get_device(service);
	struct gatt_db *db = btd_device_get_gatt_db(device);
	struct bt_gatt_client *client = btd_device_get_gatt_client(device);
	struct gas *gas = btd_service_get_user_data(service);
	char addr[18];
	bt_uuid_t gap_uuid;

	ba2str(device_get_address(device), addr);
	DBG("GAP profile accept (%s)", addr);

	if (!gas) {
		error("GAP service not handled by profile");
		return -1;
	}

	gas->db = gatt_db_ref(db);
	gas->client = bt_gatt_client_ref(client);

	/* Handle the GAP services */
	bt_uuid16_create(&gap_uuid, GAP_UUID16);
	gatt_db_foreach_service(db, &gap_uuid, foreach_gap_service, gas);

	if (!gas->attr) {
		error("GAP attribute not found");
		gas_reset(gas);
		return -1;
	}

	btd_service_connecting_complete(service, 0);

	return 0;
}
static void csc_device_remove(struct btd_service *service)
{
	struct btd_device *device = btd_service_get_device(service);
	struct btd_adapter *adapter;
	struct csc_adapter *cadapter;
	struct csc *csc;
	GSList *l;

	adapter = device_get_adapter(device);

	cadapter = find_csc_adapter(adapter);
	if (cadapter == NULL)
		return;

	l = g_slist_find_custom(cadapter->devices, device, cmp_device);
	if (l == NULL)
		return;

	csc = l->data;

	cadapter->devices = g_slist_remove(cadapter->devices, csc);

	g_dbus_unregister_interface(btd_get_dbus_connection(),
						device_get_path(device),
						CYCLINGSPEED_INTERFACE);
}
Пример #5
0
int input_device_register(struct btd_service *service)
{
    struct btd_device *device = btd_service_get_device(service);
    const char *path = device_get_path(device);
    struct input_device *idev;

    DBG("%s", path);

    idev = input_device_new(service);
    if (!idev)
        return -EINVAL;

    if (g_dbus_register_interface(btd_get_dbus_connection(),
                                  idev->path, INPUT_INTERFACE,
                                  NULL, NULL,
                                  input_properties, idev,
                                  NULL) == FALSE) {
        error("Unable to register %s interface", INPUT_INTERFACE);
        input_device_free(idev);
        return -EINVAL;
    }

    btd_service_set_user_data(service, idev);

    return 0;
}
Пример #6
0
int source_connect(struct btd_service *service)
{
	struct source *source = btd_service_get_user_data(service);

	if (!source->session)
		source->session = a2dp_avdtp_get(btd_service_get_device(service));

	if (!source->session) {
		DBG("Unable to get a session");
		return -EIO;
	}

	if (source->connect_id > 0 || source->disconnect_id > 0)
		return -EBUSY;

	if (source->state == SOURCE_STATE_CONNECTING)
		return -EBUSY;

	if (source->stream_state >= AVDTP_STATE_OPEN)
		return -EALREADY;

	if (!source_setup_stream(service, NULL)) {
		DBG("Failed to create a stream");
		return -EIO;
	}

	DBG("stream creation in progress");

	return 0;
}
static void target_cb(struct btd_service *service,
						btd_service_state_t old_state,
						btd_service_state_t new_state)
{
	struct btd_device *dev = btd_service_get_device(service);
	struct policy_data *data;

	data = find_data(dev);
	if (data == NULL)
		return;

	switch (new_state) {
	case BTD_SERVICE_STATE_UNAVAILABLE:
	case BTD_SERVICE_STATE_DISCONNECTED:
		break;
	case BTD_SERVICE_STATE_CONNECTING:
		break;
	case BTD_SERVICE_STATE_CONNECTED:
		if (data->tg_timer > 0) {
			g_source_remove(data->tg_timer);
			data->tg_timer = 0;
		}
		break;
	case BTD_SERVICE_STATE_DISCONNECTING:
		break;
	}
}
Пример #8
0
static struct control *control_init(struct btd_service *service)
{
	struct control *control;
	struct btd_device *dev = btd_service_get_device(service);

	control = find_control(dev);
	if (control != NULL)
		return control;

	control = g_new0(struct control, 1);

	if (!g_dbus_register_interface(btd_get_dbus_connection(),
					device_get_path(dev),
					AUDIO_CONTROL_INTERFACE,
					control_methods, NULL,
					control_properties, control,
					path_unregister)) {
		g_free(control);
		return NULL;
	}

	DBG("Registered interface %s on path %s", AUDIO_CONTROL_INTERFACE,
							device_get_path(dev));

	control->dev = dev;
	control->avctp_id = avctp_add_state_cb(dev, state_changed, control);
	devices = g_slist_prepend(devices, control);

	return control;
}
static void source_cb(struct btd_service *service,
						btd_service_state_t old_state,
						btd_service_state_t new_state)
{
	struct btd_device *dev = btd_service_get_device(service);
	struct policy_data *data;
	struct btd_service *target;

	target = btd_device_get_service(dev, AVRCP_TARGET_UUID);
	if (target == NULL)
		return;

	data = policy_get_data(dev);

	switch (new_state) {
	case BTD_SERVICE_STATE_UNAVAILABLE:
	case BTD_SERVICE_STATE_DISCONNECTED:
		if (old_state == BTD_SERVICE_STATE_CONNECTING) {
			int err = btd_service_get_error(service);

			if (err == -EAGAIN) {
				if (data->source_retries < SOURCE_RETRIES)
					policy_set_source_timer(data);
				else
					data->source_retries = 0;
				break;
			} else if (data->source_timer > 0) {
				g_source_remove(data->source_timer);
				data->source_timer = 0;
			}
		}

		if (data->tg_timer > 0) {
			g_source_remove(data->tg_timer);
			data->tg_timer = 0;
		} else if (btd_service_get_state(target) !=
						BTD_SERVICE_STATE_DISCONNECTED)
			policy_disconnect(data, target);
		break;
	case BTD_SERVICE_STATE_CONNECTING:
		break;
	case BTD_SERVICE_STATE_CONNECTED:
		if (data->source_timer > 0) {
			g_source_remove(data->source_timer);
			data->source_timer = 0;
		}

		/* Check if service initiate the connection then proceed
		 * immediatelly otherwise set timer
		 */
		if (old_state == BTD_SERVICE_STATE_CONNECTING)
			policy_connect(data, target);
		else if (btd_service_get_state(target) !=
						BTD_SERVICE_STATE_CONNECTED)
			policy_set_tg_timer(data);
		break;
	case BTD_SERVICE_STATE_DISCONNECTING:
		break;
	}
}
static int hog_probe(struct btd_service *service)
{
    struct btd_device *device = btd_service_get_device(service);
    const char *path = device_get_path(device);
    GSList *primaries, *l;

    DBG("path %s", path);

    primaries = btd_device_get_primaries(device);
    if (primaries == NULL)
        return -EINVAL;

    for (l = primaries; l; l = g_slist_next(l)) {
        struct gatt_primary *prim = l->data;
        struct hog_device *dev;

        if (strcmp(prim->uuid, HOG_UUID) != 0)
            continue;

        dev = hog_device_new(device, prim);
        btd_service_set_user_data(service, dev);
        return 0;
    }

    return -EINVAL;
}
Пример #11
0
static struct input_device *input_device_new(struct btd_service *service)
{
    struct btd_device *device = btd_service_get_device(service);
    struct btd_profile *p = btd_service_get_profile(service);
    const char *path = device_get_path(device);
    const sdp_record_t *rec = btd_device_get_record(device, p->remote_uuid);
    struct btd_adapter *adapter = device_get_adapter(device);
    struct input_device *idev;
    char name[HCI_MAX_NAME_LENGTH + 1];

    idev = g_new0(struct input_device, 1);
    bacpy(&idev->src, btd_adapter_get_address(adapter));
    bacpy(&idev->dst, device_get_address(device));
    idev->service = btd_service_ref(service);
    idev->device = btd_device_ref(device);
    idev->path = g_strdup(path);
    idev->handle = rec->handle;
    idev->disable_sdp = is_device_sdp_disable(rec);

    device_get_name(device, name, HCI_MAX_NAME_LENGTH);
    if (strlen(name) > 0)
        idev->name = g_strdup(name);

    /* Initialize device properties */
    extract_hid_props(idev, rec);

    return idev;
}
Пример #12
0
static int gap_driver_probe(struct btd_service *service)
{
	struct btd_device *device = btd_service_get_device(service);
	struct gas *gas;
	GSList *l;
	char addr[18];

	ba2str(device_get_address(device), addr);
	DBG("GAP profile probe (%s)", addr);

	/* Ignore, if we were probed for this device already */
	l = g_slist_find_custom(devices, device, cmp_device);
	if (l) {
		error("Profile probed twice for the same device!");
		return -1;
	}

	gas = g_new0(struct gas, 1);
	if (!gas)
		return -1;

	gas->device = btd_device_ref(device);
	devices = g_slist_append(devices, gas);

	return 0;
}
Пример #13
0
static int a2dp_sink_probe(struct btd_service *service)
{
	struct btd_device *dev = btd_service_get_device(service);

	DBG("path %s", device_get_path(dev));

	return sink_init(service);
}
Пример #14
0
static int avrcp_remote_probe(struct btd_service *service)
{
	struct btd_device *dev = btd_service_get_device(service);

	DBG("path %s", device_get_path(dev));

	return control_init_remote(service);
}
Пример #15
0
void control_unregister(struct btd_service *service)
{
	struct btd_device *dev = btd_service_get_device(service);

	g_dbus_unregister_interface(btd_get_dbus_connection(),
						device_get_path(dev),
						AUDIO_CONTROL_INTERFACE);
}
Пример #16
0
void source_unregister(struct btd_service *service)
{
	struct btd_device *dev = btd_service_get_device(service);

	DBG("%s", device_get_path(dev));

	source_free(service);
}
Пример #17
0
static int avrcp_control_disconnect(struct btd_service *service)
{
	struct btd_device *dev = btd_service_get_device(service);
	const char *path = device_get_path(dev);

	DBG("path %s", path);

	return control_disconnect(service);
}
Пример #18
0
static int a2dp_sink_disconnect(struct btd_service *service)
{
	struct btd_device *dev = btd_service_get_device(service);
	const char *path = device_get_path(dev);

	DBG("path %s", path);

	return sink_disconnect(service, FALSE);
}
static void hog_remove(struct btd_service *service)
{
    struct hog_device *dev = btd_service_get_user_data(service);
    struct btd_device *device = btd_service_get_device(service);
    const char *path = device_get_path(device);

    DBG("path %s", path);

    hog_device_free(dev);
}
static struct reconnect_data *reconnect_add(struct btd_service *service)
{
	struct btd_device *dev = btd_service_get_device(service);
	struct reconnect_data *reconnect;

	reconnect = reconnect_find(dev);
	if (!reconnect) {
		reconnect = g_new0(struct reconnect_data, 1);
		reconnect->dev = dev;
		reconnects = g_slist_append(reconnects, reconnect);
	}
Пример #21
0
static int monitor_txpower_probe(struct btd_service *service)
{
	struct btd_device *device = btd_service_get_device(service);
	struct gatt_primary *txpower;

	txpower = btd_device_get_primary(device, TX_POWER_UUID);
	if (txpower == NULL)
		return -1;

	return monitor_register_txpower(device, &enabled, txpower);
}
Пример #22
0
static int monitor_linkloss_probe(struct btd_service *service)
{
	struct btd_device *device = btd_service_get_device(service);
	struct gatt_primary *linkloss;

	linkloss = btd_device_get_primary(device, LINK_LOSS_UUID);
	if (linkloss == NULL)
		return -1;

	return monitor_register_linkloss(device, &enabled, linkloss);
}
Пример #23
0
static int heartrate_device_probe(struct btd_service *service)
{
	struct btd_device *device = btd_service_get_device(service);
	struct gatt_primary *prim;

	prim = btd_device_get_primary(device, HEART_RATE_UUID);
	if (prim == NULL)
		return -EINVAL;

	return heartrate_device_register(device, prim);
}
Пример #24
0
static int monitor_immediate_probe(struct btd_service *service)
{
	struct btd_device *device = btd_service_get_device(service);
	struct gatt_primary *immediate;

	immediate = btd_device_get_primary(device, IMMEDIATE_ALERT_UUID);
	if (immediate == NULL)
		return -1;

	return monitor_register_immediate(device, &enabled, immediate);
}
Пример #25
0
static int deviceinfo_driver_probe(struct btd_service *service)
{
	struct btd_device *device = btd_service_get_device(service);
	struct gatt_primary *prim;

	prim = btd_device_get_primary(device, DEVICE_INFORMATION_UUID);
	if (prim == NULL)
		return -EINVAL;

	return deviceinfo_register(service, prim);
}
void reporter_device_remove(struct btd_service *service)
{
	struct btd_device *device = btd_service_get_device(service);
	struct reporter_adapter *radapter;
	struct btd_adapter *adapter = device_get_adapter(device);

	radapter = find_reporter_adapter(adapter);
	if (!radapter)
		return;

	unregister_reporter_device(device, radapter);
}
Пример #27
0
static int scan_param_probe(struct btd_service *service)
{
	struct btd_device *device = btd_service_get_device(service);
	struct gatt_primary *prim;

	DBG("Probing Scan Parameters");

	prim = btd_device_get_primary(device, SCAN_PARAMETERS_UUID);
	if (!prim)
		return -EINVAL;

	return scan_register(service, prim);
}
Пример #28
0
void input_device_unregister(struct btd_service *service)
{
    struct btd_device *device = btd_service_get_device(service);
    const char *path = device_get_path(device);
    struct input_device *idev = btd_service_get_user_data(service);

    DBG("%s", path);

    g_dbus_unregister_interface(btd_get_dbus_connection(),
                                idev->path, INPUT_INTERFACE);

    input_device_free(idev);
}
int reporter_device_probe(struct btd_service *service)
{
	struct btd_device *device = btd_service_get_device(service);
	struct reporter_adapter *radapter;
	struct btd_adapter *adapter = device_get_adapter(device);

	radapter = find_reporter_adapter(adapter);
	if (!radapter)
		return -1;

	register_reporter_device(device, radapter);

	return 0;
}
Пример #30
0
static void target_cb(struct btd_service *service,
						btd_service_state_t old_state,
						btd_service_state_t new_state)
{
	struct btd_device *dev = btd_service_get_device(service);
	struct policy_data *data;

	data = find_data(dev);
	if (data == NULL)
		return;

	switch (new_state) {
	case BTD_SERVICE_STATE_UNAVAILABLE:
		if (data->tg_timer > 0) {
			g_source_remove(data->tg_timer);
			data->tg_timer = 0;
		}
		break;
	case BTD_SERVICE_STATE_DISCONNECTED:
		if (old_state == BTD_SERVICE_STATE_CONNECTING) {
			int err = btd_service_get_error(service);

			if (err == -EAGAIN) {
				if (data->tg_retries < TG_RETRIES)
					policy_set_tg_timer(data,
							TG_RETRY_TIMEOUT);
				else
					data->tg_retries = 0;
				break;
			} else if (data->tg_timer > 0) {
				g_source_remove(data->tg_timer);
				data->tg_timer = 0;
			}
		} else if (old_state == BTD_SERVICE_STATE_CONNECTED) {
			data->tg_retries = 0;
		}
		break;
	case BTD_SERVICE_STATE_CONNECTING:
		break;
	case BTD_SERVICE_STATE_CONNECTED:
		if (data->tg_timer > 0) {
			g_source_remove(data->tg_timer);
			data->tg_timer = 0;
		}
		break;
	case BTD_SERVICE_STATE_DISCONNECTING:
		break;
	}
}