1e284789bd1748eb82035c54c9b3e6027010568b8Marcel Holtmann/*
2e284789bd1748eb82035c54c9b3e6027010568b8Marcel Holtmann *
3e284789bd1748eb82035c54c9b3e6027010568b8Marcel Holtmann *  BlueZ - Bluetooth protocol stack for Linux
4e284789bd1748eb82035c54c9b3e6027010568b8Marcel Holtmann *
55592142cb9383df0556b27ac59e96547b380310bJohan Hedberg *  Copyright (C) 2006-2010  Nokia Corporation
69184e2eeb7b97371c6b83b747c8984e2340d2b47Marcel Holtmann *  Copyright (C) 2004-2010  Marcel Holtmann <marcel@holtmann.org>
7607695ed109340f4b7a5628420e0a8e8aee34f4eMarcel Holtmann *  Copyright (C) 2005-2007  Johan Hedberg <johan.hedberg@nokia.com>
8e284789bd1748eb82035c54c9b3e6027010568b8Marcel Holtmann *
9e284789bd1748eb82035c54c9b3e6027010568b8Marcel Holtmann *
10e284789bd1748eb82035c54c9b3e6027010568b8Marcel Holtmann *  This program is free software; you can redistribute it and/or modify
11e284789bd1748eb82035c54c9b3e6027010568b8Marcel Holtmann *  it under the terms of the GNU General Public License as published by
12e284789bd1748eb82035c54c9b3e6027010568b8Marcel Holtmann *  the Free Software Foundation; either version 2 of the License, or
13e284789bd1748eb82035c54c9b3e6027010568b8Marcel Holtmann *  (at your option) any later version.
14e284789bd1748eb82035c54c9b3e6027010568b8Marcel Holtmann *
15e284789bd1748eb82035c54c9b3e6027010568b8Marcel Holtmann *  This program is distributed in the hope that it will be useful,
16e284789bd1748eb82035c54c9b3e6027010568b8Marcel Holtmann *  but WITHOUT ANY WARRANTY; without even the implied warranty of
17e284789bd1748eb82035c54c9b3e6027010568b8Marcel Holtmann *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18e284789bd1748eb82035c54c9b3e6027010568b8Marcel Holtmann *  GNU General Public License for more details.
19e284789bd1748eb82035c54c9b3e6027010568b8Marcel Holtmann *
20e284789bd1748eb82035c54c9b3e6027010568b8Marcel Holtmann *  You should have received a copy of the GNU General Public License
21e284789bd1748eb82035c54c9b3e6027010568b8Marcel Holtmann *  along with this program; if not, write to the Free Software
22e284789bd1748eb82035c54c9b3e6027010568b8Marcel Holtmann *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
23e284789bd1748eb82035c54c9b3e6027010568b8Marcel Holtmann *
24e284789bd1748eb82035c54c9b3e6027010568b8Marcel Holtmann */
25e284789bd1748eb82035c54c9b3e6027010568b8Marcel Holtmann
26e284789bd1748eb82035c54c9b3e6027010568b8Marcel Holtmann#ifdef HAVE_CONFIG_H
27e284789bd1748eb82035c54c9b3e6027010568b8Marcel Holtmann#include <config.h>
28e284789bd1748eb82035c54c9b3e6027010568b8Marcel Holtmann#endif
29e284789bd1748eb82035c54c9b3e6027010568b8Marcel Holtmann
30e284789bd1748eb82035c54c9b3e6027010568b8Marcel Holtmann#include <stdio.h>
310df89f0370532854e929d68ef2836a84693acd65Marcel Holtmann#include <errno.h>
3245df23c4593250e58e355bf3cde15abb2d6d4c3cJohan Hedberg#include <stdlib.h>
3345df23c4593250e58e355bf3cde15abb2d6d4c3cJohan Hedberg#include <string.h>
346af2f85288b058b3a575622b01af6869100a7398Johan Hedberg#include <unistd.h>
351badf196a83fb8d32e212c49b7487b08962c18f0Johan Hedberg#include <sys/ioctl.h>
3645df23c4593250e58e355bf3cde15abb2d6d4c3cJohan Hedberg
376af2f85288b058b3a575622b01af6869100a7398Johan Hedberg#include <bluetooth/bluetooth.h>
38a92ba8bfd77ffa09d2cd0809f801eff0984a11d8Claudio Takahasi
398cc5595d9091b484b9a4abe314c0f3ec055e0581Marcel Holtmann#include <glib.h>
4045df23c4593250e58e355bf3cde15abb2d6d4c3cJohan Hedberg#include <dbus/dbus.h>
4133191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann#include <gdbus.h>
4233191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann
43e891f7df6225c758da0d95f7554c6cc67f72f31eGustavo F. Padovan#include "log.h"
44bae34785e2fb371509eb0a2c7529f0fe2454dde8Claudio Takahasi
453b320a0355706a98f824f4d0abf2d14f820bbd81Marcel Holtmann#include "adapter.h"
464efb97bdae52e601dfcf1627e39d1e652457c53cJohan Hedberg#include "manager.h"
4716d507e0bb939b1c98f9d5ab14c656339757b878Johan Hedberg#include "event.h"
48e54736f31acc8d26d1f1e4a8b06ed66d258a24efJohan Hedberg#include "dbus-common.h"
4945df23c4593250e58e355bf3cde15abb2d6d4c3cJohan Hedberg
5060b71acf62e1245dc2c036624aa90afcc646855aJohan Hedbergstatic DBusConnection *connection = NULL;
5160b71acf62e1245dc2c036624aa90afcc646855aJohan Hedberg
5258f06324289d7d343a52a9104d02121cb8db1047Johan Hedbergstatic void append_variant(DBusMessageIter *iter, int type, void *val)
5322ec945f109d9d1e21a8cfbc6e2dec3dd4b88c8eMarcel Holtmann{
5422ec945f109d9d1e21a8cfbc6e2dec3dd4b88c8eMarcel Holtmann	DBusMessageIter value;
5558f06324289d7d343a52a9104d02121cb8db1047Johan Hedberg	char sig[2] = { type, '\0' };
5622ec945f109d9d1e21a8cfbc6e2dec3dd4b88c8eMarcel Holtmann
5722ec945f109d9d1e21a8cfbc6e2dec3dd4b88c8eMarcel Holtmann	dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT, sig, &value);
5822ec945f109d9d1e21a8cfbc6e2dec3dd4b88c8eMarcel Holtmann
5958f06324289d7d343a52a9104d02121cb8db1047Johan Hedberg	dbus_message_iter_append_basic(&value, type, val);
6058f06324289d7d343a52a9104d02121cb8db1047Johan Hedberg
6158f06324289d7d343a52a9104d02121cb8db1047Johan Hedberg	dbus_message_iter_close_container(iter, &value);
6258f06324289d7d343a52a9104d02121cb8db1047Johan Hedberg}
6322ec945f109d9d1e21a8cfbc6e2dec3dd4b88c8eMarcel Holtmann
64d5e700051b1263b2028331d41d60de02a5a6f90eVinicius Costa Gomesstatic void append_array_variant(DBusMessageIter *iter, int type, void *val,
65d5e700051b1263b2028331d41d60de02a5a6f90eVinicius Costa Gomes							int n_elements)
6658f06324289d7d343a52a9104d02121cb8db1047Johan Hedberg{
6758f06324289d7d343a52a9104d02121cb8db1047Johan Hedberg	DBusMessageIter variant, array;
6858f06324289d7d343a52a9104d02121cb8db1047Johan Hedberg	char type_sig[2] = { type, '\0' };
6958f06324289d7d343a52a9104d02121cb8db1047Johan Hedberg	char array_sig[3] = { DBUS_TYPE_ARRAY, type, '\0' };
7022ec945f109d9d1e21a8cfbc6e2dec3dd4b88c8eMarcel Holtmann
7158f06324289d7d343a52a9104d02121cb8db1047Johan Hedberg	dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT,
7258f06324289d7d343a52a9104d02121cb8db1047Johan Hedberg						array_sig, &variant);
7322ec945f109d9d1e21a8cfbc6e2dec3dd4b88c8eMarcel Holtmann
7458f06324289d7d343a52a9104d02121cb8db1047Johan Hedberg	dbus_message_iter_open_container(&variant, DBUS_TYPE_ARRAY,
7558f06324289d7d343a52a9104d02121cb8db1047Johan Hedberg						type_sig, &array);
7622ec945f109d9d1e21a8cfbc6e2dec3dd4b88c8eMarcel Holtmann
77af7fcf80c3c9c37e00deb2b73f427581c2d27cc2Luiz Augusto von Dentz	if (dbus_type_is_fixed(type) == TRUE) {
78af7fcf80c3c9c37e00deb2b73f427581c2d27cc2Luiz Augusto von Dentz		dbus_message_iter_append_fixed_array(&array, type, val,
79af7fcf80c3c9c37e00deb2b73f427581c2d27cc2Luiz Augusto von Dentz							n_elements);
80af7fcf80c3c9c37e00deb2b73f427581c2d27cc2Luiz Augusto von Dentz	} else if (type == DBUS_TYPE_STRING || type == DBUS_TYPE_OBJECT_PATH) {
81af7fcf80c3c9c37e00deb2b73f427581c2d27cc2Luiz Augusto von Dentz		const char ***str_array = val;
82af7fcf80c3c9c37e00deb2b73f427581c2d27cc2Luiz Augusto von Dentz		int i;
83af7fcf80c3c9c37e00deb2b73f427581c2d27cc2Luiz Augusto von Dentz
84af7fcf80c3c9c37e00deb2b73f427581c2d27cc2Luiz Augusto von Dentz		for (i = 0; i < n_elements; i++)
85af7fcf80c3c9c37e00deb2b73f427581c2d27cc2Luiz Augusto von Dentz			dbus_message_iter_append_basic(&array, type,
86af7fcf80c3c9c37e00deb2b73f427581c2d27cc2Luiz Augusto von Dentz							&((*str_array)[i]));
87af7fcf80c3c9c37e00deb2b73f427581c2d27cc2Luiz Augusto von Dentz	}
8858f06324289d7d343a52a9104d02121cb8db1047Johan Hedberg
8958f06324289d7d343a52a9104d02121cb8db1047Johan Hedberg	dbus_message_iter_close_container(&variant, &array);
9058f06324289d7d343a52a9104d02121cb8db1047Johan Hedberg
9158f06324289d7d343a52a9104d02121cb8db1047Johan Hedberg	dbus_message_iter_close_container(iter, &variant);
9222ec945f109d9d1e21a8cfbc6e2dec3dd4b88c8eMarcel Holtmann}
9322ec945f109d9d1e21a8cfbc6e2dec3dd4b88c8eMarcel Holtmann
941262c4767c74f084d37c84bec778513f3d862a3eJohan Hedbergvoid dict_append_entry(DBusMessageIter *dict,
951262c4767c74f084d37c84bec778513f3d862a3eJohan Hedberg			const char *key, int type, void *val)
9622ec945f109d9d1e21a8cfbc6e2dec3dd4b88c8eMarcel Holtmann{
9722ec945f109d9d1e21a8cfbc6e2dec3dd4b88c8eMarcel Holtmann	DBusMessageIter entry;
9822ec945f109d9d1e21a8cfbc6e2dec3dd4b88c8eMarcel Holtmann
99b23b2074154582ef796b30879f36c82eeb077e0bMarcel Holtmann	if (type == DBUS_TYPE_STRING) {
100b23b2074154582ef796b30879f36c82eeb077e0bMarcel Holtmann		const char *str = *((const char **) val);
101b23b2074154582ef796b30879f36c82eeb077e0bMarcel Holtmann		if (str == NULL)
102b23b2074154582ef796b30879f36c82eeb077e0bMarcel Holtmann			return;
103b23b2074154582ef796b30879f36c82eeb077e0bMarcel Holtmann	}
104b23b2074154582ef796b30879f36c82eeb077e0bMarcel Holtmann
10522ec945f109d9d1e21a8cfbc6e2dec3dd4b88c8eMarcel Holtmann	dbus_message_iter_open_container(dict, DBUS_TYPE_DICT_ENTRY,
10622ec945f109d9d1e21a8cfbc6e2dec3dd4b88c8eMarcel Holtmann							NULL, &entry);
10722ec945f109d9d1e21a8cfbc6e2dec3dd4b88c8eMarcel Holtmann
10822ec945f109d9d1e21a8cfbc6e2dec3dd4b88c8eMarcel Holtmann	dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &key);
10922ec945f109d9d1e21a8cfbc6e2dec3dd4b88c8eMarcel Holtmann
11058f06324289d7d343a52a9104d02121cb8db1047Johan Hedberg	append_variant(&entry, type, val);
11122ec945f109d9d1e21a8cfbc6e2dec3dd4b88c8eMarcel Holtmann
11222ec945f109d9d1e21a8cfbc6e2dec3dd4b88c8eMarcel Holtmann	dbus_message_iter_close_container(dict, &entry);
11322ec945f109d9d1e21a8cfbc6e2dec3dd4b88c8eMarcel Holtmann}
11422ec945f109d9d1e21a8cfbc6e2dec3dd4b88c8eMarcel Holtmann
1153a11e84a573785024b11d89ed4f9b06e43b06ca6Johan Hedbergvoid dict_append_array(DBusMessageIter *dict, const char *key, int type,
1163a11e84a573785024b11d89ed4f9b06e43b06ca6Johan Hedberg			void *val, int n_elements)
1173a11e84a573785024b11d89ed4f9b06e43b06ca6Johan Hedberg{
11858f06324289d7d343a52a9104d02121cb8db1047Johan Hedberg	DBusMessageIter entry;
1193a11e84a573785024b11d89ed4f9b06e43b06ca6Johan Hedberg
1203a11e84a573785024b11d89ed4f9b06e43b06ca6Johan Hedberg	dbus_message_iter_open_container(dict, DBUS_TYPE_DICT_ENTRY,
1213a11e84a573785024b11d89ed4f9b06e43b06ca6Johan Hedberg						NULL, &entry);
1223a11e84a573785024b11d89ed4f9b06e43b06ca6Johan Hedberg
1233a11e84a573785024b11d89ed4f9b06e43b06ca6Johan Hedberg	dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &key);
1243a11e84a573785024b11d89ed4f9b06e43b06ca6Johan Hedberg
125d5e700051b1263b2028331d41d60de02a5a6f90eVinicius Costa Gomes	append_array_variant(&entry, type, val, n_elements);
1263a11e84a573785024b11d89ed4f9b06e43b06ca6Johan Hedberg
12758f06324289d7d343a52a9104d02121cb8db1047Johan Hedberg	dbus_message_iter_close_container(dict, &entry);
12858f06324289d7d343a52a9104d02121cb8db1047Johan Hedberg}
1293a11e84a573785024b11d89ed4f9b06e43b06ca6Johan Hedberg
13058f06324289d7d343a52a9104d02121cb8db1047Johan Hedbergdbus_bool_t emit_property_changed(DBusConnection *conn,
13158f06324289d7d343a52a9104d02121cb8db1047Johan Hedberg					const char *path,
13258f06324289d7d343a52a9104d02121cb8db1047Johan Hedberg					const char *interface,
13358f06324289d7d343a52a9104d02121cb8db1047Johan Hedberg					const char *name,
13458f06324289d7d343a52a9104d02121cb8db1047Johan Hedberg					int type, void *value)
13558f06324289d7d343a52a9104d02121cb8db1047Johan Hedberg{
13658f06324289d7d343a52a9104d02121cb8db1047Johan Hedberg	DBusMessage *signal;
13758f06324289d7d343a52a9104d02121cb8db1047Johan Hedberg	DBusMessageIter iter;
1383a11e84a573785024b11d89ed4f9b06e43b06ca6Johan Hedberg
13958f06324289d7d343a52a9104d02121cb8db1047Johan Hedberg	signal = dbus_message_new_signal(path, interface, "PropertyChanged");
1403a11e84a573785024b11d89ed4f9b06e43b06ca6Johan Hedberg
14158f06324289d7d343a52a9104d02121cb8db1047Johan Hedberg	if (!signal) {
14258f06324289d7d343a52a9104d02121cb8db1047Johan Hedberg		error("Unable to allocate new %s.PropertyChanged signal",
14358f06324289d7d343a52a9104d02121cb8db1047Johan Hedberg				interface);
14458f06324289d7d343a52a9104d02121cb8db1047Johan Hedberg		return FALSE;
14558f06324289d7d343a52a9104d02121cb8db1047Johan Hedberg	}
1463a11e84a573785024b11d89ed4f9b06e43b06ca6Johan Hedberg
14758f06324289d7d343a52a9104d02121cb8db1047Johan Hedberg	dbus_message_iter_init_append(signal, &iter);
14858f06324289d7d343a52a9104d02121cb8db1047Johan Hedberg
14958f06324289d7d343a52a9104d02121cb8db1047Johan Hedberg	dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &name);
15058f06324289d7d343a52a9104d02121cb8db1047Johan Hedberg
15158f06324289d7d343a52a9104d02121cb8db1047Johan Hedberg	append_variant(&iter, type, value);
15258f06324289d7d343a52a9104d02121cb8db1047Johan Hedberg
153a5883ecb1aa94b09bcf0e7ce4184d262027c5939Johan Hedberg	return g_dbus_send_message(conn, signal);
1543a11e84a573785024b11d89ed4f9b06e43b06ca6Johan Hedberg}
1553a11e84a573785024b11d89ed4f9b06e43b06ca6Johan Hedberg
15658f06324289d7d343a52a9104d02121cb8db1047Johan Hedbergdbus_bool_t emit_array_property_changed(DBusConnection *conn,
157c0736ea762bfea95e98c8b9f118b4e5464f2159cJohan Hedberg					const char *path,
158c0736ea762bfea95e98c8b9f118b4e5464f2159cJohan Hedberg					const char *interface,
159c0736ea762bfea95e98c8b9f118b4e5464f2159cJohan Hedberg					const char *name,
160d5e700051b1263b2028331d41d60de02a5a6f90eVinicius Costa Gomes					int type, void *value, int num)
16122ec945f109d9d1e21a8cfbc6e2dec3dd4b88c8eMarcel Holtmann{
16222ec945f109d9d1e21a8cfbc6e2dec3dd4b88c8eMarcel Holtmann	DBusMessage *signal;
16322ec945f109d9d1e21a8cfbc6e2dec3dd4b88c8eMarcel Holtmann	DBusMessageIter iter;
16422ec945f109d9d1e21a8cfbc6e2dec3dd4b88c8eMarcel Holtmann
16522ec945f109d9d1e21a8cfbc6e2dec3dd4b88c8eMarcel Holtmann	signal = dbus_message_new_signal(path, interface, "PropertyChanged");
16622ec945f109d9d1e21a8cfbc6e2dec3dd4b88c8eMarcel Holtmann
16722ec945f109d9d1e21a8cfbc6e2dec3dd4b88c8eMarcel Holtmann	if (!signal) {
16822ec945f109d9d1e21a8cfbc6e2dec3dd4b88c8eMarcel Holtmann		error("Unable to allocate new %s.PropertyChanged signal",
16922ec945f109d9d1e21a8cfbc6e2dec3dd4b88c8eMarcel Holtmann				interface);
17022ec945f109d9d1e21a8cfbc6e2dec3dd4b88c8eMarcel Holtmann		return FALSE;
17122ec945f109d9d1e21a8cfbc6e2dec3dd4b88c8eMarcel Holtmann	}
17222ec945f109d9d1e21a8cfbc6e2dec3dd4b88c8eMarcel Holtmann
17322ec945f109d9d1e21a8cfbc6e2dec3dd4b88c8eMarcel Holtmann	dbus_message_iter_init_append(signal, &iter);
17422ec945f109d9d1e21a8cfbc6e2dec3dd4b88c8eMarcel Holtmann
17522ec945f109d9d1e21a8cfbc6e2dec3dd4b88c8eMarcel Holtmann	dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &name);
17658f06324289d7d343a52a9104d02121cb8db1047Johan Hedberg
177d5e700051b1263b2028331d41d60de02a5a6f90eVinicius Costa Gomes	append_array_variant(&iter, type, value, num);
17822ec945f109d9d1e21a8cfbc6e2dec3dd4b88c8eMarcel Holtmann
179a5883ecb1aa94b09bcf0e7ce4184d262027c5939Johan Hedberg	return g_dbus_send_message(conn, signal);
18022ec945f109d9d1e21a8cfbc6e2dec3dd4b88c8eMarcel Holtmann}
18160b71acf62e1245dc2c036624aa90afcc646855aJohan Hedberg
18260b71acf62e1245dc2c036624aa90afcc646855aJohan Hedbergvoid set_dbus_connection(DBusConnection *conn)
18360b71acf62e1245dc2c036624aa90afcc646855aJohan Hedberg{
18460b71acf62e1245dc2c036624aa90afcc646855aJohan Hedberg	connection = conn;
18560b71acf62e1245dc2c036624aa90afcc646855aJohan Hedberg}
18660b71acf62e1245dc2c036624aa90afcc646855aJohan Hedberg
18760b71acf62e1245dc2c036624aa90afcc646855aJohan HedbergDBusConnection *get_dbus_connection(void)
18860b71acf62e1245dc2c036624aa90afcc646855aJohan Hedberg{
18960b71acf62e1245dc2c036624aa90afcc646855aJohan Hedberg	return connection;
19060b71acf62e1245dc2c036624aa90afcc646855aJohan Hedberg}
1917dd1803f5c49c3168e36e1f99f3481c06b09a6f5Johan Hedberg
1927dd1803f5c49c3168e36e1f99f3481c06b09a6f5Johan Hedbergconst char *class_to_icon(uint32_t class)
1937dd1803f5c49c3168e36e1f99f3481c06b09a6f5Johan Hedberg{
1947dd1803f5c49c3168e36e1f99f3481c06b09a6f5Johan Hedberg	switch ((class & 0x1f00) >> 8) {
1957dd1803f5c49c3168e36e1f99f3481c06b09a6f5Johan Hedberg	case 0x01:
1967dd1803f5c49c3168e36e1f99f3481c06b09a6f5Johan Hedberg		return "computer";
1977dd1803f5c49c3168e36e1f99f3481c06b09a6f5Johan Hedberg	case 0x02:
1987dd1803f5c49c3168e36e1f99f3481c06b09a6f5Johan Hedberg		switch ((class & 0xfc) >> 2) {
1997dd1803f5c49c3168e36e1f99f3481c06b09a6f5Johan Hedberg		case 0x01:
2007dd1803f5c49c3168e36e1f99f3481c06b09a6f5Johan Hedberg		case 0x02:
2017dd1803f5c49c3168e36e1f99f3481c06b09a6f5Johan Hedberg		case 0x03:
2027dd1803f5c49c3168e36e1f99f3481c06b09a6f5Johan Hedberg		case 0x05:
2037dd1803f5c49c3168e36e1f99f3481c06b09a6f5Johan Hedberg			return "phone";
2047dd1803f5c49c3168e36e1f99f3481c06b09a6f5Johan Hedberg		case 0x04:
2057dd1803f5c49c3168e36e1f99f3481c06b09a6f5Johan Hedberg			return "modem";
2067dd1803f5c49c3168e36e1f99f3481c06b09a6f5Johan Hedberg		}
2077dd1803f5c49c3168e36e1f99f3481c06b09a6f5Johan Hedberg		break;
2087dd1803f5c49c3168e36e1f99f3481c06b09a6f5Johan Hedberg	case 0x03:
2097dd1803f5c49c3168e36e1f99f3481c06b09a6f5Johan Hedberg		return "network-wireless";
2107dd1803f5c49c3168e36e1f99f3481c06b09a6f5Johan Hedberg	case 0x04:
2117dd1803f5c49c3168e36e1f99f3481c06b09a6f5Johan Hedberg		switch ((class & 0xfc) >> 2) {
2127dd1803f5c49c3168e36e1f99f3481c06b09a6f5Johan Hedberg		case 0x01:
2137dd1803f5c49c3168e36e1f99f3481c06b09a6f5Johan Hedberg		case 0x02:
2147dd1803f5c49c3168e36e1f99f3481c06b09a6f5Johan Hedberg			return "audio-card";	/* Headset */
2157dd1803f5c49c3168e36e1f99f3481c06b09a6f5Johan Hedberg		case 0x06:
2167dd1803f5c49c3168e36e1f99f3481c06b09a6f5Johan Hedberg			return "audio-card";	/* Headphone */
2177dd1803f5c49c3168e36e1f99f3481c06b09a6f5Johan Hedberg		case 0x0b: /* VCR */
2187dd1803f5c49c3168e36e1f99f3481c06b09a6f5Johan Hedberg		case 0x0c: /* Video Camera */
2197dd1803f5c49c3168e36e1f99f3481c06b09a6f5Johan Hedberg		case 0x0d: /* Camcorder */
2207dd1803f5c49c3168e36e1f99f3481c06b09a6f5Johan Hedberg			return "camera-video";
2217dd1803f5c49c3168e36e1f99f3481c06b09a6f5Johan Hedberg		default:
2227dd1803f5c49c3168e36e1f99f3481c06b09a6f5Johan Hedberg			return "audio-card";	/* Other audio device */
2237dd1803f5c49c3168e36e1f99f3481c06b09a6f5Johan Hedberg		}
2247dd1803f5c49c3168e36e1f99f3481c06b09a6f5Johan Hedberg		break;
2257dd1803f5c49c3168e36e1f99f3481c06b09a6f5Johan Hedberg	case 0x05:
2267dd1803f5c49c3168e36e1f99f3481c06b09a6f5Johan Hedberg		switch ((class & 0xc0) >> 6) {
2277dd1803f5c49c3168e36e1f99f3481c06b09a6f5Johan Hedberg		case 0x00:
2287dd1803f5c49c3168e36e1f99f3481c06b09a6f5Johan Hedberg			switch ((class & 0x1e) >> 2) {
2297dd1803f5c49c3168e36e1f99f3481c06b09a6f5Johan Hedberg			case 0x01:
2307dd1803f5c49c3168e36e1f99f3481c06b09a6f5Johan Hedberg			case 0x02:
2317dd1803f5c49c3168e36e1f99f3481c06b09a6f5Johan Hedberg				return "input-gaming";
2327dd1803f5c49c3168e36e1f99f3481c06b09a6f5Johan Hedberg			}
2337dd1803f5c49c3168e36e1f99f3481c06b09a6f5Johan Hedberg			break;
2347dd1803f5c49c3168e36e1f99f3481c06b09a6f5Johan Hedberg		case 0x01:
2357dd1803f5c49c3168e36e1f99f3481c06b09a6f5Johan Hedberg			return "input-keyboard";
2367dd1803f5c49c3168e36e1f99f3481c06b09a6f5Johan Hedberg		case 0x02:
2377dd1803f5c49c3168e36e1f99f3481c06b09a6f5Johan Hedberg			switch ((class & 0x1e) >> 2) {
2387dd1803f5c49c3168e36e1f99f3481c06b09a6f5Johan Hedberg			case 0x05:
2397dd1803f5c49c3168e36e1f99f3481c06b09a6f5Johan Hedberg				return "input-tablet";
2407dd1803f5c49c3168e36e1f99f3481c06b09a6f5Johan Hedberg			default:
2417dd1803f5c49c3168e36e1f99f3481c06b09a6f5Johan Hedberg				return "input-mouse";
2427dd1803f5c49c3168e36e1f99f3481c06b09a6f5Johan Hedberg			}
2437dd1803f5c49c3168e36e1f99f3481c06b09a6f5Johan Hedberg		}
2447dd1803f5c49c3168e36e1f99f3481c06b09a6f5Johan Hedberg		break;
2457dd1803f5c49c3168e36e1f99f3481c06b09a6f5Johan Hedberg	case 0x06:
2467dd1803f5c49c3168e36e1f99f3481c06b09a6f5Johan Hedberg		if (class & 0x80)
2477dd1803f5c49c3168e36e1f99f3481c06b09a6f5Johan Hedberg			return "printer";
2487dd1803f5c49c3168e36e1f99f3481c06b09a6f5Johan Hedberg		if (class & 0x20)
2497dd1803f5c49c3168e36e1f99f3481c06b09a6f5Johan Hedberg			return "camera-photo";
2507dd1803f5c49c3168e36e1f99f3481c06b09a6f5Johan Hedberg		break;
2517dd1803f5c49c3168e36e1f99f3481c06b09a6f5Johan Hedberg	}
2527dd1803f5c49c3168e36e1f99f3481c06b09a6f5Johan Hedberg
2537dd1803f5c49c3168e36e1f99f3481c06b09a6f5Johan Hedberg	return NULL;
2547dd1803f5c49c3168e36e1f99f3481c06b09a6f5Johan Hedberg}
255