Blame lib/bluetooth-utils.c

Packit 8fb625
/*
Packit 8fb625
 *
Packit 8fb625
 *  BlueZ - Bluetooth protocol stack for Linux
Packit 8fb625
 *
Packit 8fb625
 *  Copyright (C) 2009-2011  Bastien Nocera <hadess@hadess.net>
Packit 8fb625
 *  Copyright (C) 2010       Giovanni Campagna <scampa.giovanni@gmail.com>
Packit 8fb625
 *
Packit 8fb625
 *
Packit 8fb625
 *  This library is free software; you can redistribute it and/or
Packit 8fb625
 *  modify it under the terms of the GNU Lesser General Public
Packit 8fb625
 *  License as published by the Free Software Foundation; either
Packit 8fb625
 *  version 2.1 of the License, or (at your option) any later version.
Packit 8fb625
 *
Packit 8fb625
 *  This library is distributed in the hope that it will be useful,
Packit 8fb625
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 8fb625
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit 8fb625
 *  Lesser General Public License for more details.
Packit 8fb625
 *
Packit 8fb625
 *  You should have received a copy of the GNU Lesser General Public
Packit 8fb625
 *  License along with this library; if not, write to the Free Software
Packit 8fb625
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
Packit 8fb625
 *
Packit 8fb625
 */
Packit 8fb625
Packit 8fb625
/**
Packit 8fb625
 * SECTION:bluetooth-utils
Packit 8fb625
 * @short_description: Bluetooth utility functions
Packit 8fb625
 * @stability: Stable
Packit 8fb625
 * @include: bluetooth-utils.h
Packit 8fb625
 *
Packit 8fb625
 * Those helper functions are used throughout the Bluetooth
Packit 8fb625
 * management utilities.
Packit 8fb625
 **/
Packit 8fb625
Packit 8fb625
#ifdef HAVE_CONFIG_H
Packit 8fb625
#include <config.h>
Packit 8fb625
#endif
Packit 8fb625
Packit 8fb625
#include <glib/gi18n-lib.h>
Packit 8fb625
#include <gtk/gtk.h>
Packit 8fb625
Packit 8fb625
#include "bluetooth-utils.h"
Packit 8fb625
#include "gnome-bluetooth-enum-types.h"
Packit 8fb625
Packit 8fb625
/**
Packit 8fb625
 * bluetooth_type_to_string:
Packit 8fb625
 * @type: a #BluetoothType
Packit 8fb625
 *
Packit 8fb625
 * Returns a human-readable string representation of @type usable for display to users. Do not free the return value.
Packit 8fb625
 * The returned string is already translated with gettext().
Packit 8fb625
 *
Packit 8fb625
 * Return value: a string.
Packit 8fb625
 **/
Packit 8fb625
const gchar *
Packit 8fb625
bluetooth_type_to_string (BluetoothType type)
Packit 8fb625
{
Packit 8fb625
	switch (type) {
Packit 8fb625
	case BLUETOOTH_TYPE_PHONE:
Packit 8fb625
		return _("Phone");
Packit 8fb625
	case BLUETOOTH_TYPE_MODEM:
Packit 8fb625
		return _("Modem");
Packit 8fb625
	case BLUETOOTH_TYPE_COMPUTER:
Packit 8fb625
		return _("Computer");
Packit 8fb625
	case BLUETOOTH_TYPE_NETWORK:
Packit 8fb625
		return _("Network");
Packit 8fb625
	case BLUETOOTH_TYPE_HEADSET:
Packit 8fb625
		/* translators: a hands-free headset, a combination of a single speaker with a microphone */
Packit 8fb625
		return _("Headset");
Packit 8fb625
	case BLUETOOTH_TYPE_HEADPHONES:
Packit 8fb625
		return _("Headphones");
Packit 8fb625
	case BLUETOOTH_TYPE_OTHER_AUDIO:
Packit 8fb625
		return _("Audio device");
Packit 8fb625
	case BLUETOOTH_TYPE_KEYBOARD:
Packit 8fb625
		return _("Keyboard");
Packit 8fb625
	case BLUETOOTH_TYPE_MOUSE:
Packit 8fb625
		return _("Mouse");
Packit 8fb625
	case BLUETOOTH_TYPE_CAMERA:
Packit 8fb625
		return _("Camera");
Packit 8fb625
	case BLUETOOTH_TYPE_PRINTER:
Packit 8fb625
		return _("Printer");
Packit 8fb625
	case BLUETOOTH_TYPE_JOYPAD:
Packit 8fb625
		return _("Joypad");
Packit 8fb625
	case BLUETOOTH_TYPE_TABLET:
Packit 8fb625
		return _("Tablet");
Packit 8fb625
	case BLUETOOTH_TYPE_VIDEO:
Packit 8fb625
		return _("Video device");
Packit 8fb625
	case BLUETOOTH_TYPE_REMOTE_CONTROL:
Packit 8fb625
		return _("Remote control");
Packit 8fb625
	case BLUETOOTH_TYPE_SCANNER:
Packit 8fb625
		return _("Scanner");
Packit 8fb625
	case BLUETOOTH_TYPE_DISPLAY:
Packit 8fb625
		return _("Display");
Packit 8fb625
	case BLUETOOTH_TYPE_WEARABLE:
Packit 8fb625
		return _("Wearable");
Packit 8fb625
	case BLUETOOTH_TYPE_TOY:
Packit 8fb625
		return _("Toy");
Packit 8fb625
	}
Packit 8fb625
Packit 8fb625
	return _("Unknown");
Packit 8fb625
}
Packit 8fb625
Packit 8fb625
/**
Packit 8fb625
 * bluetooth_type_to_filter_string:
Packit 8fb625
 * @type: a #BluetoothType
Packit 8fb625
 *
Packit 8fb625
 * Returns a human-readable string representation of @type usable for display to users,
Packit 8fb625
 * when type filters are displayed. Do not free the return value.
Packit 8fb625
 * The returned string is already translated with gettext().
Packit 8fb625
 *
Packit 8fb625
 * Return value: a string.
Packit 8fb625
 **/
Packit 8fb625
const gchar *
Packit 8fb625
bluetooth_type_to_filter_string (BluetoothType type)
Packit 8fb625
{
Packit 8fb625
	switch (type) {
Packit 8fb625
	case BLUETOOTH_TYPE_ANY:
Packit 8fb625
		return _("All types");
Packit 8fb625
	default:
Packit 8fb625
		return bluetooth_type_to_string (type);
Packit 8fb625
	}
Packit 8fb625
Packit 8fb625
	g_assert_not_reached ();
Packit 8fb625
}
Packit 8fb625
Packit 8fb625
/**
Packit 8fb625
 * bluetooth_verify_address:
Packit 8fb625
 * @bdaddr: a string representing a Bluetooth address
Packit 8fb625
 *
Packit 8fb625
 * Returns whether the string is a valid Bluetooth address. This does not contact the device in any way.
Packit 8fb625
 *
Packit 8fb625
 * Return value: %TRUE if the address is valid, %FALSE if not.
Packit 8fb625
 **/
Packit 8fb625
gboolean
Packit 8fb625
bluetooth_verify_address (const char *bdaddr)
Packit 8fb625
{
Packit 8fb625
	guint i;
Packit 8fb625
Packit 8fb625
	g_return_val_if_fail (bdaddr != NULL, FALSE);
Packit 8fb625
Packit 8fb625
	if (strlen (bdaddr) != 17)
Packit 8fb625
		return FALSE;
Packit 8fb625
Packit 8fb625
	for (i = 0; i < 17; i++) {
Packit 8fb625
		if (((i + 1) % 3) == 0) {
Packit 8fb625
			if (bdaddr[i] != ':')
Packit 8fb625
				return FALSE;
Packit 8fb625
			continue;
Packit 8fb625
		}
Packit 8fb625
		if (g_ascii_isxdigit (bdaddr[i]) == FALSE)
Packit 8fb625
			return FALSE;
Packit 8fb625
	}
Packit 8fb625
Packit 8fb625
	return TRUE;
Packit 8fb625
}
Packit 8fb625
Packit 8fb625
/**
Packit 8fb625
 * bluetooth_class_to_type:
Packit 8fb625
 * @class: a Bluetooth device class
Packit 8fb625
 *
Packit 8fb625
 * Returns the type of device corresponding to the given @class value.
Packit 8fb625
 *
Packit 8fb625
 * Return value: a #BluetoothType.
Packit 8fb625
 **/
Packit 8fb625
BluetoothType
Packit 8fb625
bluetooth_class_to_type (guint32 class)
Packit 8fb625
{
Packit 8fb625
	switch ((class & 0x1f00) >> 8) {
Packit 8fb625
	case 0x01:
Packit 8fb625
		return BLUETOOTH_TYPE_COMPUTER;
Packit 8fb625
	case 0x02:
Packit 8fb625
		switch ((class & 0xfc) >> 2) {
Packit 8fb625
		case 0x01:
Packit 8fb625
		case 0x02:
Packit 8fb625
		case 0x03:
Packit 8fb625
		case 0x05:
Packit 8fb625
			return BLUETOOTH_TYPE_PHONE;
Packit 8fb625
		case 0x04:
Packit 8fb625
			return BLUETOOTH_TYPE_MODEM;
Packit 8fb625
		}
Packit 8fb625
		break;
Packit 8fb625
	case 0x03:
Packit 8fb625
		return BLUETOOTH_TYPE_NETWORK;
Packit 8fb625
	case 0x04:
Packit 8fb625
		switch ((class & 0xfc) >> 2) {
Packit 8fb625
		case 0x01:
Packit 8fb625
		case 0x02:
Packit 8fb625
			return BLUETOOTH_TYPE_HEADSET;
Packit 8fb625
		case 0x06:
Packit 8fb625
			return BLUETOOTH_TYPE_HEADPHONES;
Packit 8fb625
		case 0x0b: /* VCR */
Packit 8fb625
		case 0x0c: /* Video Camera */
Packit 8fb625
		case 0x0d: /* Camcorder */
Packit 8fb625
			return BLUETOOTH_TYPE_VIDEO;
Packit 8fb625
		default:
Packit 8fb625
			return BLUETOOTH_TYPE_OTHER_AUDIO;
Packit 8fb625
		}
Packit 8fb625
		break;
Packit 8fb625
	case 0x05:
Packit 8fb625
		switch ((class & 0xc0) >> 6) {
Packit 8fb625
		case 0x00:
Packit 8fb625
			switch ((class & 0x1e) >> 2) {
Packit 8fb625
			case 0x01:
Packit 8fb625
			case 0x02:
Packit 8fb625
				return BLUETOOTH_TYPE_JOYPAD;
Packit 8fb625
			case 0x03:
Packit 8fb625
				return BLUETOOTH_TYPE_REMOTE_CONTROL;
Packit 8fb625
			}
Packit 8fb625
			break;
Packit 8fb625
		case 0x01:
Packit 8fb625
			return BLUETOOTH_TYPE_KEYBOARD;
Packit 8fb625
		case 0x02:
Packit 8fb625
			switch ((class & 0x1e) >> 2) {
Packit 8fb625
			case 0x05:
Packit 8fb625
				return BLUETOOTH_TYPE_TABLET;
Packit 8fb625
			default:
Packit 8fb625
				return BLUETOOTH_TYPE_MOUSE;
Packit 8fb625
			}
Packit 8fb625
		}
Packit 8fb625
		break;
Packit 8fb625
	case 0x06:
Packit 8fb625
		if (class & 0x80)
Packit 8fb625
			return BLUETOOTH_TYPE_PRINTER;
Packit 8fb625
		if (class & 0x40)
Packit 8fb625
			return BLUETOOTH_TYPE_SCANNER;
Packit 8fb625
		if (class & 0x20)
Packit 8fb625
			return BLUETOOTH_TYPE_CAMERA;
Packit 8fb625
		if (class & 0x10)
Packit 8fb625
			return BLUETOOTH_TYPE_DISPLAY;
Packit 8fb625
		break;
Packit 8fb625
	case 0x07:
Packit 8fb625
		return BLUETOOTH_TYPE_WEARABLE;
Packit 8fb625
	case 0x08:
Packit 8fb625
		return BLUETOOTH_TYPE_TOY;
Packit 8fb625
	}
Packit 8fb625
Packit 8fb625
	return 0;
Packit 8fb625
}
Packit 8fb625
Packit 8fb625
/**
Packit 8fb625
 * bluetooth_appearance_to_type:
Packit 8fb625
 * @appearance: a Bluetooth device appearance
Packit 8fb625
 *
Packit 8fb625
 * Returns the type of device corresponding to the given @appearance value,
Packit 8fb625
 * as usually found in the GAP service.
Packit 8fb625
 *
Packit 8fb625
 * Return value: a #BluetoothType.
Packit 8fb625
 **/
Packit 8fb625
BluetoothType
Packit 8fb625
bluetooth_appearance_to_type (guint16 appearance)
Packit 8fb625
{
Packit 8fb625
	switch ((appearance & 0xffc0) >> 6) {
Packit 8fb625
	case 0x01:
Packit 8fb625
		return BLUETOOTH_TYPE_PHONE;
Packit 8fb625
	case 0x02:
Packit 8fb625
		return BLUETOOTH_TYPE_COMPUTER;
Packit 8fb625
	case 0x05:
Packit 8fb625
		return BLUETOOTH_TYPE_DISPLAY;
Packit 8fb625
	case 0x0a:
Packit 8fb625
		return BLUETOOTH_TYPE_OTHER_AUDIO;
Packit 8fb625
	case 0x0b:
Packit 8fb625
		return BLUETOOTH_TYPE_SCANNER;
Packit 8fb625
	case 0x0f: /* HID Generic */
Packit 8fb625
		switch (appearance & 0x3f) {
Packit 8fb625
		case 0x01:
Packit 8fb625
			return BLUETOOTH_TYPE_KEYBOARD;
Packit 8fb625
		case 0x02:
Packit 8fb625
			return BLUETOOTH_TYPE_MOUSE;
Packit 8fb625
		case 0x03:
Packit 8fb625
		case 0x04:
Packit 8fb625
			return BLUETOOTH_TYPE_JOYPAD;
Packit 8fb625
		case 0x05:
Packit 8fb625
			return BLUETOOTH_TYPE_TABLET;
Packit 8fb625
		case 0x08:
Packit 8fb625
			return BLUETOOTH_TYPE_SCANNER;
Packit 8fb625
		}
Packit 8fb625
		break;
Packit 8fb625
	}
Packit 8fb625
Packit 8fb625
	return 0;
Packit 8fb625
Packit 8fb625
}
Packit 8fb625
Packit 8fb625
static const char *
Packit 8fb625
uuid16_custom_to_string (guint uuid16, const char *uuid)
Packit 8fb625
{
Packit 8fb625
	switch (uuid16) {
Packit 8fb625
	case 0x2:
Packit 8fb625
		return "SyncMLClient";
Packit 8fb625
	case 0x5601:
Packit 8fb625
		return "Nokia SyncML Server";
Packit 8fb625
	default:
Packit 8fb625
		g_debug ("Unhandled custom UUID %s (0x%x)", uuid, uuid16);
Packit 8fb625
		return NULL;
Packit 8fb625
	}
Packit 8fb625
}
Packit 8fb625
Packit 8fb625
/* Short names from Table 2 at:
Packit 8fb625
 * https://www.bluetooth.org/Technical/AssignedNumbers/service_discovery.htm */
Packit 8fb625
static const char *
Packit 8fb625
uuid16_to_string (guint uuid16, const char *uuid)
Packit 8fb625
{
Packit 8fb625
	switch (uuid16) {
Packit 8fb625
	case BLUETOOTH_UUID_SPP:
Packit 8fb625
		return "SerialPort";
Packit 8fb625
	case BLUETOOTH_UUID_DUN:
Packit 8fb625
		return "DialupNetworking";
Packit 8fb625
	case BLUETOOTH_UUID_IRMC:
Packit 8fb625
		return "IrMCSync";
Packit 8fb625
	case BLUETOOTH_UUID_OPP:
Packit 8fb625
		return "OBEXObjectPush";
Packit 8fb625
	case BLUETOOTH_UUID_FTP:
Packit 8fb625
		return "OBEXFileTransfer";
Packit 8fb625
	case BLUETOOTH_UUID_HSP:
Packit 8fb625
		return "HSP";
Packit 8fb625
	case BLUETOOTH_UUID_A2DP_SOURCE:
Packit 8fb625
		return "AudioSource";
Packit 8fb625
	case BLUETOOTH_UUID_A2DP_SINK:
Packit 8fb625
		return "AudioSink";
Packit 8fb625
	case BLUETOOTH_UUID_AVRCP_TARGET:
Packit 8fb625
		return "A/V_RemoteControlTarget";
Packit 8fb625
	case BLUETOOTH_UUID_A2DP:
Packit 8fb625
		return "AdvancedAudioDistribution";
Packit 8fb625
	case BLUETOOTH_UUID_AVRCP_CONTROL:
Packit 8fb625
		return "A/V_RemoteControl";
Packit 8fb625
	case BLUETOOTH_UUID_HSP_AG:
Packit 8fb625
		return "Headset_-_AG";
Packit 8fb625
	case BLUETOOTH_UUID_PAN_PANU:
Packit 8fb625
		return "PANU";
Packit 8fb625
	case BLUETOOTH_UUID_PAN_NAP:
Packit 8fb625
		return "NAP";
Packit 8fb625
	case BLUETOOTH_UUID_PAN_GN:
Packit 8fb625
		return "GN";
Packit 8fb625
	case BLUETOOTH_UUID_HFP_HF:
Packit 8fb625
		return "Handsfree";
Packit 8fb625
	case BLUETOOTH_UUID_HFP_AG:
Packit 8fb625
		return "HandsfreeAudioGateway";
Packit 8fb625
	case BLUETOOTH_UUID_HID:
Packit 8fb625
	case 0x1812:
Packit 8fb625
		return "HumanInterfaceDeviceService";
Packit 8fb625
	case BLUETOOTH_UUID_SAP:
Packit 8fb625
		return "SIM_Access";
Packit 8fb625
	case BLUETOOTH_UUID_PBAP:
Packit 8fb625
		return "Phonebook_Access_-_PSE";
Packit 8fb625
	case BLUETOOTH_UUID_GENERIC_AUDIO:
Packit 8fb625
		return "GenericAudio";
Packit 8fb625
	case BLUETOOTH_UUID_SDP: /* ServiceDiscoveryServerServiceClassID */
Packit 8fb625
	case BLUETOOTH_UUID_PNP: /* PnPInformation */
Packit 8fb625
		/* Those are ignored */
Packit 8fb625
		return NULL;
Packit 8fb625
	case BLUETOOTH_UUID_GENERIC_NET:
Packit 8fb625
		return "GenericNetworking";
Packit 8fb625
	case BLUETOOTH_UUID_VDP_SOURCE:
Packit 8fb625
		return "VideoSource";
Packit 8fb625
	case 0x8e771303:
Packit 8fb625
	case 0x8e771301:
Packit 8fb625
		return "SEMC HLA";
Packit 8fb625
	case 0x8e771401:
Packit 8fb625
		return "SEMC Watch Phone";
Packit 8fb625
	default:
Packit 8fb625
		g_debug ("Unhandled UUID %s (0x%x)", uuid, uuid16);
Packit 8fb625
		return NULL;
Packit 8fb625
	}
Packit 8fb625
}
Packit 8fb625
Packit 8fb625
/**
Packit 8fb625
 * bluetooth_uuid_to_string:
Packit 8fb625
 * @uuid: a string representing a Bluetooth UUID
Packit 8fb625
 *
Packit 8fb625
 * Returns a string representing a human-readable (but not usable for display to users) version of the @uuid. Do not free the return value.
Packit 8fb625
 *
Packit 8fb625
 * Return value: a string.
Packit 8fb625
 **/
Packit 8fb625
const char *
Packit 8fb625
bluetooth_uuid_to_string (const char *uuid)
Packit 8fb625
{
Packit 8fb625
	char **parts;
Packit 8fb625
	guint uuid16;
Packit 8fb625
	gboolean is_custom = FALSE;
Packit 8fb625
Packit 8fb625
	if (g_str_has_suffix (uuid, "-0000-1000-8000-0002ee000002") != FALSE)
Packit 8fb625
		is_custom = TRUE;
Packit 8fb625
Packit 8fb625
	parts = g_strsplit (uuid, "-", -1);
Packit 8fb625
	if (parts == NULL || parts[0] == NULL) {
Packit 8fb625
		g_strfreev (parts);
Packit 8fb625
		return NULL;
Packit 8fb625
	}
Packit 8fb625
Packit 8fb625
	uuid16 = g_ascii_strtoull (parts[0], NULL, 16);
Packit 8fb625
	g_strfreev (parts);
Packit 8fb625
	if (uuid16 == 0)
Packit 8fb625
		return NULL;
Packit 8fb625
Packit 8fb625
	if (is_custom == FALSE)
Packit 8fb625
		return uuid16_to_string (uuid16, uuid);
Packit 8fb625
	return uuid16_custom_to_string (uuid16, uuid);
Packit 8fb625
}
Packit 8fb625
Packit 8fb625
/**
Packit 8fb625
 * bluetooth_send_to_address:
Packit 8fb625
 * @address: Remote device to use
Packit 8fb625
 * @alias: Remote device's name
Packit 8fb625
 *
Packit 8fb625
 * Start a GUI application for transfering files over Bluetooth.
Packit 8fb625
 **/
Packit 8fb625
void
Packit 8fb625
bluetooth_send_to_address (const char *address,
Packit 8fb625
			   const char *alias)
Packit 8fb625
{
Packit 8fb625
	GPtrArray *a;
Packit 8fb625
	GError *err = NULL;
Packit 8fb625
Packit 8fb625
	a = g_ptr_array_new_with_free_func ((GDestroyNotify) g_free);
Packit 8fb625
Packit 8fb625
	g_ptr_array_add (a, g_strdup ("bluetooth-sendto"));
Packit 8fb625
	if (address != NULL)
Packit 8fb625
		g_ptr_array_add (a, g_strdup_printf ("--device=%s", address));
Packit 8fb625
	if (address != NULL && alias != NULL)
Packit 8fb625
		g_ptr_array_add (a, g_strdup_printf ("--name=%s", alias));
Packit 8fb625
	g_ptr_array_add (a, NULL);
Packit 8fb625
Packit 8fb625
	if (g_spawn_async(NULL, (char **) a->pdata, NULL,
Packit 8fb625
			  G_SPAWN_SEARCH_PATH, NULL, NULL, NULL, &err) == FALSE) {
Packit 8fb625
		g_printerr("Couldn't execute command: %s\n", err->message);
Packit 8fb625
		g_error_free (err);
Packit 8fb625
	}
Packit 8fb625
Packit 8fb625
	g_ptr_array_free (a, TRUE);
Packit 8fb625
}
Packit 8fb625