3 * oFono - Open Source Telephony
5 * Copyright (C) 2008-2011 Intel Corporation. All rights reserved.
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
31 #define OFONO_ERROR_INTERFACE "org.ofono.Error"
33 static DBusConnection *g_connection;
35 struct error_mapping_entry {
37 DBusMessage *(*ofono_error_func)(DBusMessage *);
40 struct error_mapping_entry cme_errors_mapping[] = {
41 { 3, __ofono_error_not_allowed },
42 { 4, __ofono_error_not_supported },
43 { 16, __ofono_error_incorrect_password },
44 { 30, __ofono_error_not_registered },
45 { 31, __ofono_error_timed_out },
46 { 32, __ofono_error_access_denied },
47 { 50, __ofono_error_invalid_args },
50 static void append_variant(DBusMessageIter *iter,
51 int type, void *value)
54 DBusMessageIter valueiter;
59 dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT,
62 dbus_message_iter_append_basic(&valueiter, type, value);
64 dbus_message_iter_close_container(iter, &valueiter);
67 void ofono_dbus_dict_append(DBusMessageIter *dict,
68 const char *key, int type, void *value)
70 DBusMessageIter keyiter;
72 if (type == DBUS_TYPE_STRING) {
73 const char *str = *((const char **) value);
78 dbus_message_iter_open_container(dict, DBUS_TYPE_DICT_ENTRY,
81 dbus_message_iter_append_basic(&keyiter, DBUS_TYPE_STRING, &key);
83 append_variant(&keyiter, type, value);
85 dbus_message_iter_close_container(dict, &keyiter);
88 static void append_array_variant(DBusMessageIter *iter, int type, void *val)
90 DBusMessageIter variant, array;
93 const char **str_array = *(const char ***) val;
96 arraysig[0] = DBUS_TYPE_ARRAY;
97 arraysig[1] = typesig[0] = type;
98 arraysig[2] = typesig[1] = '\0';
100 dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT,
103 dbus_message_iter_open_container(&variant, DBUS_TYPE_ARRAY,
106 for (i = 0; str_array[i]; i++)
107 dbus_message_iter_append_basic(&array, type,
110 dbus_message_iter_close_container(&variant, &array);
112 dbus_message_iter_close_container(iter, &variant);
115 void ofono_dbus_dict_append_array(DBusMessageIter *dict, const char *key,
118 DBusMessageIter entry;
120 dbus_message_iter_open_container(dict, DBUS_TYPE_DICT_ENTRY,
123 dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &key);
125 append_array_variant(&entry, type, val);
127 dbus_message_iter_close_container(dict, &entry);
130 static void append_dict_variant(DBusMessageIter *iter, int type, void *val)
132 DBusMessageIter variant, array, entry;
135 const void **val_array = *(const void ***) val;
138 arraysig[0] = DBUS_TYPE_ARRAY;
139 arraysig[1] = typesig[0] = DBUS_DICT_ENTRY_BEGIN_CHAR;
140 arraysig[2] = typesig[1] = DBUS_TYPE_STRING;
141 arraysig[3] = typesig[2] = type;
142 arraysig[4] = typesig[3] = DBUS_DICT_ENTRY_END_CHAR;
143 arraysig[5] = typesig[4] = '\0';
145 dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT,
148 dbus_message_iter_open_container(&variant, DBUS_TYPE_ARRAY,
151 for (i = 0; val_array[i]; i += 2) {
152 dbus_message_iter_open_container(&array, DBUS_TYPE_DICT_ENTRY,
155 dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING,
156 &(val_array[i + 0]));
159 * D-Bus expects a char** or uint8* depending on the type
160 * given. Since we are dealing with an array through a void**
161 * (and thus val_array[i] is a pointer) we need to
162 * differentiate DBUS_TYPE_STRING from the others. The other
163 * option would be the user to pass the exact type to this
164 * function, instead of a pointer to it. However in this case
165 * a cast from type to void* would be needed, which is not
168 if (type == DBUS_TYPE_STRING) {
169 dbus_message_iter_append_basic(&entry, type,
170 &(val_array[i + 1]));
172 dbus_message_iter_append_basic(&entry, type,
176 dbus_message_iter_close_container(&array, &entry);
179 dbus_message_iter_close_container(&variant, &array);
181 dbus_message_iter_close_container(iter, &variant);
184 void ofono_dbus_dict_append_dict(DBusMessageIter *dict, const char *key,
187 DBusMessageIter entry;
189 dbus_message_iter_open_container(dict, DBUS_TYPE_DICT_ENTRY,
192 dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &key);
194 append_dict_variant(&entry, type, val);
196 dbus_message_iter_close_container(dict, &entry);
199 int ofono_dbus_signal_property_changed(DBusConnection *conn,
201 const char *interface,
203 int type, void *value)
206 DBusMessageIter iter;
208 signal = dbus_message_new_signal(path, interface, "PropertyChanged");
209 if (signal == NULL) {
210 ofono_error("Unable to allocate new %s.PropertyChanged signal",
215 dbus_message_iter_init_append(signal, &iter);
217 dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &name);
219 append_variant(&iter, type, value);
221 return g_dbus_send_message(conn, signal);
224 int ofono_dbus_signal_array_property_changed(DBusConnection *conn,
226 const char *interface,
228 int type, void *value)
232 DBusMessageIter iter;
234 signal = dbus_message_new_signal(path, interface, "PropertyChanged");
235 if (signal == NULL) {
236 ofono_error("Unable to allocate new %s.PropertyChanged signal",
241 dbus_message_iter_init_append(signal, &iter);
243 dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &name);
245 append_array_variant(&iter, type, value);
247 return g_dbus_send_message(conn, signal);
250 int ofono_dbus_signal_dict_property_changed(DBusConnection *conn,
252 const char *interface,
254 int type, void *value)
258 DBusMessageIter iter;
260 signal = dbus_message_new_signal(path, interface, "PropertyChanged");
261 if (signal == NULL) {
262 ofono_error("Unable to allocate new %s.PropertyChanged signal",
267 dbus_message_iter_init_append(signal, &iter);
269 dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &name);
271 append_dict_variant(&iter, type, value);
273 return g_dbus_send_message(conn, signal);
276 DBusMessage *__ofono_error_invalid_args(DBusMessage *msg)
278 return g_dbus_create_error(msg, OFONO_ERROR_INTERFACE
280 "Invalid arguments in method call");
283 DBusMessage *__ofono_error_invalid_format(DBusMessage *msg)
285 return g_dbus_create_error(msg, OFONO_ERROR_INTERFACE
287 "Argument format is not recognized");
290 DBusMessage *__ofono_error_not_implemented(DBusMessage *msg)
292 return g_dbus_create_error(msg, OFONO_ERROR_INTERFACE
294 "Implementation not provided");
297 DBusMessage *__ofono_error_failed(DBusMessage *msg)
299 return g_dbus_create_error(msg, OFONO_ERROR_INTERFACE ".Failed",
303 DBusMessage *__ofono_error_busy(DBusMessage *msg)
305 return g_dbus_create_error(msg, OFONO_ERROR_INTERFACE ".InProgress",
306 "Operation already in progress");
309 DBusMessage *__ofono_error_not_found(DBusMessage *msg)
311 return g_dbus_create_error(msg, OFONO_ERROR_INTERFACE ".NotFound",
312 "Object is not found or not valid for this operation");
315 DBusMessage *__ofono_error_not_active(DBusMessage *msg)
317 return g_dbus_create_error(msg, OFONO_ERROR_INTERFACE ".NotActive",
318 "Operation is not active or in progress");
321 DBusMessage *__ofono_error_not_supported(DBusMessage *msg)
323 return g_dbus_create_error(msg, OFONO_ERROR_INTERFACE
325 "Operation is not supported by the"
329 DBusMessage *__ofono_error_not_available(DBusMessage *msg)
331 return g_dbus_create_error(msg, OFONO_ERROR_INTERFACE
333 "Operation currently not available");
336 DBusMessage *__ofono_error_timed_out(DBusMessage *msg)
338 return g_dbus_create_error(msg, OFONO_ERROR_INTERFACE ".Timedout",
339 "Operation failure due to timeout");
342 DBusMessage *__ofono_error_sim_not_ready(DBusMessage *msg)
344 return g_dbus_create_error(msg, OFONO_ERROR_INTERFACE ".SimNotReady",
345 "SIM is not ready or not inserted");
348 DBusMessage *__ofono_error_in_use(DBusMessage *msg)
350 return g_dbus_create_error(msg, OFONO_ERROR_INTERFACE ".InUse",
351 "The resource is currently in use");
354 DBusMessage *__ofono_error_not_attached(DBusMessage *msg)
356 return g_dbus_create_error(msg, OFONO_ERROR_INTERFACE ".NotAttached",
357 "GPRS is not attached");
360 DBusMessage *__ofono_error_attach_in_progress(DBusMessage *msg)
362 return g_dbus_create_error(msg,
363 OFONO_ERROR_INTERFACE ".AttachInProgress",
364 "GPRS Attach is in progress");
367 DBusMessage *__ofono_error_not_registered(DBusMessage *msg)
369 return g_dbus_create_error(msg,
370 OFONO_ERROR_INTERFACE ".NotRegistered",
371 "Modem is not registered to the network");
374 DBusMessage *__ofono_error_canceled(DBusMessage *msg)
376 return g_dbus_create_error(msg, OFONO_ERROR_INTERFACE ".Canceled",
377 "Operation has been canceled");
380 DBusMessage *__ofono_error_access_denied(DBusMessage *msg)
382 return g_dbus_create_error(msg, OFONO_ERROR_INTERFACE ".AccessDenied",
383 "Operation not permitted");
386 DBusMessage *__ofono_error_emergency_active(DBusMessage *msg)
388 return g_dbus_create_error(msg,
389 OFONO_ERROR_INTERFACE ".EmergencyActive",
390 "Emergency mode active");
393 DBusMessage *__ofono_error_incorrect_password(DBusMessage *msg)
395 return g_dbus_create_error(msg,
396 OFONO_ERROR_INTERFACE ".IncorrectPassword",
397 "Password is incorrect");
400 DBusMessage *__ofono_error_not_allowed(DBusMessage *msg)
402 return g_dbus_create_error(msg, OFONO_ERROR_INTERFACE ".NotAllowed",
403 "Operation is not allowed");
406 DBusMessage *__ofono_error_not_recognized(DBusMessage *msg)
408 return g_dbus_create_error(msg, OFONO_ERROR_INTERFACE ".NotRecognized",
409 "String not recognized as USSD/SS");
412 DBusMessage *__ofono_error_from_error(const struct ofono_error *error,
415 struct error_mapping_entry *e;
419 switch (error->type) {
420 case OFONO_ERROR_TYPE_CME:
421 e = cme_errors_mapping;
422 maxentries = sizeof(cme_errors_mapping) /
423 sizeof(struct error_mapping_entry);
424 for (i = 0; i < maxentries; i++)
425 if (e[i].error == error->error)
426 return e[i].ofono_error_func(msg);
428 case OFONO_ERROR_TYPE_CMS:
429 return __ofono_error_failed(msg);
430 case OFONO_ERROR_TYPE_CEER:
431 return __ofono_error_failed(msg);
433 return __ofono_error_failed(msg);
436 return __ofono_error_failed(msg);
439 void __ofono_dbus_pending_reply(DBusMessage **msg, DBusMessage *reply)
441 DBusConnection *conn = ofono_dbus_get_connection();
443 g_dbus_send_message(conn, reply);
445 dbus_message_unref(*msg);
449 gboolean __ofono_dbus_valid_object_path(const char *path)
460 if (path[0] && !path[1] && path[0] == '/')
466 for (i = 0; path[i]; i++) {
467 if (path[i] == '/' && c == '/')
472 if (path[i] >= 'a' && path[i] <= 'z')
475 if (path[i] >= 'A' && path[i] <= 'Z')
478 if (path[i] >= '0' && path[i] <= '9')
481 if (path[i] == '_' || path[i] == '/')
487 if (path[i-1] == '/')
493 DBusConnection *ofono_dbus_get_connection(void)
498 static void dbus_gsm_set_connection(DBusConnection *conn)
500 if (conn && g_connection != NULL)
501 ofono_error("Setting a connection when it is not NULL");
506 int __ofono_dbus_init(DBusConnection *conn)
508 dbus_gsm_set_connection(conn);
513 void __ofono_dbus_cleanup(void)
515 DBusConnection *conn = ofono_dbus_get_connection();
517 if (conn == NULL || !dbus_connection_get_is_connected(conn))
520 dbus_gsm_set_connection(NULL);