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
37 static GSList *g_devinfo_drivers = NULL;
38 static GSList *g_driver_list = NULL;
39 static GSList *g_modem_list = NULL;
41 static int next_modem_id = 0;
42 static gboolean powering_down = FALSE;
43 static int modems_remaining = 0;
45 static struct ofono_watchlist *g_modemwatches = NULL;
48 PROPERTY_TYPE_INVALID = 0,
50 PROPERTY_TYPE_INTEGER,
51 PROPERTY_TYPE_BOOLEAN,
55 MODEM_STATE_POWER_OFF,
63 enum modem_state modem_state;
65 struct ofono_watchlist *atom_watches;
66 GSList *interface_list;
68 unsigned int call_ids;
70 guint interface_update;
72 ofono_bool_t powered_pending;
73 ofono_bool_t get_online;
74 ofono_bool_t lockdown;
79 struct ofono_watchlist *online_watches;
80 struct ofono_watchlist *powered_watches;
82 GHashTable *properties;
83 struct ofono_sim *sim;
84 unsigned int sim_watch;
85 unsigned int sim_ready_watch;
86 const struct ofono_modem_driver *driver;
92 struct ofono_devinfo {
97 unsigned int dun_watch;
98 const struct ofono_devinfo_driver *driver;
100 struct ofono_atom *atom;
104 enum ofono_atom_type type;
105 enum modem_state modem_state;
106 void (*destruct)(struct ofono_atom *atom);
107 void (*unregister)(struct ofono_atom *atom);
109 struct ofono_modem *modem;
113 struct ofono_watchlist_item item;
114 enum ofono_atom_type type;
117 struct modem_property {
118 enum property_type type;
122 static const char *modem_type_to_string(enum ofono_modem_type type)
125 case OFONO_MODEM_TYPE_HARDWARE:
127 case OFONO_MODEM_TYPE_HFP:
129 case OFONO_MODEM_TYPE_SAP:
136 unsigned int __ofono_modem_callid_next(struct ofono_modem *modem)
140 for (i = 1; i < sizeof(modem->call_ids) * 8; i++) {
141 if (modem->call_ids & (1 << i))
150 void __ofono_modem_callid_hold(struct ofono_modem *modem, int id)
152 modem->call_ids |= (1 << id);
155 void __ofono_modem_callid_release(struct ofono_modem *modem, int id)
157 modem->call_ids &= ~(1 << id);
160 void ofono_modem_set_data(struct ofono_modem *modem, void *data)
165 modem->driver_data = data;
168 void *ofono_modem_get_data(struct ofono_modem *modem)
173 return modem->driver_data;
176 const char *ofono_modem_get_path(struct ofono_modem *modem)
184 struct ofono_atom *__ofono_modem_add_atom(struct ofono_modem *modem,
185 enum ofono_atom_type type,
186 void (*destruct)(struct ofono_atom *),
189 struct ofono_atom *atom;
194 atom = g_new0(struct ofono_atom, 1);
197 atom->modem_state = modem->modem_state;
198 atom->destruct = destruct;
202 modem->atoms = g_slist_prepend(modem->atoms, atom);
207 struct ofono_atom *__ofono_modem_add_atom_offline(struct ofono_modem *modem,
208 enum ofono_atom_type type,
209 void (*destruct)(struct ofono_atom *),
212 struct ofono_atom *atom;
214 atom = __ofono_modem_add_atom(modem, type, destruct, data);
216 atom->modem_state = MODEM_STATE_OFFLINE;
221 void *__ofono_atom_get_data(struct ofono_atom *atom)
226 const char *__ofono_atom_get_path(struct ofono_atom *atom)
228 return atom->modem->path;
231 struct ofono_modem *__ofono_atom_get_modem(struct ofono_atom *atom)
236 static void call_watches(struct ofono_atom *atom,
237 enum ofono_atom_watch_condition cond)
239 struct ofono_modem *modem = atom->modem;
240 GSList *atom_watches = modem->atom_watches->items;
242 struct atom_watch *watch;
243 ofono_atom_watch_func notify;
245 for (l = atom_watches; l; l = l->next) {
248 if (watch->type != atom->type)
251 notify = watch->item.notify;
252 notify(atom, cond, watch->item.notify_data);
256 void __ofono_atom_register(struct ofono_atom *atom,
257 void (*unregister)(struct ofono_atom *))
259 if (unregister == NULL)
262 atom->unregister = unregister;
264 call_watches(atom, OFONO_ATOM_WATCH_CONDITION_REGISTERED);
267 void __ofono_atom_unregister(struct ofono_atom *atom)
269 if (atom->unregister == NULL)
272 call_watches(atom, OFONO_ATOM_WATCH_CONDITION_UNREGISTERED);
274 atom->unregister(atom);
275 atom->unregister = NULL;
278 gboolean __ofono_atom_get_registered(struct ofono_atom *atom)
280 return atom->unregister ? TRUE : FALSE;
283 unsigned int __ofono_modem_add_atom_watch(struct ofono_modem *modem,
284 enum ofono_atom_type type,
285 ofono_atom_watch_func notify,
286 void *data, ofono_destroy_func destroy)
288 struct atom_watch *watch;
291 struct ofono_atom *atom;
296 watch = g_new0(struct atom_watch, 1);
299 watch->item.notify = notify;
300 watch->item.destroy = destroy;
301 watch->item.notify_data = data;
303 id = __ofono_watchlist_add_item(modem->atom_watches,
304 (struct ofono_watchlist_item *)watch);
306 for (l = modem->atoms; l; l = l->next) {
309 if (atom->type != type || atom->unregister == NULL)
312 notify(atom, OFONO_ATOM_WATCH_CONDITION_REGISTERED, data);
318 gboolean __ofono_modem_remove_atom_watch(struct ofono_modem *modem,
321 return __ofono_watchlist_remove_item(modem->atom_watches, id);
324 struct ofono_atom *__ofono_modem_find_atom(struct ofono_modem *modem,
325 enum ofono_atom_type type)
328 struct ofono_atom *atom;
333 for (l = modem->atoms; l; l = l->next) {
336 if (atom->type == type && atom->unregister != NULL)
343 void __ofono_modem_foreach_atom(struct ofono_modem *modem,
344 enum ofono_atom_type type,
345 ofono_atom_func callback, void *data)
348 struct ofono_atom *atom;
353 for (l = modem->atoms; l; l = l->next) {
356 if (atom->type != type)
359 callback(atom, data);
363 void __ofono_modem_foreach_registered_atom(struct ofono_modem *modem,
364 enum ofono_atom_type type,
365 ofono_atom_func callback,
369 struct ofono_atom *atom;
374 for (l = modem->atoms; l; l = l->next) {
377 if (atom->type != type)
380 if (atom->unregister == NULL)
383 callback(atom, data);
387 void __ofono_atom_free(struct ofono_atom *atom)
389 struct ofono_modem *modem = atom->modem;
391 modem->atoms = g_slist_remove(modem->atoms, atom);
393 __ofono_atom_unregister(atom);
396 atom->destruct(atom);
401 static void flush_atoms(struct ofono_modem *modem, enum modem_state new_state)
413 struct ofono_atom *atom = cur->data;
415 if (atom->modem_state <= new_state) {
421 __ofono_atom_unregister(atom);
424 atom->destruct(atom);
429 prev->next = cur->next;
431 modem->atoms = cur->next;
439 static void notify_online_watches(struct ofono_modem *modem)
441 struct ofono_watchlist_item *item;
443 ofono_modem_online_notify_func notify;
445 if (modem->online_watches == NULL)
448 for (l = modem->online_watches->items; l; l = l->next) {
450 notify = item->notify;
451 notify(modem, modem->online, item->notify_data);
455 static void notify_powered_watches(struct ofono_modem *modem)
457 struct ofono_watchlist_item *item;
459 ofono_modem_powered_notify_func notify;
461 if (modem->powered_watches == NULL)
464 for (l = modem->powered_watches->items; l; l = l->next) {
466 notify = item->notify;
467 notify(modem, modem->powered, item->notify_data);
471 static void set_online(struct ofono_modem *modem, ofono_bool_t new_online)
473 DBusConnection *conn = ofono_dbus_get_connection();
475 if (new_online == modem->online)
478 modem->online = new_online;
480 ofono_dbus_signal_property_changed(conn, modem->path,
481 OFONO_MODEM_INTERFACE,
482 "Online", DBUS_TYPE_BOOLEAN,
485 notify_online_watches(modem);
488 static void modem_change_state(struct ofono_modem *modem,
489 enum modem_state new_state)
491 struct ofono_modem_driver const *driver = modem->driver;
492 enum modem_state old_state = modem->modem_state;
494 DBG("old state: %d, new state: %d", old_state, new_state);
496 if (old_state == new_state)
499 modem->modem_state = new_state;
501 if (old_state > new_state)
502 flush_atoms(modem, new_state);
505 case MODEM_STATE_POWER_OFF:
509 case MODEM_STATE_PRE_SIM:
510 if (old_state < MODEM_STATE_PRE_SIM && driver->pre_sim)
511 driver->pre_sim(modem);
514 case MODEM_STATE_OFFLINE:
515 if (old_state < MODEM_STATE_OFFLINE) {
516 if (driver->post_sim)
517 driver->post_sim(modem);
519 __ofono_history_probe_drivers(modem);
520 __ofono_nettime_probe_drivers(modem);
525 case MODEM_STATE_ONLINE:
526 if (driver->post_online)
527 driver->post_online(modem);
533 unsigned int __ofono_modem_add_online_watch(struct ofono_modem *modem,
534 ofono_modem_online_notify_func notify,
535 void *data, ofono_destroy_func destroy)
537 struct ofono_watchlist_item *item;
539 if (modem == NULL || notify == NULL)
542 item = g_new0(struct ofono_watchlist_item, 1);
544 item->notify = notify;
545 item->destroy = destroy;
546 item->notify_data = data;
548 return __ofono_watchlist_add_item(modem->online_watches, item);
551 void __ofono_modem_remove_online_watch(struct ofono_modem *modem,
554 __ofono_watchlist_remove_item(modem->online_watches, id);
557 unsigned int __ofono_modem_add_powered_watch(struct ofono_modem *modem,
558 ofono_modem_powered_notify_func notify,
559 void *data, ofono_destroy_func destroy)
561 struct ofono_watchlist_item *item;
563 if (modem == NULL || notify == NULL)
566 item = g_new0(struct ofono_watchlist_item, 1);
568 item->notify = notify;
569 item->destroy = destroy;
570 item->notify_data = data;
572 return __ofono_watchlist_add_item(modem->powered_watches, item);
575 void __ofono_modem_remove_powered_watch(struct ofono_modem *modem,
578 __ofono_watchlist_remove_item(modem->powered_watches, id);
581 static gboolean modem_has_sim(struct ofono_modem *modem)
584 struct ofono_atom *atom;
586 for (l = modem->atoms; l; l = l->next) {
589 if (atom->type == OFONO_ATOM_TYPE_SIM)
596 static void common_online_cb(const struct ofono_error *error, void *data)
598 struct ofono_modem *modem = data;
600 if (error->type != OFONO_ERROR_TYPE_NO_ERROR)
604 * If we need to get online after a silent reset this callback
605 * is called. The callback should not consider the pending dbus
608 * Additionally, this process can be interrupted by the following
610 * - Sim being removed or reset
611 * - SetProperty(Powered, False) being called
612 * - SetProperty(Lockdown, True) being called
614 * We should not set the modem to the online state in these cases.
616 switch (modem->modem_state) {
617 case MODEM_STATE_OFFLINE:
618 set_online(modem, TRUE);
620 /* Will this increase emergency call setup time??? */
621 modem_change_state(modem, MODEM_STATE_ONLINE);
623 case MODEM_STATE_POWER_OFF:
624 /* The powered operation is pending */
626 case MODEM_STATE_PRE_SIM:
628 * Its valid to be in online even without a SIM/SIM being
629 * PIN locked. e.g.: Emergency mode
631 DBG("Online in PRE SIM state");
633 set_online(modem, TRUE);
635 case MODEM_STATE_ONLINE:
636 ofono_error("Online called when the modem is already online!");
641 static void online_cb(const struct ofono_error *error, void *data)
643 struct ofono_modem *modem = data;
649 if (error->type == OFONO_ERROR_TYPE_NO_ERROR)
650 reply = dbus_message_new_method_return(modem->pending);
652 reply = __ofono_error_failed(modem->pending);
654 __ofono_dbus_pending_reply(&modem->pending, reply);
657 common_online_cb(error, data);
660 static void offline_cb(const struct ofono_error *error, void *data)
662 struct ofono_modem *modem = data;
665 if (error->type == OFONO_ERROR_TYPE_NO_ERROR)
666 reply = dbus_message_new_method_return(modem->pending);
668 reply = __ofono_error_failed(modem->pending);
670 __ofono_dbus_pending_reply(&modem->pending, reply);
672 if (error->type == OFONO_ERROR_TYPE_NO_ERROR) {
673 switch (modem->modem_state) {
674 case MODEM_STATE_PRE_SIM:
675 set_online(modem, FALSE);
677 case MODEM_STATE_ONLINE:
678 set_online(modem, FALSE);
679 modem_change_state(modem, MODEM_STATE_OFFLINE);
687 static void sim_state_watch(enum ofono_sim_state new_state, void *user)
689 struct ofono_modem *modem = user;
692 case OFONO_SIM_STATE_NOT_PRESENT:
693 modem_change_state(modem, MODEM_STATE_PRE_SIM);
694 case OFONO_SIM_STATE_INSERTED:
696 case OFONO_SIM_STATE_LOCKED_OUT:
697 modem_change_state(modem, MODEM_STATE_PRE_SIM);
699 case OFONO_SIM_STATE_READY:
700 modem_change_state(modem, MODEM_STATE_OFFLINE);
703 * If we don't have the set_online method, also proceed
704 * straight to the online state
706 if (modem->driver->set_online == NULL)
707 set_online(modem, TRUE);
709 if (modem->online == TRUE)
710 modem_change_state(modem, MODEM_STATE_ONLINE);
711 else if (modem->get_online)
712 modem->driver->set_online(modem, 1, common_online_cb,
715 modem->get_online = FALSE;
721 static DBusMessage *set_property_online(struct ofono_modem *modem,
723 DBusMessageIter *var)
726 const struct ofono_modem_driver *driver = modem->driver;
728 if (modem->powered == FALSE)
729 return __ofono_error_not_available(msg);
731 if (dbus_message_iter_get_arg_type(var) != DBUS_TYPE_BOOLEAN)
732 return __ofono_error_invalid_args(msg);
734 dbus_message_iter_get_basic(var, &online);
736 if (modem->pending != NULL)
737 return __ofono_error_busy(msg);
739 if (modem->online == online)
740 return dbus_message_new_method_return(msg);
742 if (ofono_modem_get_emergency_mode(modem) == TRUE)
743 return __ofono_error_emergency_active(msg);
745 if (driver->set_online == NULL)
746 return __ofono_error_not_implemented(msg);
748 modem->pending = dbus_message_ref(msg);
750 driver->set_online(modem, online,
751 online ? online_cb : offline_cb, modem);
756 ofono_bool_t ofono_modem_get_online(struct ofono_modem *modem)
761 return modem->online;
764 void __ofono_modem_append_properties(struct ofono_modem *modem,
765 DBusMessageIter *dict)
771 struct ofono_devinfo *info;
772 dbus_bool_t emergency = ofono_modem_get_emergency_mode(modem);
775 ofono_dbus_dict_append(dict, "Online", DBUS_TYPE_BOOLEAN,
778 ofono_dbus_dict_append(dict, "Powered", DBUS_TYPE_BOOLEAN,
781 ofono_dbus_dict_append(dict, "Lockdown", DBUS_TYPE_BOOLEAN,
784 ofono_dbus_dict_append(dict, "Emergency", DBUS_TYPE_BOOLEAN,
787 info = __ofono_atom_find(OFONO_ATOM_TYPE_DEVINFO, modem);
789 if (info->manufacturer)
790 ofono_dbus_dict_append(dict, "Manufacturer",
792 &info->manufacturer);
795 ofono_dbus_dict_append(dict, "Model", DBUS_TYPE_STRING,
799 ofono_dbus_dict_append(dict, "Revision",
804 ofono_dbus_dict_append(dict, "Serial",
809 interfaces = g_new0(char *, g_slist_length(modem->interface_list) + 1);
810 for (i = 0, l = modem->interface_list; l; l = l->next, i++)
811 interfaces[i] = l->data;
812 ofono_dbus_dict_append_array(dict, "Interfaces", DBUS_TYPE_STRING,
816 features = g_new0(char *, g_slist_length(modem->feature_list) + 1);
817 for (i = 0, l = modem->feature_list; l; l = l->next, i++)
818 features[i] = l->data;
819 ofono_dbus_dict_append_array(dict, "Features", DBUS_TYPE_STRING,
824 ofono_dbus_dict_append(dict, "Name", DBUS_TYPE_STRING,
827 strtype = modem_type_to_string(modem->driver->modem_type);
828 ofono_dbus_dict_append(dict, "Type", DBUS_TYPE_STRING, &strtype);
831 static DBusMessage *modem_get_properties(DBusConnection *conn,
832 DBusMessage *msg, void *data)
834 struct ofono_modem *modem = data;
836 DBusMessageIter iter;
837 DBusMessageIter dict;
839 reply = dbus_message_new_method_return(msg);
843 dbus_message_iter_init_append(reply, &iter);
845 dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
846 OFONO_PROPERTIES_ARRAY_SIGNATURE,
848 __ofono_modem_append_properties(modem, &dict);
849 dbus_message_iter_close_container(&iter, &dict);
854 static int set_powered(struct ofono_modem *modem, ofono_bool_t powered)
856 const struct ofono_modem_driver *driver = modem->driver;
859 if (modem->powered_pending == powered)
862 /* Remove the atoms even if the driver is no longer available */
863 if (powered == FALSE)
864 modem_change_state(modem, MODEM_STATE_POWER_OFF);
866 modem->powered_pending = powered;
871 if (powered == TRUE) {
873 err = driver->enable(modem);
876 err = driver->disable(modem);
880 modem->powered = powered;
881 notify_powered_watches(modem);
882 } else if (err != -EINPROGRESS)
883 modem->powered_pending = modem->powered;
888 static void lockdown_remove(struct ofono_modem *modem)
890 DBusConnection *conn = ofono_dbus_get_connection();
892 if (modem->lock_watch) {
893 g_dbus_remove_watch(conn, modem->lock_watch);
894 modem->lock_watch = 0;
897 g_free(modem->lock_owner);
898 modem->lock_owner = NULL;
900 modem->lockdown = FALSE;
903 static gboolean set_powered_timeout(gpointer user)
905 struct ofono_modem *modem = user;
907 DBG("modem: %p", modem);
911 if (modem->powered_pending == FALSE) {
912 DBusConnection *conn = ofono_dbus_get_connection();
913 dbus_bool_t powered = FALSE;
915 set_online(modem, FALSE);
917 modem->powered = FALSE;
918 notify_powered_watches(modem);
920 ofono_dbus_signal_property_changed(conn, modem->path,
921 OFONO_MODEM_INTERFACE,
922 "Powered", DBUS_TYPE_BOOLEAN,
925 modem->powered_pending = modem->powered;
928 if (modem->pending != NULL) {
931 reply = __ofono_error_timed_out(modem->pending);
932 __ofono_dbus_pending_reply(&modem->pending, reply);
935 lockdown_remove(modem);
941 static void lockdown_disconnect(DBusConnection *conn, void *user_data)
943 struct ofono_modem *modem = user_data;
947 ofono_dbus_signal_property_changed(conn, modem->path,
948 OFONO_MODEM_INTERFACE,
949 "Lockdown", DBUS_TYPE_BOOLEAN,
952 modem->lock_watch = 0;
953 lockdown_remove(modem);
956 static DBusMessage *set_property_lockdown(struct ofono_modem *modem,
958 DBusMessageIter *var)
960 DBusConnection *conn = ofono_dbus_get_connection();
961 ofono_bool_t lockdown;
966 if (dbus_message_iter_get_arg_type(var) != DBUS_TYPE_BOOLEAN)
967 return __ofono_error_invalid_args(msg);
969 dbus_message_iter_get_basic(var, &lockdown);
971 if (modem->pending != NULL)
972 return __ofono_error_busy(msg);
974 caller = dbus_message_get_sender(msg);
976 if (modem->lockdown && g_strcmp0(caller, modem->lock_owner))
977 return __ofono_error_access_denied(msg);
979 if (modem->lockdown == lockdown)
980 return dbus_message_new_method_return(msg);
982 if (lockdown == FALSE) {
983 lockdown_remove(modem);
987 if (ofono_modem_get_emergency_mode(modem) == TRUE)
988 return __ofono_error_emergency_active(msg);
990 modem->lock_owner = g_strdup(caller);
992 modem->lock_watch = g_dbus_add_disconnect_watch(conn,
993 modem->lock_owner, lockdown_disconnect,
996 if (modem->lock_watch == 0) {
997 g_free(modem->lock_owner);
998 modem->lock_owner = NULL;
1000 return __ofono_error_failed(msg);
1003 modem->lockdown = lockdown;
1005 if (modem->powered == FALSE)
1008 err = set_powered(modem, FALSE);
1010 if (err != -EINPROGRESS) {
1011 lockdown_remove(modem);
1012 return __ofono_error_failed(msg);
1015 modem->pending = dbus_message_ref(msg);
1016 modem->timeout = g_timeout_add_seconds(20,
1017 set_powered_timeout, modem);
1021 set_online(modem, FALSE);
1024 ofono_dbus_signal_property_changed(conn, modem->path,
1025 OFONO_MODEM_INTERFACE,
1026 "Powered", DBUS_TYPE_BOOLEAN,
1030 g_dbus_send_reply(conn, msg, DBUS_TYPE_INVALID);
1032 ofono_dbus_signal_property_changed(conn, modem->path,
1033 OFONO_MODEM_INTERFACE,
1034 "Lockdown", DBUS_TYPE_BOOLEAN,
1040 static DBusMessage *modem_set_property(DBusConnection *conn,
1041 DBusMessage *msg, void *data)
1043 struct ofono_modem *modem = data;
1044 DBusMessageIter iter, var;
1047 if (dbus_message_iter_init(msg, &iter) == FALSE)
1048 return __ofono_error_invalid_args(msg);
1050 if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
1051 return __ofono_error_invalid_args(msg);
1053 dbus_message_iter_get_basic(&iter, &name);
1054 dbus_message_iter_next(&iter);
1056 if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT)
1057 return __ofono_error_invalid_args(msg);
1059 if (powering_down == TRUE)
1060 return __ofono_error_failed(msg);
1062 dbus_message_iter_recurse(&iter, &var);
1064 if (g_str_equal(name, "Online"))
1065 return set_property_online(modem, msg, &var);
1067 if (g_str_equal(name, "Powered") == TRUE) {
1068 ofono_bool_t powered;
1071 if (dbus_message_iter_get_arg_type(&var) != DBUS_TYPE_BOOLEAN)
1072 return __ofono_error_invalid_args(msg);
1074 dbus_message_iter_get_basic(&var, &powered);
1076 if (modem->pending != NULL)
1077 return __ofono_error_busy(msg);
1079 if (modem->powered == powered)
1080 return dbus_message_new_method_return(msg);
1082 if (ofono_modem_get_emergency_mode(modem) == TRUE)
1083 return __ofono_error_emergency_active(msg);
1085 if (modem->lockdown)
1086 return __ofono_error_access_denied(msg);
1088 err = set_powered(modem, powered);
1090 if (err != -EINPROGRESS)
1091 return __ofono_error_failed(msg);
1093 modem->pending = dbus_message_ref(msg);
1094 modem->timeout = g_timeout_add_seconds(20,
1095 set_powered_timeout, modem);
1099 g_dbus_send_reply(conn, msg, DBUS_TYPE_INVALID);
1101 ofono_dbus_signal_property_changed(conn, modem->path,
1102 OFONO_MODEM_INTERFACE,
1103 "Powered", DBUS_TYPE_BOOLEAN,
1107 modem_change_state(modem, MODEM_STATE_PRE_SIM);
1109 /* Force SIM Ready for devies with no sim atom */
1110 if (modem_has_sim(modem) == FALSE)
1111 sim_state_watch(OFONO_SIM_STATE_READY, modem);
1113 set_online(modem, FALSE);
1114 modem_change_state(modem, MODEM_STATE_POWER_OFF);
1120 if (g_str_equal(name, "Lockdown"))
1121 return set_property_lockdown(modem, msg, &var);
1123 return __ofono_error_invalid_args(msg);
1126 static const GDBusMethodTable modem_methods[] = {
1127 { GDBUS_METHOD("GetProperties",
1128 NULL, GDBUS_ARGS({ "properties", "a{sv}" }),
1129 modem_get_properties) },
1130 { GDBUS_ASYNC_METHOD("SetProperty",
1131 GDBUS_ARGS({ "property", "s" }, { "value", "v" }),
1132 NULL, modem_set_property) },
1136 static const GDBusSignalTable modem_signals[] = {
1137 { GDBUS_SIGNAL("PropertyChanged",
1138 GDBUS_ARGS({ "name", "s" }, { "value", "v" })) },
1142 void ofono_modem_set_powered(struct ofono_modem *modem, ofono_bool_t powered)
1144 DBusConnection *conn = ofono_dbus_get_connection();
1145 dbus_bool_t dbus_powered = powered;
1147 if (modem->timeout > 0) {
1148 g_source_remove(modem->timeout);
1152 if (modem->powered_pending != modem->powered &&
1153 modem->pending != NULL) {
1156 if (powered == modem->powered_pending)
1157 reply = dbus_message_new_method_return(modem->pending);
1159 reply = __ofono_error_failed(modem->pending);
1161 __ofono_dbus_pending_reply(&modem->pending, reply);
1164 modem->powered_pending = powered;
1166 if (modem->powered == powered)
1169 modem->powered = powered;
1170 notify_powered_watches(modem);
1172 if (modem->lockdown)
1173 ofono_dbus_signal_property_changed(conn, modem->path,
1174 OFONO_MODEM_INTERFACE,
1175 "Lockdown", DBUS_TYPE_BOOLEAN,
1178 if (modem->driver == NULL) {
1179 ofono_error("Calling ofono_modem_set_powered on a"
1180 "modem with no driver is not valid, "
1181 "please fix the modem driver.");
1185 ofono_dbus_signal_property_changed(conn, modem->path,
1186 OFONO_MODEM_INTERFACE,
1187 "Powered", DBUS_TYPE_BOOLEAN,
1191 modem_change_state(modem, MODEM_STATE_PRE_SIM);
1193 /* Force SIM Ready for devices with no sim atom */
1194 if (modem_has_sim(modem) == FALSE)
1195 sim_state_watch(OFONO_SIM_STATE_READY, modem);
1197 set_online(modem, FALSE);
1199 modem_change_state(modem, MODEM_STATE_POWER_OFF);
1203 if (powering_down && powered == FALSE) {
1204 modems_remaining -= 1;
1206 if (modems_remaining == 0)
1211 ofono_bool_t ofono_modem_get_powered(struct ofono_modem *modem)
1216 return modem->powered;
1219 static gboolean trigger_interface_update(void *data)
1221 struct ofono_modem *modem = data;
1222 DBusConnection *conn = ofono_dbus_get_connection();
1228 interfaces = g_new0(char *, g_slist_length(modem->interface_list) + 1);
1229 for (i = 0, l = modem->interface_list; l; l = l->next, i++)
1230 interfaces[i] = l->data;
1231 ofono_dbus_signal_array_property_changed(conn, modem->path,
1232 OFONO_MODEM_INTERFACE,
1233 "Interfaces", DBUS_TYPE_STRING,
1237 features = g_new0(char *, g_slist_length(modem->feature_list) + 1);
1238 for (i = 0, l = modem->feature_list; l; l = l->next, i++)
1239 features[i] = l->data;
1240 ofono_dbus_signal_array_property_changed(conn, modem->path,
1241 OFONO_MODEM_INTERFACE,
1242 "Features", DBUS_TYPE_STRING,
1246 modem->interface_update = 0;
1251 static const struct {
1252 const char *interface;
1253 const char *feature;
1255 { OFONO_NETWORK_REGISTRATION_INTERFACE, "net" },
1256 { OFONO_RADIO_SETTINGS_INTERFACE, "rat" },
1257 { OFONO_CELL_BROADCAST_INTERFACE, "cbs" },
1258 { OFONO_MESSAGE_MANAGER_INTERFACE, "sms" },
1259 { OFONO_SIM_MANAGER_INTERFACE, "sim" },
1260 { OFONO_STK_INTERFACE, "stk" },
1261 { OFONO_SUPPLEMENTARY_SERVICES_INTERFACE, "ussd" },
1262 { OFONO_CONNECTION_MANAGER_INTERFACE, "gprs" },
1263 { OFONO_TEXT_TELEPHONY_INTERFACE, "tty" },
1264 { OFONO_LOCATION_REPORTING_INTERFACE, "gps" },
1268 static const char *get_feature(const char *interface)
1272 for (i = 0; feature_map[i].interface; i++) {
1273 if (strcmp(feature_map[i].interface, interface) == 0)
1274 return feature_map[i].feature;
1280 void ofono_modem_add_interface(struct ofono_modem *modem,
1281 const char *interface)
1283 const char *feature;
1285 modem->interface_list = g_slist_prepend(modem->interface_list,
1286 g_strdup(interface));
1288 feature = get_feature(interface);
1290 modem->feature_list = g_slist_prepend(modem->feature_list,
1293 if (modem->interface_update != 0)
1296 modem->interface_update = g_idle_add(trigger_interface_update, modem);
1299 void ofono_modem_remove_interface(struct ofono_modem *modem,
1300 const char *interface)
1303 const char *feature;
1305 found = g_slist_find_custom(modem->interface_list, interface,
1306 (GCompareFunc) strcmp);
1307 if (found == NULL) {
1308 ofono_error("Interface %s not found on the interface_list",
1313 g_free(found->data);
1314 modem->interface_list = g_slist_remove(modem->interface_list,
1317 feature = get_feature(interface);
1319 found = g_slist_find_custom(modem->feature_list, feature,
1320 (GCompareFunc) strcmp);
1322 g_free(found->data);
1323 modem->feature_list =
1324 g_slist_remove(modem->feature_list,
1329 if (modem->interface_update != 0)
1332 modem->interface_update = g_idle_add(trigger_interface_update, modem);
1335 static void query_serial_cb(const struct ofono_error *error,
1336 const char *serial, void *user)
1338 struct ofono_devinfo *info = user;
1339 DBusConnection *conn = ofono_dbus_get_connection();
1340 const char *path = __ofono_atom_get_path(info->atom);
1342 if (error->type != OFONO_ERROR_TYPE_NO_ERROR)
1345 info->serial = g_strdup(serial);
1347 ofono_dbus_signal_property_changed(conn, path,
1348 OFONO_MODEM_INTERFACE,
1349 "Serial", DBUS_TYPE_STRING,
1353 static void query_serial(struct ofono_devinfo *info)
1355 if (info->driver->query_serial == NULL)
1358 info->driver->query_serial(info, query_serial_cb, info);
1361 static void query_revision_cb(const struct ofono_error *error,
1362 const char *revision, void *user)
1364 struct ofono_devinfo *info = user;
1365 DBusConnection *conn = ofono_dbus_get_connection();
1366 const char *path = __ofono_atom_get_path(info->atom);
1368 if (error->type != OFONO_ERROR_TYPE_NO_ERROR)
1371 info->revision = g_strdup(revision);
1373 ofono_dbus_signal_property_changed(conn, path,
1374 OFONO_MODEM_INTERFACE,
1375 "Revision", DBUS_TYPE_STRING,
1382 static void query_revision(struct ofono_devinfo *info)
1384 if (info->driver->query_revision == NULL) {
1389 info->driver->query_revision(info, query_revision_cb, info);
1392 static void query_model_cb(const struct ofono_error *error,
1393 const char *model, void *user)
1395 struct ofono_devinfo *info = user;
1396 DBusConnection *conn = ofono_dbus_get_connection();
1397 const char *path = __ofono_atom_get_path(info->atom);
1399 if (error->type != OFONO_ERROR_TYPE_NO_ERROR)
1402 info->model = g_strdup(model);
1404 ofono_dbus_signal_property_changed(conn, path,
1405 OFONO_MODEM_INTERFACE,
1406 "Model", DBUS_TYPE_STRING,
1410 query_revision(info);
1413 static void query_model(struct ofono_devinfo *info)
1415 if (info->driver->query_model == NULL) {
1416 /* If model is not supported, don't bother querying revision */
1421 info->driver->query_model(info, query_model_cb, info);
1424 static void query_manufacturer_cb(const struct ofono_error *error,
1425 const char *manufacturer, void *user)
1427 struct ofono_devinfo *info = user;
1428 DBusConnection *conn = ofono_dbus_get_connection();
1429 const char *path = __ofono_atom_get_path(info->atom);
1431 if (error->type != OFONO_ERROR_TYPE_NO_ERROR)
1434 info->manufacturer = g_strdup(manufacturer);
1436 ofono_dbus_signal_property_changed(conn, path,
1437 OFONO_MODEM_INTERFACE,
1440 &info->manufacturer);
1446 static gboolean query_manufacturer(gpointer user)
1448 struct ofono_devinfo *info = user;
1450 if (info->driver->query_manufacturer == NULL) {
1455 info->driver->query_manufacturer(info, query_manufacturer_cb, info);
1460 static void attr_template(struct ofono_emulator *em,
1461 struct ofono_emulator_request *req,
1464 struct ofono_error result;
1471 switch (ofono_emulator_request_get_type(req)) {
1472 case OFONO_EMULATOR_REQUEST_TYPE_COMMAND_ONLY:
1473 ofono_emulator_send_info(em, attr, TRUE);
1474 result.type = OFONO_ERROR_TYPE_NO_ERROR;
1475 ofono_emulator_send_final(em, &result);
1477 case OFONO_EMULATOR_REQUEST_TYPE_SUPPORT:
1478 result.type = OFONO_ERROR_TYPE_NO_ERROR;
1479 ofono_emulator_send_final(em, &result);
1482 result.type = OFONO_ERROR_TYPE_FAILURE;
1483 ofono_emulator_send_final(em, &result);
1487 static void gmi_cb(struct ofono_emulator *em,
1488 struct ofono_emulator_request *req, void *userdata)
1490 struct ofono_devinfo *info = userdata;
1492 attr_template(em, req, info->manufacturer);
1495 static void gmm_cb(struct ofono_emulator *em,
1496 struct ofono_emulator_request *req, void *userdata)
1498 struct ofono_devinfo *info = userdata;
1500 attr_template(em, req, info->model);
1503 static void gmr_cb(struct ofono_emulator *em,
1504 struct ofono_emulator_request *req, void *userdata)
1506 struct ofono_devinfo *info = userdata;
1508 attr_template(em, req, info->revision);
1511 static void gcap_cb(struct ofono_emulator *em,
1512 struct ofono_emulator_request *req, void *userdata)
1514 attr_template(em, req, "+GCAP: +CGSM");
1517 static void dun_watch(struct ofono_atom *atom,
1518 enum ofono_atom_watch_condition cond, void *data)
1520 struct ofono_emulator *em = __ofono_atom_get_data(atom);
1522 if (cond == OFONO_ATOM_WATCH_CONDITION_UNREGISTERED)
1525 ofono_emulator_add_handler(em, "+GMI", gmi_cb, data, NULL);
1526 ofono_emulator_add_handler(em, "+GMM", gmm_cb, data, NULL);
1527 ofono_emulator_add_handler(em, "+GMR", gmr_cb, data, NULL);
1528 ofono_emulator_add_handler(em, "+GCAP", gcap_cb, data, NULL);
1531 int ofono_devinfo_driver_register(const struct ofono_devinfo_driver *d)
1533 DBG("driver: %p, name: %s", d, d->name);
1535 if (d->probe == NULL)
1538 g_devinfo_drivers = g_slist_prepend(g_devinfo_drivers, (void *) d);
1543 void ofono_devinfo_driver_unregister(const struct ofono_devinfo_driver *d)
1545 DBG("driver: %p, name: %s", d, d->name);
1547 g_devinfo_drivers = g_slist_remove(g_devinfo_drivers, (void *) d);
1550 static void devinfo_remove(struct ofono_atom *atom)
1552 struct ofono_devinfo *info = __ofono_atom_get_data(atom);
1553 DBG("atom: %p", atom);
1558 if (info->driver == NULL)
1561 if (info->driver->remove)
1562 info->driver->remove(info);
1567 struct ofono_devinfo *ofono_devinfo_create(struct ofono_modem *modem,
1568 unsigned int vendor,
1572 struct ofono_devinfo *info;
1575 info = g_new0(struct ofono_devinfo, 1);
1577 info->atom = __ofono_modem_add_atom(modem, OFONO_ATOM_TYPE_DEVINFO,
1578 devinfo_remove, info);
1580 for (l = g_devinfo_drivers; l; l = l->next) {
1581 const struct ofono_devinfo_driver *drv = l->data;
1583 if (g_strcmp0(drv->name, driver))
1586 if (drv->probe(info, vendor, data) < 0)
1596 static void devinfo_unregister(struct ofono_atom *atom)
1598 struct ofono_devinfo *info = __ofono_atom_get_data(atom);
1600 g_free(info->manufacturer);
1601 info->manufacturer = NULL;
1603 g_free(info->model);
1606 g_free(info->revision);
1607 info->revision = NULL;
1609 g_free(info->serial);
1610 info->serial = NULL;
1613 void ofono_devinfo_register(struct ofono_devinfo *info)
1615 struct ofono_modem *modem = __ofono_atom_get_modem(info->atom);
1617 __ofono_atom_register(info->atom, devinfo_unregister);
1619 info->dun_watch = __ofono_modem_add_atom_watch(modem,
1620 OFONO_ATOM_TYPE_EMULATOR_DUN,
1621 dun_watch, info, NULL);
1623 query_manufacturer(info);
1626 void ofono_devinfo_remove(struct ofono_devinfo *info)
1628 __ofono_atom_free(info->atom);
1631 void ofono_devinfo_set_data(struct ofono_devinfo *info, void *data)
1633 info->driver_data = data;
1636 void *ofono_devinfo_get_data(struct ofono_devinfo *info)
1638 return info->driver_data;
1641 static void unregister_property(gpointer data)
1643 struct modem_property *property = data;
1645 DBG("property %p", property);
1647 g_free(property->value);
1651 static int set_modem_property(struct ofono_modem *modem, const char *name,
1652 enum property_type type, const void *value)
1654 struct modem_property *property;
1656 DBG("modem %p property %s", modem, name);
1658 if (type != PROPERTY_TYPE_STRING &&
1659 type != PROPERTY_TYPE_INTEGER)
1662 property = g_try_new0(struct modem_property, 1);
1663 if (property == NULL)
1666 property->type = type;
1669 case PROPERTY_TYPE_STRING:
1670 property->value = g_strdup((const char *) value);
1672 case PROPERTY_TYPE_INTEGER:
1673 property->value = g_memdup(value, sizeof(int));
1675 case PROPERTY_TYPE_BOOLEAN:
1676 property->value = g_memdup(value, sizeof(ofono_bool_t));
1682 g_hash_table_replace(modem->properties, g_strdup(name), property);
1687 static gboolean get_modem_property(struct ofono_modem *modem, const char *name,
1688 enum property_type type,
1691 struct modem_property *property;
1693 DBG("modem %p property %s", modem, name);
1695 property = g_hash_table_lookup(modem->properties, name);
1697 if (property == NULL)
1700 if (property->type != type)
1703 switch (property->type) {
1704 case PROPERTY_TYPE_STRING:
1705 *((const char **) value) = property->value;
1707 case PROPERTY_TYPE_INTEGER:
1708 memcpy(value, property->value, sizeof(int));
1710 case PROPERTY_TYPE_BOOLEAN:
1711 memcpy(value, property->value, sizeof(ofono_bool_t));
1718 int ofono_modem_set_string(struct ofono_modem *modem,
1719 const char *key, const char *value)
1721 return set_modem_property(modem, key, PROPERTY_TYPE_STRING, value);
1724 int ofono_modem_set_integer(struct ofono_modem *modem,
1725 const char *key, int value)
1727 return set_modem_property(modem, key, PROPERTY_TYPE_INTEGER, &value);
1730 int ofono_modem_set_boolean(struct ofono_modem *modem,
1731 const char *key, ofono_bool_t value)
1733 return set_modem_property(modem, key, PROPERTY_TYPE_BOOLEAN, &value);
1736 const char *ofono_modem_get_string(struct ofono_modem *modem, const char *key)
1740 if (get_modem_property(modem, key,
1741 PROPERTY_TYPE_STRING, &value) == FALSE)
1747 int ofono_modem_get_integer(struct ofono_modem *modem, const char *key)
1751 if (get_modem_property(modem, key,
1752 PROPERTY_TYPE_INTEGER, &value) == FALSE)
1758 ofono_bool_t ofono_modem_get_boolean(struct ofono_modem *modem, const char *key)
1762 if (get_modem_property(modem, key,
1763 PROPERTY_TYPE_BOOLEAN, &value) == FALSE)
1769 void ofono_modem_set_name(struct ofono_modem *modem, const char *name)
1772 g_free(modem->name);
1774 modem->name = g_strdup(name);
1776 if (modem->driver) {
1777 DBusConnection *conn = ofono_dbus_get_connection();
1779 ofono_dbus_signal_property_changed(conn, modem->path,
1780 OFONO_MODEM_INTERFACE,
1781 "Name", DBUS_TYPE_STRING,
1786 void ofono_modem_set_driver(struct ofono_modem *modem, const char *type)
1788 DBG("type: %s", type);
1793 if (strlen(type) > 16)
1796 g_free(modem->driver_type);
1797 modem->driver_type = g_strdup(type);
1800 struct ofono_modem *ofono_modem_create(const char *name, const char *type)
1802 struct ofono_modem *modem;
1805 DBG("name: %s, type: %s", name, type);
1807 if (strlen(type) > 16)
1810 if (name && strlen(name) > 64)
1814 snprintf(path, sizeof(path), "/%s_%d", type, next_modem_id);
1816 snprintf(path, sizeof(path), "/%s", name);
1818 if (__ofono_dbus_valid_object_path(path) == FALSE)
1821 modem = g_try_new0(struct ofono_modem, 1);
1826 modem->path = g_strdup(path);
1827 modem->driver_type = g_strdup(type);
1828 modem->properties = g_hash_table_new_full(g_str_hash, g_str_equal,
1829 g_free, unregister_property);
1831 g_modem_list = g_slist_prepend(g_modem_list, modem);
1839 static void sim_watch(struct ofono_atom *atom,
1840 enum ofono_atom_watch_condition cond, void *data)
1842 struct ofono_modem *modem = data;
1844 if (cond == OFONO_ATOM_WATCH_CONDITION_UNREGISTERED) {
1845 modem->sim_ready_watch = 0;
1849 modem->sim = __ofono_atom_get_data(atom);
1850 modem->sim_ready_watch = ofono_sim_add_state_watch(modem->sim,
1855 void __ofono_modemwatch_init(void)
1857 g_modemwatches = __ofono_watchlist_new(g_free);
1860 void __ofono_modemwatch_cleanup(void)
1862 __ofono_watchlist_free(g_modemwatches);
1865 unsigned int __ofono_modemwatch_add(ofono_modemwatch_cb_t cb, void *user,
1866 ofono_destroy_func destroy)
1868 struct ofono_watchlist_item *watch;
1873 watch = g_new0(struct ofono_watchlist_item, 1);
1876 watch->destroy = destroy;
1877 watch->notify_data = user;
1879 return __ofono_watchlist_add_item(g_modemwatches, watch);
1882 gboolean __ofono_modemwatch_remove(unsigned int id)
1884 return __ofono_watchlist_remove_item(g_modemwatches, id);
1887 static void call_modemwatches(struct ofono_modem *modem, gboolean added)
1890 struct ofono_watchlist_item *watch;
1891 ofono_modemwatch_cb_t notify;
1893 DBG("%p added:%d", modem, added);
1895 for (l = g_modemwatches->items; l; l = l->next) {
1898 notify = watch->notify;
1899 notify(modem, added, watch->notify_data);
1903 static void emit_modem_added(struct ofono_modem *modem)
1905 DBusMessage *signal;
1906 DBusMessageIter iter;
1907 DBusMessageIter dict;
1912 signal = dbus_message_new_signal(OFONO_MANAGER_PATH,
1913 OFONO_MANAGER_INTERFACE,
1919 dbus_message_iter_init_append(signal, &iter);
1922 dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH, &path);
1923 dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
1924 OFONO_PROPERTIES_ARRAY_SIGNATURE,
1926 __ofono_modem_append_properties(modem, &dict);
1927 dbus_message_iter_close_container(&iter, &dict);
1929 g_dbus_send_message(ofono_dbus_get_connection(), signal);
1932 ofono_bool_t ofono_modem_is_registered(struct ofono_modem *modem)
1937 if (modem->driver == NULL)
1943 int ofono_modem_register(struct ofono_modem *modem)
1945 DBusConnection *conn = ofono_dbus_get_connection();
1953 if (powering_down == TRUE)
1956 if (modem->driver != NULL)
1959 for (l = g_driver_list; l; l = l->next) {
1960 const struct ofono_modem_driver *drv = l->data;
1962 if (g_strcmp0(drv->name, modem->driver_type))
1965 if (drv->probe(modem) < 0)
1968 modem->driver = drv;
1972 if (modem->driver == NULL)
1975 if (!g_dbus_register_interface(conn, modem->path,
1976 OFONO_MODEM_INTERFACE,
1977 modem_methods, modem_signals, NULL,
1979 ofono_error("Modem register failed on path %s", modem->path);
1981 if (modem->driver->remove)
1982 modem->driver->remove(modem);
1984 modem->driver = NULL;
1989 g_free(modem->driver_type);
1990 modem->driver_type = NULL;
1992 modem->atom_watches = __ofono_watchlist_new(g_free);
1993 modem->online_watches = __ofono_watchlist_new(g_free);
1994 modem->powered_watches = __ofono_watchlist_new(g_free);
1996 emit_modem_added(modem);
1997 call_modemwatches(modem, TRUE);
1999 modem->sim_watch = __ofono_modem_add_atom_watch(modem,
2000 OFONO_ATOM_TYPE_SIM,
2001 sim_watch, modem, NULL);
2006 static void emit_modem_removed(struct ofono_modem *modem)
2008 DBusConnection *conn = ofono_dbus_get_connection();
2009 const char *path = modem->path;
2013 g_dbus_emit_signal(conn, OFONO_MANAGER_PATH, OFONO_MANAGER_INTERFACE,
2014 "ModemRemoved", DBUS_TYPE_OBJECT_PATH, &path,
2018 static void modem_unregister(struct ofono_modem *modem)
2020 DBusConnection *conn = ofono_dbus_get_connection();
2024 if (modem->powered == TRUE)
2025 set_powered(modem, FALSE);
2027 __ofono_watchlist_free(modem->atom_watches);
2028 modem->atom_watches = NULL;
2030 __ofono_watchlist_free(modem->online_watches);
2031 modem->online_watches = NULL;
2033 __ofono_watchlist_free(modem->powered_watches);
2034 modem->powered_watches = NULL;
2036 modem->sim_watch = 0;
2037 modem->sim_ready_watch = 0;
2039 g_slist_foreach(modem->interface_list, (GFunc) g_free, NULL);
2040 g_slist_free(modem->interface_list);
2041 modem->interface_list = NULL;
2043 g_slist_foreach(modem->feature_list, (GFunc) g_free, NULL);
2044 g_slist_free(modem->feature_list);
2045 modem->feature_list = NULL;
2047 if (modem->timeout) {
2048 g_source_remove(modem->timeout);
2052 if (modem->pending) {
2053 dbus_message_unref(modem->pending);
2054 modem->pending = NULL;
2057 if (modem->interface_update) {
2058 g_source_remove(modem->interface_update);
2059 modem->interface_update = 0;
2062 if (modem->lock_watch) {
2063 lockdown_remove(modem);
2065 ofono_dbus_signal_property_changed(conn, modem->path,
2066 OFONO_MODEM_INTERFACE,
2067 "Lockdown", DBUS_TYPE_BOOLEAN,
2071 g_dbus_unregister_interface(conn, modem->path, OFONO_MODEM_INTERFACE);
2073 if (modem->driver && modem->driver->remove)
2074 modem->driver->remove(modem);
2076 g_hash_table_destroy(modem->properties);
2077 modem->properties = NULL;
2079 modem->driver = NULL;
2081 emit_modem_removed(modem);
2082 call_modemwatches(modem, FALSE);
2085 void ofono_modem_remove(struct ofono_modem *modem)
2093 modem_unregister(modem);
2095 g_modem_list = g_slist_remove(g_modem_list, modem);
2097 g_free(modem->driver_type);
2098 g_free(modem->name);
2099 g_free(modem->path);
2103 void ofono_modem_reset(struct ofono_modem *modem)
2109 if (modem->pending) {
2110 DBusMessage *reply = __ofono_error_failed(modem->pending);
2111 __ofono_dbus_pending_reply(&modem->pending, reply);
2114 if (modem->modem_state == MODEM_STATE_ONLINE)
2115 modem->get_online = TRUE;
2117 ofono_modem_set_powered(modem, FALSE);
2119 err = set_powered(modem, TRUE);
2120 if (err == -EINPROGRESS)
2123 modem_change_state(modem, MODEM_STATE_PRE_SIM);
2126 void __ofono_modem_sim_reset(struct ofono_modem *modem)
2130 modem_change_state(modem, MODEM_STATE_PRE_SIM);
2133 int ofono_modem_driver_register(const struct ofono_modem_driver *d)
2135 DBG("driver: %p, name: %s", d, d->name);
2137 if (d->probe == NULL)
2140 g_driver_list = g_slist_prepend(g_driver_list, (void *) d);
2145 void ofono_modem_driver_unregister(const struct ofono_modem_driver *d)
2148 struct ofono_modem *modem;
2150 DBG("driver: %p, name: %s", d, d->name);
2152 g_driver_list = g_slist_remove(g_driver_list, (void *) d);
2154 for (l = g_modem_list; l; l = l->next) {
2157 if (modem->driver != d)
2160 modem_unregister(modem);
2164 void __ofono_modem_shutdown(void)
2166 struct ofono_modem *modem;
2169 powering_down = TRUE;
2171 for (l = g_modem_list; l; l = l->next) {
2174 if (modem->driver == NULL)
2177 if (modem->powered == FALSE && modem->powered_pending == FALSE)
2180 if (set_powered(modem, FALSE) == -EINPROGRESS)
2181 modems_remaining += 1;
2184 if (modems_remaining == 0)
2188 void __ofono_modem_foreach(ofono_modem_foreach_func func, void *userdata)
2190 struct ofono_modem *modem;
2193 for (l = g_modem_list; l; l = l->next) {
2195 func(modem, userdata);
2199 ofono_bool_t ofono_modem_get_emergency_mode(struct ofono_modem *modem)
2201 return modem->emergency != 0;
2204 void __ofono_modem_inc_emergency_mode(struct ofono_modem *modem)
2206 DBusConnection *conn = ofono_dbus_get_connection();
2207 dbus_bool_t emergency = TRUE;
2209 if (++modem->emergency > 1)
2212 ofono_dbus_signal_property_changed(conn, modem->path,
2213 OFONO_MODEM_INTERFACE,
2214 "Emergency", DBUS_TYPE_BOOLEAN,
2218 void __ofono_modem_dec_emergency_mode(struct ofono_modem *modem)
2220 DBusConnection *conn = ofono_dbus_get_connection();
2221 dbus_bool_t emergency = FALSE;
2223 if (modem->emergency == 0) {
2224 ofono_error("emergency mode is already deactivated!!!");
2228 if (modem->emergency > 1)
2231 ofono_dbus_signal_property_changed(conn, modem->path,
2232 OFONO_MODEM_INTERFACE,
2233 "Emergency", DBUS_TYPE_BOOLEAN,