Home | History | Annotate | Download | only in src
      1 /*
      2  *
      3  *  BlueZ - Bluetooth protocol stack for Linux
      4  *
      5  *  Copyright (C) 2006-2010  Nokia Corporation
      6  *  Copyright (C) 2004-2010  Marcel Holtmann <marcel (at) holtmann.org>
      7  *  Copyright (C) 2005-2007  Johan Hedberg <johan.hedberg (at) nokia.com>
      8  *
      9  *
     10  *  This program is free software; you can redistribute it and/or modify
     11  *  it under the terms of the GNU General Public License as published by
     12  *  the Free Software Foundation; either version 2 of the License, or
     13  *  (at your option) any later version.
     14  *
     15  *  This program is distributed in the hope that it will be useful,
     16  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
     17  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     18  *  GNU General Public License for more details.
     19  *
     20  *  You should have received a copy of the GNU General Public License
     21  *  along with this program; if not, write to the Free Software
     22  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
     23  *
     24  */
     25 
     26 #ifdef HAVE_CONFIG_H
     27 #include <config.h>
     28 #endif
     29 
     30 #include <stdio.h>
     31 #include <errno.h>
     32 #include <stdlib.h>
     33 #include <string.h>
     34 #include <unistd.h>
     35 #include <sys/ioctl.h>
     36 
     37 #include <bluetooth/bluetooth.h>
     38 
     39 #include <glib.h>
     40 #include <dbus/dbus.h>
     41 #include <gdbus.h>
     42 
     43 #include "log.h"
     44 
     45 #include "adapter.h"
     46 #include "manager.h"
     47 #include "event.h"
     48 #include "dbus-common.h"
     49 
     50 static DBusConnection *connection = NULL;
     51 
     52 static void append_variant(DBusMessageIter *iter, int type, void *val)
     53 {
     54 	DBusMessageIter value;
     55 	char sig[2] = { type, '\0' };
     56 
     57 	dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT, sig, &value);
     58 
     59 	dbus_message_iter_append_basic(&value, type, val);
     60 
     61 	dbus_message_iter_close_container(iter, &value);
     62 }
     63 
     64 static void append_array_variant(DBusMessageIter *iter, int type, void *val,
     65 							int n_elements)
     66 {
     67 	DBusMessageIter variant, array;
     68 	char type_sig[2] = { type, '\0' };
     69 	char array_sig[3] = { DBUS_TYPE_ARRAY, type, '\0' };
     70 
     71 	dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT,
     72 						array_sig, &variant);
     73 
     74 	dbus_message_iter_open_container(&variant, DBUS_TYPE_ARRAY,
     75 						type_sig, &array);
     76 
     77 	if (dbus_type_is_fixed(type) == TRUE) {
     78 		dbus_message_iter_append_fixed_array(&array, type, val,
     79 							n_elements);
     80 	} else if (type == DBUS_TYPE_STRING || type == DBUS_TYPE_OBJECT_PATH) {
     81 		const char ***str_array = val;
     82 		int i;
     83 
     84 		for (i = 0; i < n_elements; i++)
     85 			dbus_message_iter_append_basic(&array, type,
     86 							&((*str_array)[i]));
     87 	}
     88 
     89 	dbus_message_iter_close_container(&variant, &array);
     90 
     91 	dbus_message_iter_close_container(iter, &variant);
     92 }
     93 
     94 void dict_append_entry(DBusMessageIter *dict,
     95 			const char *key, int type, void *val)
     96 {
     97 	DBusMessageIter entry;
     98 
     99 	if (type == DBUS_TYPE_STRING) {
    100 		const char *str = *((const char **) val);
    101 		if (str == NULL)
    102 			return;
    103 	}
    104 
    105 	dbus_message_iter_open_container(dict, DBUS_TYPE_DICT_ENTRY,
    106 							NULL, &entry);
    107 
    108 	dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &key);
    109 
    110 	append_variant(&entry, type, val);
    111 
    112 	dbus_message_iter_close_container(dict, &entry);
    113 }
    114 
    115 void dict_append_array(DBusMessageIter *dict, const char *key, int type,
    116 			void *val, int n_elements)
    117 {
    118 	DBusMessageIter entry;
    119 
    120 	dbus_message_iter_open_container(dict, DBUS_TYPE_DICT_ENTRY,
    121 						NULL, &entry);
    122 
    123 	dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &key);
    124 
    125 	append_array_variant(&entry, type, val, n_elements);
    126 
    127 	dbus_message_iter_close_container(dict, &entry);
    128 }
    129 
    130 dbus_bool_t emit_property_changed(DBusConnection *conn,
    131 					const char *path,
    132 					const char *interface,
    133 					const char *name,
    134 					int type, void *value)
    135 {
    136 	DBusMessage *signal;
    137 	DBusMessageIter iter;
    138 
    139 	signal = dbus_message_new_signal(path, interface, "PropertyChanged");
    140 
    141 	if (!signal) {
    142 		error("Unable to allocate new %s.PropertyChanged signal",
    143 				interface);
    144 		return FALSE;
    145 	}
    146 
    147 	dbus_message_iter_init_append(signal, &iter);
    148 
    149 	dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &name);
    150 
    151 	append_variant(&iter, type, value);
    152 
    153 	return g_dbus_send_message(conn, signal);
    154 }
    155 
    156 dbus_bool_t emit_array_property_changed(DBusConnection *conn,
    157 					const char *path,
    158 					const char *interface,
    159 					const char *name,
    160 					int type, void *value, int num)
    161 {
    162 	DBusMessage *signal;
    163 	DBusMessageIter iter;
    164 
    165 	signal = dbus_message_new_signal(path, interface, "PropertyChanged");
    166 
    167 	if (!signal) {
    168 		error("Unable to allocate new %s.PropertyChanged signal",
    169 				interface);
    170 		return FALSE;
    171 	}
    172 
    173 	dbus_message_iter_init_append(signal, &iter);
    174 
    175 	dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &name);
    176 
    177 	append_array_variant(&iter, type, value, num);
    178 
    179 	return g_dbus_send_message(conn, signal);
    180 }
    181 
    182 void set_dbus_connection(DBusConnection *conn)
    183 {
    184 	connection = conn;
    185 }
    186 
    187 DBusConnection *get_dbus_connection(void)
    188 {
    189 	return connection;
    190 }
    191 
    192 const char *class_to_icon(uint32_t class)
    193 {
    194 	switch ((class & 0x1f00) >> 8) {
    195 	case 0x01:
    196 		return "computer";
    197 	case 0x02:
    198 		switch ((class & 0xfc) >> 2) {
    199 		case 0x01:
    200 		case 0x02:
    201 		case 0x03:
    202 		case 0x05:
    203 			return "phone";
    204 		case 0x04:
    205 			return "modem";
    206 		}
    207 		break;
    208 	case 0x03:
    209 		return "network-wireless";
    210 	case 0x04:
    211 		switch ((class & 0xfc) >> 2) {
    212 		case 0x01:
    213 		case 0x02:
    214 			return "audio-card";	/* Headset */
    215 		case 0x06:
    216 			return "audio-card";	/* Headphone */
    217 		case 0x0b: /* VCR */
    218 		case 0x0c: /* Video Camera */
    219 		case 0x0d: /* Camcorder */
    220 			return "camera-video";
    221 		default:
    222 			return "audio-card";	/* Other audio device */
    223 		}
    224 		break;
    225 	case 0x05:
    226 		switch ((class & 0xc0) >> 6) {
    227 		case 0x00:
    228 			switch ((class & 0x1e) >> 2) {
    229 			case 0x01:
    230 			case 0x02:
    231 				return "input-gaming";
    232 			}
    233 			break;
    234 		case 0x01:
    235 			return "input-keyboard";
    236 		case 0x02:
    237 			switch ((class & 0x1e) >> 2) {
    238 			case 0x05:
    239 				return "input-tablet";
    240 			default:
    241 				return "input-mouse";
    242 			}
    243 		}
    244 		break;
    245 	case 0x06:
    246 		if (class & 0x80)
    247 			return "printer";
    248 		if (class & 0x20)
    249 			return "camera-photo";
    250 		break;
    251 	}
    252 
    253 	return NULL;
    254 }
    255