• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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@holtmann.org>
7  *  Copyright (C) 2005-2007  Johan Hedberg <johan.hedberg@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 
append_variant(DBusMessageIter * iter,int type,void * val)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 
append_array_variant(DBusMessageIter * iter,int type,void * val,int n_elements)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 
dict_append_entry(DBusMessageIter * dict,const char * key,int type,void * val)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 
dict_append_array(DBusMessageIter * dict,const char * key,int type,void * val,int n_elements)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 
emit_property_changed(DBusConnection * conn,const char * path,const char * interface,const char * name,int type,void * value)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 
emit_array_property_changed(DBusConnection * conn,const char * path,const char * interface,const char * name,int type,void * value,int num)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 
set_dbus_connection(DBusConnection * conn)182 void set_dbus_connection(DBusConnection *conn)
183 {
184 	connection = conn;
185 }
186 
get_dbus_connection(void)187 DBusConnection *get_dbus_connection(void)
188 {
189 	return connection;
190 }
191 
class_to_icon(uint32_t class)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