telephony-ofono.c revision 806c74dbebe7402d0485f80854b95aca8e68fcea
1a34c155f55270b917795d003be24488f53d9b711Forrest Zhao/*
2a34c155f55270b917795d003be24488f53d9b711Forrest Zhao *
3a34c155f55270b917795d003be24488f53d9b711Forrest Zhao *  BlueZ - Bluetooth protocol stack for Linux
4a34c155f55270b917795d003be24488f53d9b711Forrest Zhao *
5d3b613c392352f59fd6b18becf80e6504ad2423cMarcel Holtmann *  Copyright (C) 2009-2010  Intel Corporation
65592142cb9383df0556b27ac59e96547b380310bJohan Hedberg *  Copyright (C) 2006-2009  Nokia Corporation
79184e2eeb7b97371c6b83b747c8984e2340d2b47Marcel Holtmann *  Copyright (C) 2004-2010  Marcel Holtmann <marcel@holtmann.org>
8a34c155f55270b917795d003be24488f53d9b711Forrest Zhao *
9a34c155f55270b917795d003be24488f53d9b711Forrest Zhao *
10a34c155f55270b917795d003be24488f53d9b711Forrest Zhao *  This program is free software; you can redistribute it and/or modify
11a34c155f55270b917795d003be24488f53d9b711Forrest Zhao *  it under the terms of the GNU General Public License as published by
12a34c155f55270b917795d003be24488f53d9b711Forrest Zhao *  the Free Software Foundation; either version 2 of the License, or
13a34c155f55270b917795d003be24488f53d9b711Forrest Zhao *  (at your option) any later version.
14a34c155f55270b917795d003be24488f53d9b711Forrest Zhao *
15a34c155f55270b917795d003be24488f53d9b711Forrest Zhao *  This program is distributed in the hope that it will be useful,
16a34c155f55270b917795d003be24488f53d9b711Forrest Zhao *  but WITHOUT ANY WARRANTY; without even the implied warranty of
17a34c155f55270b917795d003be24488f53d9b711Forrest Zhao *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18a34c155f55270b917795d003be24488f53d9b711Forrest Zhao *  GNU General Public License for more details.
19a34c155f55270b917795d003be24488f53d9b711Forrest Zhao *
20a34c155f55270b917795d003be24488f53d9b711Forrest Zhao *  You should have received a copy of the GNU General Public License
21a34c155f55270b917795d003be24488f53d9b711Forrest Zhao *  along with this program; if not, write to the Free Software
22a34c155f55270b917795d003be24488f53d9b711Forrest Zhao *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
23a34c155f55270b917795d003be24488f53d9b711Forrest Zhao *
24a34c155f55270b917795d003be24488f53d9b711Forrest Zhao */
25a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
26a34c155f55270b917795d003be24488f53d9b711Forrest Zhao#ifdef HAVE_CONFIG_H
27a34c155f55270b917795d003be24488f53d9b711Forrest Zhao#include <config.h>
28a34c155f55270b917795d003be24488f53d9b711Forrest Zhao#endif
29a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
30a34c155f55270b917795d003be24488f53d9b711Forrest Zhao#include <stdlib.h>
31a34c155f55270b917795d003be24488f53d9b711Forrest Zhao#include <stdio.h>
32a34c155f55270b917795d003be24488f53d9b711Forrest Zhao#include <string.h>
33a34c155f55270b917795d003be24488f53d9b711Forrest Zhao#include <stdint.h>
34a34c155f55270b917795d003be24488f53d9b711Forrest Zhao#include <glib.h>
35a34c155f55270b917795d003be24488f53d9b711Forrest Zhao#include <dbus/dbus.h>
36a34c155f55270b917795d003be24488f53d9b711Forrest Zhao#include <gdbus.h>
37a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
38e891f7df6225c758da0d95f7554c6cc67f72f31eGustavo F. Padovan#include "log.h"
39a34c155f55270b917795d003be24488f53d9b711Forrest Zhao#include "telephony.h"
40a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
41a34c155f55270b917795d003be24488f53d9b711Forrest Zhaoenum net_registration_status {
42a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	NETWORK_REG_STATUS_HOME = 0x00,
43a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	NETWORK_REG_STATUS_ROAM,
44a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	NETWORK_REG_STATUS_NOSERV
45a34c155f55270b917795d003be24488f53d9b711Forrest Zhao};
46a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
47a34c155f55270b917795d003be24488f53d9b711Forrest Zhaostruct voice_call {
48a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	char *obj_path;
49a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	int status;
50a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	gboolean originating;
51a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	char *number;
528309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	guint watch;
53a34c155f55270b917795d003be24488f53d9b711Forrest Zhao};
54a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
55a34c155f55270b917795d003be24488f53d9b711Forrest Zhaostatic DBusConnection *connection = NULL;
56a34c155f55270b917795d003be24488f53d9b711Forrest Zhaostatic char *modem_obj_path = NULL;
57a34c155f55270b917795d003be24488f53d9b711Forrest Zhaostatic char *last_dialed_number = NULL;
58a34c155f55270b917795d003be24488f53d9b711Forrest Zhaostatic GSList *calls = NULL;
599946e8636c3361dc769c5f8a463b74158018d3ddLuiz Augusto von Dentzstatic GSList *watches = NULL;
60c49dc8c7c815191b5825896f827cac2e2ff395ffLuiz Augusto von Dentzstatic GSList *pending = NULL;
61a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
62a34c155f55270b917795d003be24488f53d9b711Forrest Zhao#define OFONO_BUS_NAME "org.ofono"
63a34c155f55270b917795d003be24488f53d9b711Forrest Zhao#define OFONO_PATH "/"
64806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz#define OFONO_MODEM_INTERFACE "org.ofono.Modem"
65d89690657f2634ceb9d4b13257ccc7d60bc0cb5dForrest Zhao#define OFONO_MANAGER_INTERFACE "org.ofono.Manager"
66a34c155f55270b917795d003be24488f53d9b711Forrest Zhao#define OFONO_NETWORKREG_INTERFACE "org.ofono.NetworkRegistration"
67a34c155f55270b917795d003be24488f53d9b711Forrest Zhao#define OFONO_VCMANAGER_INTERFACE "org.ofono.VoiceCallManager"
68a34c155f55270b917795d003be24488f53d9b711Forrest Zhao#define OFONO_VC_INTERFACE "org.ofono.VoiceCall"
69a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
70a34c155f55270b917795d003be24488f53d9b711Forrest Zhao/* HAL battery namespace key values */
71a34c155f55270b917795d003be24488f53d9b711Forrest Zhaostatic int battchg_cur = -1;    /* "battery.charge_level.current" */
72a34c155f55270b917795d003be24488f53d9b711Forrest Zhaostatic int battchg_last = -1;   /* "battery.charge_level.last_full" */
73a34c155f55270b917795d003be24488f53d9b711Forrest Zhaostatic int battchg_design = -1; /* "battery.charge_level.design" */
74a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
75a34c155f55270b917795d003be24488f53d9b711Forrest Zhaostatic struct {
76a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	uint8_t status;
77a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	uint32_t signals_bar;
78a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	char *operator_name;
79a34c155f55270b917795d003be24488f53d9b711Forrest Zhao} net = {
80a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	.status = NETWORK_REG_STATUS_NOSERV,
81a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	.signals_bar = 0,
82a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	.operator_name = NULL,
83a34c155f55270b917795d003be24488f53d9b711Forrest Zhao};
84a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
85a34c155f55270b917795d003be24488f53d9b711Forrest Zhaostatic const char *chld_str = "0,1,1x,2,2x,3,4";
86a34c155f55270b917795d003be24488f53d9b711Forrest Zhaostatic char *subscriber_number = NULL;
87a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
88a34c155f55270b917795d003be24488f53d9b711Forrest Zhaostatic gboolean events_enabled = FALSE;
89a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
90a34c155f55270b917795d003be24488f53d9b711Forrest Zhaostatic struct indicator ofono_indicators[] =
91a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
92884debf8418651b63b1a5a8918092ba4d230783eJohan Hedberg	{ "battchg",	"0-5",	5,	TRUE },
93884debf8418651b63b1a5a8918092ba4d230783eJohan Hedberg	{ "signal",	"0-5",	5,	TRUE },
94884debf8418651b63b1a5a8918092ba4d230783eJohan Hedberg	{ "service",	"0,1",	1,	TRUE },
95884debf8418651b63b1a5a8918092ba4d230783eJohan Hedberg	{ "call",	"0,1",	0,	TRUE },
96884debf8418651b63b1a5a8918092ba4d230783eJohan Hedberg	{ "callsetup",	"0-3",	0,	TRUE },
97884debf8418651b63b1a5a8918092ba4d230783eJohan Hedberg	{ "callheld",	"0-2",	0,	FALSE },
98884debf8418651b63b1a5a8918092ba4d230783eJohan Hedberg	{ "roam",	"0,1",	0,	TRUE },
99a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	{ NULL }
100a34c155f55270b917795d003be24488f53d9b711Forrest Zhao};
101a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
102a34c155f55270b917795d003be24488f53d9b711Forrest Zhaostatic struct voice_call *find_vc(const char *path)
103a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
104a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	GSList *l;
105a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
106a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	for (l = calls; l != NULL; l = l->next) {
107a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		struct voice_call *vc = l->data;
108a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
109a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		if (g_str_equal(vc->obj_path, path))
110a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			return vc;
111a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	}
112a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
113a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	return NULL;
114a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
115a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
116a34c155f55270b917795d003be24488f53d9b711Forrest Zhaostatic struct voice_call *find_vc_with_status(int status)
117a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
118a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	GSList *l;
119a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
120a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	for (l = calls; l != NULL; l = l->next) {
121a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		struct voice_call *vc = l->data;
122a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
123a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		if (vc->status == status)
124a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			return vc;
125a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	}
126a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
127a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	return NULL;
128a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
129a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1301097cfd46e906ddfd8a827ce683c1eddf2d98499Luiz Augusto von Dentzstatic int number_type(const char *number)
1311097cfd46e906ddfd8a827ce683c1eddf2d98499Luiz Augusto von Dentz{
1321097cfd46e906ddfd8a827ce683c1eddf2d98499Luiz Augusto von Dentz	if (number == NULL)
1331097cfd46e906ddfd8a827ce683c1eddf2d98499Luiz Augusto von Dentz		return NUMBER_TYPE_TELEPHONY;
1341097cfd46e906ddfd8a827ce683c1eddf2d98499Luiz Augusto von Dentz
1351097cfd46e906ddfd8a827ce683c1eddf2d98499Luiz Augusto von Dentz	if (number[0] == '+' || strncmp(number, "00", 2) == 0)
1361097cfd46e906ddfd8a827ce683c1eddf2d98499Luiz Augusto von Dentz		return NUMBER_TYPE_INTERNATIONAL;
1371097cfd46e906ddfd8a827ce683c1eddf2d98499Luiz Augusto von Dentz
1381097cfd46e906ddfd8a827ce683c1eddf2d98499Luiz Augusto von Dentz	return NUMBER_TYPE_TELEPHONY;
1391097cfd46e906ddfd8a827ce683c1eddf2d98499Luiz Augusto von Dentz}
1401097cfd46e906ddfd8a827ce683c1eddf2d98499Luiz Augusto von Dentz
141a34c155f55270b917795d003be24488f53d9b711Forrest Zhaovoid telephony_device_connected(void *telephony_device)
142a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
1431097cfd46e906ddfd8a827ce683c1eddf2d98499Luiz Augusto von Dentz	struct voice_call *coming;
1441097cfd46e906ddfd8a827ce683c1eddf2d98499Luiz Augusto von Dentz
1458e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan	DBG("telephony-ofono: device %p connected", telephony_device);
1461097cfd46e906ddfd8a827ce683c1eddf2d98499Luiz Augusto von Dentz
1471097cfd46e906ddfd8a827ce683c1eddf2d98499Luiz Augusto von Dentz	coming = find_vc_with_status(CALL_STATUS_ALERTING);
1481097cfd46e906ddfd8a827ce683c1eddf2d98499Luiz Augusto von Dentz	if (coming) {
1491097cfd46e906ddfd8a827ce683c1eddf2d98499Luiz Augusto von Dentz		if (find_vc_with_status(CALL_STATUS_ACTIVE))
1501097cfd46e906ddfd8a827ce683c1eddf2d98499Luiz Augusto von Dentz			telephony_call_waiting_ind(coming->number,
1511097cfd46e906ddfd8a827ce683c1eddf2d98499Luiz Augusto von Dentz						number_type(coming->number));
1521097cfd46e906ddfd8a827ce683c1eddf2d98499Luiz Augusto von Dentz		else
1531097cfd46e906ddfd8a827ce683c1eddf2d98499Luiz Augusto von Dentz			telephony_incoming_call_ind(coming->number,
1541097cfd46e906ddfd8a827ce683c1eddf2d98499Luiz Augusto von Dentz						number_type(coming->number));
1551097cfd46e906ddfd8a827ce683c1eddf2d98499Luiz Augusto von Dentz	}
156a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
157a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
158a34c155f55270b917795d003be24488f53d9b711Forrest Zhaovoid telephony_device_disconnected(void *telephony_device)
159a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
1608e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan	DBG("telephony-ofono: device %p disconnected", telephony_device);
161a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	events_enabled = FALSE;
162a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
163a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
164a34c155f55270b917795d003be24488f53d9b711Forrest Zhaovoid telephony_event_reporting_req(void *telephony_device, int ind)
165a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
166a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	events_enabled = ind == 1 ? TRUE : FALSE;
167a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
168a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	telephony_event_reporting_rsp(telephony_device, CME_ERROR_NONE);
169a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
170a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
171a34c155f55270b917795d003be24488f53d9b711Forrest Zhaovoid telephony_response_and_hold_req(void *telephony_device, int rh)
172a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
173b0d302d48976920cec7548ec5cc603f3896bbb8cJohan Hedberg	telephony_response_and_hold_rsp(telephony_device,
174b0d302d48976920cec7548ec5cc603f3896bbb8cJohan Hedberg						CME_ERROR_NOT_SUPPORTED);
175a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
176a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
177a34c155f55270b917795d003be24488f53d9b711Forrest Zhaovoid telephony_last_dialed_number_req(void *telephony_device)
178a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
1798e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan	DBG("telephony-ofono: last dialed number request");
180a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
181a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	if (last_dialed_number)
182a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		telephony_dial_number_req(telephony_device, last_dialed_number);
183a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	else
184a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		telephony_last_dialed_number_rsp(telephony_device,
185a34c155f55270b917795d003be24488f53d9b711Forrest Zhao				CME_ERROR_NOT_ALLOWED);
186a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
187a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
188a34c155f55270b917795d003be24488f53d9b711Forrest Zhaostatic int send_method_call(const char *dest, const char *path,
189a34c155f55270b917795d003be24488f53d9b711Forrest Zhao                                const char *interface, const char *method,
190a34c155f55270b917795d003be24488f53d9b711Forrest Zhao                                DBusPendingCallNotifyFunction cb,
191a34c155f55270b917795d003be24488f53d9b711Forrest Zhao                                void *user_data, int type, ...)
192a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
193a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	DBusMessage *msg;
194a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	DBusPendingCall *call;
195a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	va_list args;
196a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
197a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	msg = dbus_message_new_method_call(dest, path, interface, method);
198a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	if (!msg) {
199a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		error("Unable to allocate new D-Bus %s message", method);
200a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		return -ENOMEM;
201a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	}
202a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
203a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	va_start(args, type);
204a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
205a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	if (!dbus_message_append_args_valist(msg, type, args)) {
206a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		dbus_message_unref(msg);
207a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		va_end(args);
208a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		return -EIO;
209a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	}
210a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
211a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	va_end(args);
212a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
213a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	if (!cb) {
214a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		g_dbus_send_message(connection, msg);
215a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		return 0;
216a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	}
217a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
218a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	if (!dbus_connection_send_with_reply(connection, msg, &call, -1)) {
219a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		error("Sending %s failed", method);
220a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		dbus_message_unref(msg);
221a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		return -EIO;
222a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	}
223a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
224a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	dbus_pending_call_set_notify(call, cb, user_data, NULL);
225c49dc8c7c815191b5825896f827cac2e2ff395ffLuiz Augusto von Dentz	pending = g_slist_prepend(pending, call);
226a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	dbus_message_unref(msg);
227a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
228a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	return 0;
229a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
230a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
231a34c155f55270b917795d003be24488f53d9b711Forrest Zhaovoid telephony_terminate_call_req(void *telephony_device)
232a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
233a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	struct voice_call *vc;
234a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	int ret;
235a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
236e925c22367a6b5c501c6635691d3e3399f492e78Marcel Holtmann	if ((vc = find_vc_with_status(CALL_STATUS_ACTIVE))) {
237e925c22367a6b5c501c6635691d3e3399f492e78Marcel Holtmann	} else if ((vc = find_vc_with_status(CALL_STATUS_DIALING))) {
238e925c22367a6b5c501c6635691d3e3399f492e78Marcel Holtmann	} else if ((vc = find_vc_with_status(CALL_STATUS_ALERTING))) {
239e925c22367a6b5c501c6635691d3e3399f492e78Marcel Holtmann	} else if ((vc = find_vc_with_status(CALL_STATUS_INCOMING))) {
240e925c22367a6b5c501c6635691d3e3399f492e78Marcel Holtmann	}
241a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
242a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	if (!vc) {
243a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		error("in telephony_terminate_call_req, no active call");
244a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		telephony_terminate_call_rsp(telephony_device,
245a34c155f55270b917795d003be24488f53d9b711Forrest Zhao					CME_ERROR_NOT_ALLOWED);
246a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		return;
247a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	}
248a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
249a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	ret = send_method_call(OFONO_BUS_NAME, vc->obj_path,
250a34c155f55270b917795d003be24488f53d9b711Forrest Zhao					OFONO_VC_INTERFACE,
251a34c155f55270b917795d003be24488f53d9b711Forrest Zhao					"Hangup", NULL,
252a34c155f55270b917795d003be24488f53d9b711Forrest Zhao					NULL, DBUS_TYPE_INVALID);
253a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
254a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	if (ret < 0) {
255a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		telephony_answer_call_rsp(telephony_device,
256a34c155f55270b917795d003be24488f53d9b711Forrest Zhao					CME_ERROR_AG_FAILURE);
257a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		return;
258a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	}
259a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
260a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	telephony_answer_call_rsp(telephony_device, CME_ERROR_NONE);
261a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
262a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
263a34c155f55270b917795d003be24488f53d9b711Forrest Zhaovoid telephony_answer_call_req(void *telephony_device)
264a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
26516ec168ac7fdd18cb2cbc7b3be7df349fd84c41cLuiz Augusto von Dentz	struct voice_call *vc;
266a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	int ret;
267a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
26816ec168ac7fdd18cb2cbc7b3be7df349fd84c41cLuiz Augusto von Dentz	vc = find_vc_with_status(CALL_STATUS_INCOMING);
26916ec168ac7fdd18cb2cbc7b3be7df349fd84c41cLuiz Augusto von Dentz	if (!vc)
27016ec168ac7fdd18cb2cbc7b3be7df349fd84c41cLuiz Augusto von Dentz		vc = find_vc_with_status(CALL_STATUS_ALERTING);
27116ec168ac7fdd18cb2cbc7b3be7df349fd84c41cLuiz Augusto von Dentz
27216ec168ac7fdd18cb2cbc7b3be7df349fd84c41cLuiz Augusto von Dentz	if (!vc)
27316ec168ac7fdd18cb2cbc7b3be7df349fd84c41cLuiz Augusto von Dentz		vc = find_vc_with_status(CALL_STATUS_WAITING);
27416ec168ac7fdd18cb2cbc7b3be7df349fd84c41cLuiz Augusto von Dentz
275a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	if (!vc) {
276a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		telephony_answer_call_rsp(telephony_device,
277a34c155f55270b917795d003be24488f53d9b711Forrest Zhao					CME_ERROR_NOT_ALLOWED);
278a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		return;
279a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	}
280a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
281a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	ret = send_method_call(OFONO_BUS_NAME, vc->obj_path,
282a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			OFONO_VC_INTERFACE,
283a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			"Answer", NULL,
284a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			NULL, DBUS_TYPE_INVALID);
285a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
286a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	if (ret < 0) {
287a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		telephony_answer_call_rsp(telephony_device,
288a34c155f55270b917795d003be24488f53d9b711Forrest Zhao					CME_ERROR_AG_FAILURE);
289a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		return;
290a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	}
291a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
292a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	telephony_answer_call_rsp(telephony_device, CME_ERROR_NONE);
293a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
294a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
295a34c155f55270b917795d003be24488f53d9b711Forrest Zhaovoid telephony_dial_number_req(void *telephony_device, const char *number)
296a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
29783003660808c30390f21c569a5ba7dbdd8344a41Claudio Takahasi	const char *clir;
298a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	int ret;
299a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
3008e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan	DBG("telephony-ofono: dial request to %s", number);
301a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
302c5321032b046c39477ab99a05e933b13d0b67a04Forrest Zhao	if (!modem_obj_path) {
303c5321032b046c39477ab99a05e933b13d0b67a04Forrest Zhao		telephony_dial_number_rsp(telephony_device,
304c5321032b046c39477ab99a05e933b13d0b67a04Forrest Zhao					CME_ERROR_AG_FAILURE);
305c5321032b046c39477ab99a05e933b13d0b67a04Forrest Zhao		return;
306c5321032b046c39477ab99a05e933b13d0b67a04Forrest Zhao	}
307c5321032b046c39477ab99a05e933b13d0b67a04Forrest Zhao
308a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	if (!strncmp(number, "*31#", 4)) {
309a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		number += 4;
31083003660808c30390f21c569a5ba7dbdd8344a41Claudio Takahasi		clir = "enabled";
311a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	} else if (!strncmp(number, "#31#", 4)) {
312a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		number += 4;
31383003660808c30390f21c569a5ba7dbdd8344a41Claudio Takahasi		clir =  "disabled";
31483003660808c30390f21c569a5ba7dbdd8344a41Claudio Takahasi	} else
31583003660808c30390f21c569a5ba7dbdd8344a41Claudio Takahasi		clir = "default";
316a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
317a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	ret = send_method_call(OFONO_BUS_NAME, modem_obj_path,
318a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			OFONO_VCMANAGER_INTERFACE,
319a34c155f55270b917795d003be24488f53d9b711Forrest Zhao                        "Dial", NULL, NULL,
320a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			DBUS_TYPE_STRING, &number,
321a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			DBUS_TYPE_STRING, &clir,
322a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			DBUS_TYPE_INVALID);
323a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
324a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	if (ret < 0)
325a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		telephony_dial_number_rsp(telephony_device,
326a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			CME_ERROR_AG_FAILURE);
327a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	else
328a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		telephony_dial_number_rsp(telephony_device, CME_ERROR_NONE);
329a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
330a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
331a34c155f55270b917795d003be24488f53d9b711Forrest Zhaovoid telephony_transmit_dtmf_req(void *telephony_device, char tone)
332a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
333a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	char *tone_string;
334a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	int ret;
335a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
3368e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan	DBG("telephony-ofono: transmit dtmf: %c", tone);
337a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
338c5321032b046c39477ab99a05e933b13d0b67a04Forrest Zhao	if (!modem_obj_path) {
339c5321032b046c39477ab99a05e933b13d0b67a04Forrest Zhao		telephony_transmit_dtmf_rsp(telephony_device,
340c5321032b046c39477ab99a05e933b13d0b67a04Forrest Zhao					CME_ERROR_AG_FAILURE);
341c5321032b046c39477ab99a05e933b13d0b67a04Forrest Zhao		return;
342c5321032b046c39477ab99a05e933b13d0b67a04Forrest Zhao	}
343c5321032b046c39477ab99a05e933b13d0b67a04Forrest Zhao
344a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	tone_string = g_strdup_printf("%c", tone);
345a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	ret = send_method_call(OFONO_BUS_NAME, modem_obj_path,
346a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			OFONO_VCMANAGER_INTERFACE,
347a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			"SendTones", NULL, NULL,
348a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			DBUS_TYPE_STRING, &tone_string,
349a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			DBUS_TYPE_INVALID);
350a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	g_free(tone_string);
351a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
352a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	if (ret < 0)
353a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		telephony_transmit_dtmf_rsp(telephony_device,
354a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			CME_ERROR_AG_FAILURE);
355a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	else
356a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		telephony_transmit_dtmf_rsp(telephony_device, CME_ERROR_NONE);
357a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
358a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
359a34c155f55270b917795d003be24488f53d9b711Forrest Zhaovoid telephony_subscriber_number_req(void *telephony_device)
360a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
3618e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan	DBG("telephony-ofono: subscriber number request");
362a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
363a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	if (subscriber_number)
364a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		telephony_subscriber_number_ind(subscriber_number,
365a34c155f55270b917795d003be24488f53d9b711Forrest Zhao						NUMBER_TYPE_TELEPHONY,
366a34c155f55270b917795d003be24488f53d9b711Forrest Zhao						SUBSCRIBER_SERVICE_VOICE);
367a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	telephony_subscriber_number_rsp(telephony_device, CME_ERROR_NONE);
368a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
369a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
370a34c155f55270b917795d003be24488f53d9b711Forrest Zhaovoid telephony_list_current_calls_req(void *telephony_device)
371a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
372a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	GSList *l;
373a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	int i;
374a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
3758e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan	DBG("telephony-ofono: list current calls request");
376a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
377a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	for (l = calls, i = 1; l != NULL; l = l->next, i++) {
378a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		struct voice_call *vc = l->data;
379a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		int direction;
380a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
381a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		direction = vc->originating ?
382a34c155f55270b917795d003be24488f53d9b711Forrest Zhao				CALL_DIR_OUTGOING : CALL_DIR_INCOMING;
383a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
384a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		telephony_list_current_call_ind(i, direction, vc->status,
385a34c155f55270b917795d003be24488f53d9b711Forrest Zhao					CALL_MODE_VOICE, CALL_MULTIPARTY_NO,
386a34c155f55270b917795d003be24488f53d9b711Forrest Zhao					vc->number, NUMBER_TYPE_TELEPHONY);
387a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	}
388a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	telephony_list_current_calls_rsp(telephony_device, CME_ERROR_NONE);
389a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
390a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
391a34c155f55270b917795d003be24488f53d9b711Forrest Zhaovoid telephony_operator_selection_req(void *telephony_device)
392a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
3938e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan	DBG("telephony-ofono: operator selection request");
394a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
395a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	telephony_operator_selection_ind(OPERATOR_MODE_AUTO,
396a34c155f55270b917795d003be24488f53d9b711Forrest Zhao				net.operator_name ? net.operator_name : "");
397a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	telephony_operator_selection_rsp(telephony_device, CME_ERROR_NONE);
398a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
399a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
400a34c155f55270b917795d003be24488f53d9b711Forrest Zhaovoid telephony_call_hold_req(void *telephony_device, const char *cmd)
401a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
4028e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan	DBG("telephony-ofono: got call hold request %s", cmd);
403a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	telephony_call_hold_rsp(telephony_device, CME_ERROR_NONE);
404a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
405a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
406a34c155f55270b917795d003be24488f53d9b711Forrest Zhaovoid telephony_nr_and_ec_req(void *telephony_device, gboolean enable)
407a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
4088e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan	DBG("telephony-ofono: got %s NR and EC request",
409a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			enable ? "enable" : "disable");
410a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
411a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	telephony_nr_and_ec_rsp(telephony_device, CME_ERROR_NONE);
412a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
413a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
414a34c155f55270b917795d003be24488f53d9b711Forrest Zhaovoid telephony_key_press_req(void *telephony_device, const char *keys)
415a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
4168e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan	DBG("telephony-ofono: got key press request for %s", keys);
417a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	telephony_key_press_rsp(telephony_device, CME_ERROR_NONE);
418a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
419a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
4200218ab79ea881c593111b7165cd57337c711d2ecPeter Zotovvoid telephony_voice_dial_req(void *telephony_device, gboolean enable)
4210218ab79ea881c593111b7165cd57337c711d2ecPeter Zotov{
4228e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan	DBG("telephony-ofono: got %s voice dial request",
4230218ab79ea881c593111b7165cd57337c711d2ecPeter Zotov			enable ? "enable" : "disable");
4240218ab79ea881c593111b7165cd57337c711d2ecPeter Zotov
4250218ab79ea881c593111b7165cd57337c711d2ecPeter Zotov	telephony_voice_dial_rsp(telephony_device, CME_ERROR_NOT_SUPPORTED);
4260218ab79ea881c593111b7165cd57337c711d2ecPeter Zotov}
4270218ab79ea881c593111b7165cd57337c711d2ecPeter Zotov
428a34c155f55270b917795d003be24488f53d9b711Forrest Zhaostatic gboolean iter_get_basic_args(DBusMessageIter *iter,
429a34c155f55270b917795d003be24488f53d9b711Forrest Zhao					int first_arg_type, ...)
430a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
431a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	int type;
432a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	va_list ap;
433a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
434a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	va_start(ap, first_arg_type);
435a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
436a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	for (type = first_arg_type; type != DBUS_TYPE_INVALID;
437a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		type = va_arg(ap, int)) {
438a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		void *value = va_arg(ap, void *);
439a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		int real_type = dbus_message_iter_get_arg_type(iter);
440a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
441a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		if (real_type != type) {
442a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			error("iter_get_basic_args: expected %c but got %c",
443a34c155f55270b917795d003be24488f53d9b711Forrest Zhao				(char) type, (char) real_type);
444a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			break;
445a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		}
446a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
447a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		dbus_message_iter_get_basic(iter, value);
448a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		dbus_message_iter_next(iter);
449a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	}
450a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
451a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	va_end(ap);
452a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
453a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	return type == DBUS_TYPE_INVALID ? TRUE : FALSE;
454a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
455a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
4569fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentzstatic void call_free(struct voice_call *vc)
4579fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz{
4589fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	DBG("%s", vc->obj_path);
4599fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
4609fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	g_dbus_remove_watch(connection, vc->watch);
4619fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	g_free(vc->obj_path);
4629fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	g_free(vc->number);
4639fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	g_free(vc);
4649fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz}
4659fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
4669fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentzstatic gboolean handle_vc_property_changed(DBusConnection *conn,
4679fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz					DBusMessage *msg, void *data)
4689fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz{
4699fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	struct voice_call *vc = data;
4709fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	const char *obj_path = dbus_message_get_path(msg);
4719fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	DBusMessageIter iter, sub;
4729fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	const char *property, *state;
4739fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
4749fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	DBG("path %s", obj_path);
4759fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
4769fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	dbus_message_iter_init(msg, &iter);
4779fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
4789fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING) {
4799fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		error("Unexpected signature in vc PropertyChanged signal");
4809fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		return TRUE;
4819fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	}
4829fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
4839fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	dbus_message_iter_get_basic(&iter, &property);
4849fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	DBG("property %s", property);
4859fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
4869fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	dbus_message_iter_next(&iter);
4879fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	dbus_message_iter_recurse(&iter, &sub);
4889fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	if (g_str_equal(property, "State")) {
4899fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		dbus_message_iter_get_basic(&sub, &state);
4909fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		DBG("State %s", state);
4919fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		if (g_str_equal(state, "disconnected")) {
4929fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz			if (vc->status == CALL_STATUS_ACTIVE)
4939fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz				telephony_update_indicator(ofono_indicators,
4949fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz						"call", EV_CALL_INACTIVE);
4959fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz			else
4969fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz				telephony_update_indicator(ofono_indicators,
4979fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz					"callsetup", EV_CALLSETUP_INACTIVE);
4989fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz			if (vc->status == CALL_STATUS_INCOMING)
4999fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz				telephony_calling_stopped_ind();
5009fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz			calls = g_slist_remove(calls, vc);
5019fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz			call_free(vc);
5029fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		} else if (g_str_equal(state, "active")) {
5039fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz			telephony_update_indicator(ofono_indicators,
5049fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz							"call", EV_CALL_ACTIVE);
5059fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz			telephony_update_indicator(ofono_indicators,
5069fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz							"callsetup",
5079fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz							EV_CALLSETUP_INACTIVE);
5089fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz			if (vc->status == CALL_STATUS_INCOMING)
5099fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz				telephony_calling_stopped_ind();
5109fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz			vc->status = CALL_STATUS_ACTIVE;
5119fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		} else if (g_str_equal(state, "alerting")) {
5129fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz			telephony_update_indicator(ofono_indicators,
5139fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz					"callsetup", EV_CALLSETUP_ALERTING);
5149fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz			vc->status = CALL_STATUS_ALERTING;
5159fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz			vc->originating = TRUE;
5169fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		} else if (g_str_equal(state, "incoming")) {
5179fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz			/* state change from waiting to incoming */
5189fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz			telephony_update_indicator(ofono_indicators,
5199fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz					"callsetup", EV_CALLSETUP_INCOMING);
5209fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz			telephony_incoming_call_ind(vc->number,
5219fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz						NUMBER_TYPE_TELEPHONY);
5229fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz			vc->status = CALL_STATUS_INCOMING;
5239fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz			vc->originating = FALSE;
5249fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		}
5259fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	}
5269fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
5279fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	return TRUE;
5289fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz}
5299fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
5309fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentzstatic struct voice_call *call_new(const char *path, DBusMessageIter *properties)
5319fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz{
5329fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	struct voice_call *vc;
5339fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
5349fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	DBG("%s", path);
5359fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
5369fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	vc = g_new0(struct voice_call, 1);
5379fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	vc->obj_path = g_strdup(path);
5389fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	vc->watch = g_dbus_add_signal_watch(connection, NULL, path,
5399fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz					OFONO_VC_INTERFACE, "PropertyChanged",
5409fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz					handle_vc_property_changed, vc, NULL);
5419fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
5429fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	while (dbus_message_iter_get_arg_type(properties)
5439fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz						== DBUS_TYPE_DICT_ENTRY) {
5449fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		DBusMessageIter entry, value;
5459fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		const char *property, *cli, *state;
5469fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
5479fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		dbus_message_iter_recurse(properties, &entry);
5489fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		dbus_message_iter_get_basic(&entry, &property);
5499fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
5509fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		dbus_message_iter_next(&entry);
5519fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		dbus_message_iter_recurse(&entry, &value);
5529fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
5539fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		if (g_str_equal(property, "LineIdentification")) {
5549fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz			dbus_message_iter_get_basic(&value, &cli);
5559fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz			DBG("cli %s", cli);
5569fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz			vc->number = g_strdup(cli);
5579fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		} else if (g_str_equal(property, "State")) {
5589fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz			dbus_message_iter_get_basic(&value, &state);
5599fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz			DBG("state %s", state);
5609fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz			if (g_str_equal(state, "incoming"))
5619fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz				vc->status = CALL_STATUS_INCOMING;
5629fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz			else if (g_str_equal(state, "dialing"))
5639fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz				vc->status = CALL_STATUS_DIALING;
5649fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz			else if (g_str_equal(state, "alerting"))
5659fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz				vc->status = CALL_STATUS_ALERTING;
5669fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz			else if (g_str_equal(state, "waiting"))
5679fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz				vc->status = CALL_STATUS_WAITING;
5689fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		}
5699fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
5709fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		dbus_message_iter_next(properties);
5719fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	}
5729fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
5739fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	switch (vc->status) {
5749fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	case CALL_STATUS_INCOMING:
5759fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		DBG("CALL_STATUS_INCOMING");
5769fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		vc->originating = FALSE;
5779fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		telephony_update_indicator(ofono_indicators, "callsetup",
5789fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz					EV_CALLSETUP_INCOMING);
5799fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		telephony_incoming_call_ind(vc->number, NUMBER_TYPE_TELEPHONY);
5809fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		break;
5819fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	case CALL_STATUS_DIALING:
5829fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		DBG("CALL_STATUS_DIALING");
5839fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		vc->originating = TRUE;
5849fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		g_free(last_dialed_number);
5859fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		last_dialed_number = g_strdup(vc->number);
5869fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		telephony_update_indicator(ofono_indicators, "callsetup",
5879fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz					EV_CALLSETUP_OUTGOING);
5889fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		break;
5899fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	case CALL_STATUS_ALERTING:
5909fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		DBG("CALL_STATUS_ALERTING");
5919fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		vc->originating = TRUE;
5929fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		g_free(last_dialed_number);
5939fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		last_dialed_number = g_strdup(vc->number);
5949fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		telephony_update_indicator(ofono_indicators, "callsetup",
5959fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz					EV_CALLSETUP_ALERTING);
5969fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		break;
5979fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	case CALL_STATUS_WAITING:
5989fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		DBG("CALL_STATUS_WAITING");
5999fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		vc->originating = FALSE;
6009fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		telephony_update_indicator(ofono_indicators, "callsetup",
6019fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz					EV_CALLSETUP_INCOMING);
6029fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		telephony_call_waiting_ind(vc->number, NUMBER_TYPE_TELEPHONY);
6039fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		break;
6049fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	}
6059fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
6069fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	return vc;
6079fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz}
6089fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
609c49dc8c7c815191b5825896f827cac2e2ff395ffLuiz Augusto von Dentzstatic void remove_pending(DBusPendingCall *call)
610c49dc8c7c815191b5825896f827cac2e2ff395ffLuiz Augusto von Dentz{
611c49dc8c7c815191b5825896f827cac2e2ff395ffLuiz Augusto von Dentz	pending = g_slist_remove(pending, call);
612c49dc8c7c815191b5825896f827cac2e2ff395ffLuiz Augusto von Dentz	dbus_pending_call_unref(call);
613c49dc8c7c815191b5825896f827cac2e2ff395ffLuiz Augusto von Dentz}
614c49dc8c7c815191b5825896f827cac2e2ff395ffLuiz Augusto von Dentz
6159fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentzstatic void call_added(const char *path, DBusMessageIter *properties)
6169fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz{
6179fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	struct voice_call *vc;
6189fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
6199fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	DBG("%s", path);
6209fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
6219fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	vc = find_vc(path);
6229fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	if (vc)
6239fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		return;
6249fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
6259fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	vc = call_new(path, properties);
6269fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	calls = g_slist_prepend(calls, vc);
6279fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz}
6289fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
6299fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentzstatic void get_calls_reply(DBusPendingCall *call, void *user_data)
6309fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz{
6319fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	DBusError err;
6329fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	DBusMessage *reply;
6339fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	DBusMessageIter iter, entry;
6349fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
6359fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	DBG("");
6369fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	reply = dbus_pending_call_steal_reply(call);
6379fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
6389fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	dbus_error_init(&err);
6399fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	if (dbus_set_error_from_message(&err, reply)) {
6409fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		error("ofono replied with an error: %s, %s",
6419fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz				err.name, err.message);
6429fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		dbus_error_free(&err);
6439fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		goto done;
6449fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	}
6459fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
6469fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	dbus_message_iter_init(reply, &iter);
6479fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
6489fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY) {
6499fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		error("Unexpected signature");
6509fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		goto done;
6519fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	}
6529fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
6539fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	dbus_message_iter_recurse(&iter, &entry);
6549fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
6559fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	while (dbus_message_iter_get_arg_type(&entry)
6569fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz						== DBUS_TYPE_STRUCT) {
6579fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		const char *path;
6589fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		DBusMessageIter value, properties;
6599fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
6609fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		dbus_message_iter_recurse(&entry, &value);
6619fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		dbus_message_iter_get_basic(&value, &path);
6629fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
6639fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		dbus_message_iter_next(&value);
6649fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		dbus_message_iter_recurse(&value, &properties);
6659fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
6669fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		call_added(path, &properties);
6679fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
6689fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		dbus_message_iter_next(&entry);
6699fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	}
6709fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
6719fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentzdone:
6729fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	dbus_message_unref(reply);
673c49dc8c7c815191b5825896f827cac2e2ff395ffLuiz Augusto von Dentz	remove_pending(call);
6749fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz}
6759fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
676e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentzstatic void handle_network_property(const char *property, DBusMessageIter *variant)
677a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
67883003660808c30390f21c569a5ba7dbdd8344a41Claudio Takahasi	const char *status, *operator;
679a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	unsigned int signals_bar;
680a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
681a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	if (g_str_equal(property, "Status")) {
682e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz		dbus_message_iter_get_basic(variant, &status);
6838e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan		DBG("Status is %s", status);
684a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		if (g_str_equal(status, "registered")) {
685a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			net.status = NETWORK_REG_STATUS_HOME;
686a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			telephony_update_indicator(ofono_indicators,
687a34c155f55270b917795d003be24488f53d9b711Forrest Zhao						"roam", EV_ROAM_INACTIVE);
688a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			telephony_update_indicator(ofono_indicators,
689a34c155f55270b917795d003be24488f53d9b711Forrest Zhao						"service", EV_SERVICE_PRESENT);
690a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		} else if (g_str_equal(status, "roaming")) {
691a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			net.status = NETWORK_REG_STATUS_ROAM;
692a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			telephony_update_indicator(ofono_indicators,
693a34c155f55270b917795d003be24488f53d9b711Forrest Zhao						"roam", EV_ROAM_ACTIVE);
694a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			telephony_update_indicator(ofono_indicators,
695a34c155f55270b917795d003be24488f53d9b711Forrest Zhao						"service", EV_SERVICE_PRESENT);
696a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		} else {
697a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			net.status = NETWORK_REG_STATUS_NOSERV;
698a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			telephony_update_indicator(ofono_indicators,
699a34c155f55270b917795d003be24488f53d9b711Forrest Zhao						"roam", EV_ROAM_INACTIVE);
700a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			telephony_update_indicator(ofono_indicators,
701a34c155f55270b917795d003be24488f53d9b711Forrest Zhao						"service", EV_SERVICE_NONE);
702a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		}
703e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	} else if (g_str_equal(property, "Name")) {
704e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz		dbus_message_iter_get_basic(variant, &operator);
7058e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan		DBG("Operator is %s", operator);
706a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		g_free(net.operator_name);
707a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		net.operator_name = g_strdup(operator);
708a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	} else if (g_str_equal(property, "SignalStrength")) {
709e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz		dbus_message_iter_get_basic(variant, &signals_bar);
7108e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan		DBG("SignalStrength is %d", signals_bar);
711a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		net.signals_bar = signals_bar;
712a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		telephony_update_indicator(ofono_indicators, "signal",
713a34c155f55270b917795d003be24488f53d9b711Forrest Zhao						(signals_bar + 20) / 21);
714a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	}
715a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
716a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
717e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentzstatic int parse_network_properties(DBusMessageIter *properties)
718a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
719a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	uint32_t features = AG_FEATURE_EC_ANDOR_NR |
720a34c155f55270b917795d003be24488f53d9b711Forrest Zhao				AG_FEATURE_REJECT_A_CALL |
721a34c155f55270b917795d003be24488f53d9b711Forrest Zhao				AG_FEATURE_ENHANCED_CALL_STATUS |
722a34c155f55270b917795d003be24488f53d9b711Forrest Zhao				AG_FEATURE_EXTENDED_ERROR_RESULT_CODES;
723a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
724e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	while (dbus_message_iter_get_arg_type(properties)
725e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz						== DBUS_TYPE_DICT_ENTRY) {
726e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz		const char *key;
727e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz		DBusMessageIter value, entry;
728e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz
729e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz		dbus_message_iter_recurse(properties, &entry);
730e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz		dbus_message_iter_get_basic(&entry, &key);
731e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz
732e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz		dbus_message_iter_next(&entry);
733e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz		dbus_message_iter_recurse(&entry, &value);
734e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz
735e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz		handle_network_property(key, &value);
736e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz
737e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz		dbus_message_iter_next(properties);
738e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	}
739e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz
740e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	telephony_ready_ind(features, ofono_indicators, BTRH_NOT_SUPPORTED,
741e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz								chld_str);
742e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz
743e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	return 0;
744e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz}
745e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz
746e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentzstatic void get_properties_reply(DBusPendingCall *call, void *user_data)
747e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz{
748e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	DBusError err;
749e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	DBusMessage *reply;
750e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	DBusMessageIter iter, properties;
751e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	int ret = 0;
752e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz
753e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	DBG("");
754a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	reply = dbus_pending_call_steal_reply(call);
755a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
756a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	dbus_error_init(&err);
757a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	if (dbus_set_error_from_message(&err, reply)) {
758a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		error("ofono replied with an error: %s, %s",
759a34c155f55270b917795d003be24488f53d9b711Forrest Zhao				err.name, err.message);
760a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		dbus_error_free(&err);
761a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		goto done;
762a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	}
763a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
764a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	dbus_message_iter_init(reply, &iter);
765a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
766a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY) {
767e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz		error("Unexpected signature");
768a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		goto done;
769a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	}
770a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
771e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	dbus_message_iter_recurse(&iter, &properties);
772a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
773e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	ret = parse_network_properties(&properties);
7749fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	if (ret < 0) {
775e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz		error("Unable to parse %s.GetProperty reply",
776e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz						OFONO_NETWORKREG_INTERFACE);
7779fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		goto done;
7789fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	}
7799fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
7809fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	ret = send_method_call(OFONO_BUS_NAME, modem_obj_path,
7819fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz				OFONO_VCMANAGER_INTERFACE, "GetCalls",
7829fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz				get_calls_reply, NULL, DBUS_TYPE_INVALID);
7839fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	if (ret < 0)
7849fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		error("Unable to send %s.GetCalls",
7859fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz						OFONO_VCMANAGER_INTERFACE);
786a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
787a34c155f55270b917795d003be24488f53d9b711Forrest Zhaodone:
788a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	dbus_message_unref(reply);
789c49dc8c7c815191b5825896f827cac2e2ff395ffLuiz Augusto von Dentz	remove_pending(call);
790a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
791a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
792806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentzstatic void network_found(const char *path)
793a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
794e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	int ret;
795c5321032b046c39477ab99a05e933b13d0b67a04Forrest Zhao
796e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	DBG("%s", path);
797e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz
798e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	modem_obj_path = g_strdup(path);
799e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz
800e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	ret = send_method_call(OFONO_BUS_NAME, path,
801e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz				OFONO_NETWORKREG_INTERFACE, "GetProperties",
802e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz				get_properties_reply, NULL, DBUS_TYPE_INVALID);
803e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	if (ret < 0)
804e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz		error("Unable to send %s.GetProperties",
805e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz						OFONO_NETWORKREG_INTERFACE);
806a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
807a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
808806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentzstatic void modem_removed(const char *path)
809806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz{
810806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	if (g_strcmp0(modem_obj_path, path) != 0)
811806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		return;
812806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
813806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	DBG("%s", path);
814806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
815806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	g_slist_foreach(calls, (GFunc) call_free, NULL);
816806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	g_slist_free(calls);
817806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	calls = NULL;
818806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
819806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	g_free(net.operator_name);
820806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	net.operator_name = NULL;
821806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
822806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	g_free(modem_obj_path);
823806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	modem_obj_path = NULL;
824806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz}
825806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
826806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentzstatic void parse_modem_interfaces(const char *path, DBusMessageIter *ifaces)
827806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz{
828806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	DBG("%s", path);
829806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
830806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	while (dbus_message_iter_get_arg_type(ifaces) == DBUS_TYPE_STRING) {
831806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		const char *iface;
832806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
833806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		dbus_message_iter_get_basic(ifaces, &iface);
834806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
835806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		if (g_str_equal(iface, OFONO_NETWORKREG_INTERFACE)) {
836806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz			network_found(path);
837806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz			return;
838806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		}
839806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
840806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		dbus_message_iter_next(ifaces);
841806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	}
842806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
843806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	modem_removed(path);
844806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz}
845806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
846806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentzstatic void modem_added(const char *path, DBusMessageIter *properties)
847806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz{
848806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	if (modem_obj_path != NULL) {
849806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		DBG("Ignoring, modem already exist");
850806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		return;
851806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	}
852806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
853806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	DBG("%s", path);
854806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
855806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	while (dbus_message_iter_get_arg_type(properties)
856806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz						== DBUS_TYPE_DICT_ENTRY) {
857806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		const char *key;
858806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		DBusMessageIter interfaces, value, entry;
859806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
860806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		dbus_message_iter_recurse(properties, &entry);
861806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		dbus_message_iter_get_basic(&entry, &key);
862806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
863806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		dbus_message_iter_next(&entry);
864806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		dbus_message_iter_recurse(&entry, &value);
865806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
866806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		if (strcasecmp(key, "Interfaces") != 0)
867806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz			goto next;
868806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
869806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		if (dbus_message_iter_get_arg_type(&value)
870806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz							!= DBUS_TYPE_ARRAY) {
871806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz			error("Invalid Signature");
872806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz			return;
873806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		}
874806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
875806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		dbus_message_iter_recurse(&value, &interfaces);
876806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
877806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		parse_modem_interfaces(path, &interfaces);
878806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
879806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		if (modem_obj_path != NULL)
880806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz			return;
881806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
882806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	next:
883806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		dbus_message_iter_next(properties);
884806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	}
885806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz}
886806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
887e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentzstatic void get_modems_reply(DBusPendingCall *call, void *user_data)
888a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
889a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	DBusError err;
890a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	DBusMessage *reply;
891e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	DBusMessageIter iter, entry;
892a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
8938e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan	DBG("list_modem_reply is called\n");
894a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	reply = dbus_pending_call_steal_reply(call);
895a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
896a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	dbus_error_init(&err);
897a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	if (dbus_set_error_from_message(&err, reply)) {
898a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		error("ofono replied with an error: %s, %s",
899a34c155f55270b917795d003be24488f53d9b711Forrest Zhao				err.name, err.message);
900a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		dbus_error_free(&err);
901a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		goto done;
902a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	}
903a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
904806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	/* Skip modem selection if a modem already exist */
905806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	if (modem_obj_path != NULL)
906806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		goto done;
907806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
908a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	dbus_message_iter_init(reply, &iter);
909a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
910a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY) {
911e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz		error("Unexpected signature");
912a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		goto done;
913a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	}
914a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
915e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	dbus_message_iter_recurse(&iter, &entry);
916a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
917806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	while (dbus_message_iter_get_arg_type(&entry)
918806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz						== DBUS_TYPE_STRUCT) {
919806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		const char *path;
920806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		DBusMessageIter item, properties;
921806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
922806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		dbus_message_iter_recurse(&entry, &item);
923806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		dbus_message_iter_get_basic(&item, &path);
924806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
925806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		dbus_message_iter_next(&item);
926806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		dbus_message_iter_recurse(&item, &properties);
927a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
928806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		modem_added(path, &properties);
929806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		if (modem_obj_path != NULL)
930806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz			break;
931a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
932806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		dbus_message_iter_next(&entry);
933806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	}
934a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
935a34c155f55270b917795d003be24488f53d9b711Forrest Zhaodone:
936a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	dbus_message_unref(reply);
937c49dc8c7c815191b5825896f827cac2e2ff395ffLuiz Augusto von Dentz	remove_pending(call);
938a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
939a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
940e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentzstatic gboolean handle_network_property_changed(DBusConnection *conn,
9418309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz						DBusMessage *msg, void *data)
942a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
943e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	DBusMessageIter iter, variant;
944a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	const char *property;
945a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
946a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	dbus_message_iter_init(msg, &iter);
947a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
948a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING) {
949a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		error("Unexpected signature in networkregistration"
950a34c155f55270b917795d003be24488f53d9b711Forrest Zhao					" PropertyChanged signal");
9518309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz		return TRUE;
952a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	}
953a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	dbus_message_iter_get_basic(&iter, &property);
9548e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan	DBG("in handle_registration_property_changed(),"
955a34c155f55270b917795d003be24488f53d9b711Forrest Zhao					" the property is %s", property);
956a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
957a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	dbus_message_iter_next(&iter);
958e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	dbus_message_iter_recurse(&iter, &variant);
959a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
960e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	handle_network_property(property, &variant);
9618309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz
9628309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	return TRUE;
963a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
964a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
965806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentzstatic void handle_modem_property(const char *path, const char *property,
966806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz						DBusMessageIter *variant)
967806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz{
968806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	DBG("%s", property);
969806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
970806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	if (g_str_equal(property, "Interfaces")) {
971806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		DBusMessageIter interfaces;
972806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
973806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		if (dbus_message_iter_get_arg_type(variant)
974806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz							!= DBUS_TYPE_ARRAY) {
975806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz			error("Invalid signature");
976806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz			return;
977806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		}
978806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
979806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		dbus_message_iter_recurse(variant, &interfaces);
980806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		parse_modem_interfaces(path, &interfaces);
981806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	}
982806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz}
983806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
984806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentzstatic gboolean handle_modem_property_changed(DBusConnection *conn,
985806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz						DBusMessage *msg, void *data)
986806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz{
987806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	DBusMessageIter iter, variant;
988806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	const char *property, *path;
989806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
990806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	path = dbus_message_get_path(msg);
991806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
992806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	/* Ignore if modem already exist and paths doesn't match */
993806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	if (modem_obj_path != NULL &&
994806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz				g_str_equal(path, modem_obj_path) == FALSE)
995806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		return TRUE;
996806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
997806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	dbus_message_iter_init(msg, &iter);
998806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
999806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING) {
1000806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		error("Unexpected signature in %s.%s PropertyChanged signal",
1001806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz					dbus_message_get_interface(msg),
1002806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz					dbus_message_get_member(msg));
1003806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		return TRUE;
1004806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	}
1005806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
1006806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	dbus_message_iter_get_basic(&iter, &property);
1007806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
1008806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	dbus_message_iter_next(&iter);
1009806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	dbus_message_iter_recurse(&iter, &variant);
1010806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
1011806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	handle_modem_property(path, property, &variant);
1012806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
1013806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	return TRUE;
1014806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz}
1015806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
10169fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentzstatic gboolean handle_vcmanager_call_added(DBusConnection *conn,
10179fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz						DBusMessage *msg, void *data)
1018a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
10199fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	DBusMessageIter iter, properties;
10209fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	const char *path = dbus_message_get_path(msg);
1021a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
10229fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	/* Ignore call if modem path doesn't math */
10239fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	if (g_strcmp0(modem_obj_path, path) != 0)
10249fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		return TRUE;
1025a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
10269fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	dbus_message_iter_init(msg, &iter);
1027a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
10289fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	if (dbus_message_iter_get_arg_type(&iter)
10299fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz						!= DBUS_TYPE_OBJECT_PATH) {
10309fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		error("Unexpected signature in %s.%s signal",
10319fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz					dbus_message_get_interface(msg),
10329fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz					dbus_message_get_member(msg));
10339fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		return TRUE;
1034a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	}
1035a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
10369fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	dbus_message_iter_get_basic(&iter, &path);
10379fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	dbus_message_iter_next(&iter);
10389fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	dbus_message_iter_recurse(&iter, &properties);
1039a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
10409fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	call_added(path, &properties);
1041a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
10429fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	return TRUE;
1043a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
1044a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
10459fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentzstatic void call_removed(const char *path)
1046a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
10479fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	struct voice_call *vc;
1048a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
10499fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	DBG("%s", path);
1050a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
10519fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	vc = find_vc(path);
10529fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	if (vc == NULL)
10539fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		return;
10548309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz
10559fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	calls = g_slist_remove(calls, vc);
10569fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	call_free(vc);
10578309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz}
10588309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz
10599fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentzstatic gboolean handle_vcmanager_call_removed(DBusConnection *conn,
10608309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz						DBusMessage *msg, void *data)
10618309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz{
10629fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	const char *path = dbus_message_get_path(msg);
10638309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz
10649fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	/* Ignore call if modem path doesn't math */
10659fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	if (g_strcmp0(modem_obj_path, path) != 0)
10668309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz		return TRUE;
10678309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz
10689fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	if (!dbus_message_get_args(msg, NULL,
10699fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz				DBUS_TYPE_OBJECT_PATH, &path,
10709fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz				DBUS_TYPE_INVALID)) {
10719fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		error("Unexpected signature in %s.%s signal",
10729fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz					dbus_message_get_interface(msg),
10739fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz					dbus_message_get_member(msg));
10748309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz		return TRUE;
10758309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	}
10768309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz
10779fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	call_removed(path);
10788309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz
10798309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	return TRUE;
1080a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
1081a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1082e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentzstatic gboolean handle_manager_modem_added(DBusConnection *conn,
1083e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz						DBusMessage *msg, void *data)
1084e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz{
1085e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	DBusMessageIter iter, properties;
1086e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	const char *path;
1087e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz
1088e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	if (modem_obj_path != NULL)
1089e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz		return TRUE;
1090e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz
1091e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	dbus_message_iter_init(msg, &iter);
1092e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz
1093e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	if (dbus_message_iter_get_arg_type(&iter)
1094e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz						!= DBUS_TYPE_OBJECT_PATH) {
1095e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz		error("Unexpected signature in %s.%s signal",
1096e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz					dbus_message_get_interface(msg),
1097e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz					dbus_message_get_member(msg));
1098e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz		return TRUE;
1099e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	}
1100e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz
1101e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	dbus_message_iter_get_basic(&iter, &path);
1102806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	dbus_message_iter_next(&iter);
1103e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	dbus_message_iter_recurse(&iter, &properties);
1104e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz
1105806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	modem_added(path, &properties);
1106e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz
1107e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	return TRUE;
1108e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz}
1109e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz
1110e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentzstatic gboolean handle_manager_modem_removed(DBusConnection *conn,
1111e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz						DBusMessage *msg, void *data)
1112e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz{
1113e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	const char *path;
1114e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz
1115e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	if (!dbus_message_get_args(msg, NULL,
1116e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz				DBUS_TYPE_OBJECT_PATH, &path,
1117e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz				DBUS_TYPE_INVALID)) {
1118e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz		error("Unexpected signature in %s.%s signal",
1119e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz					dbus_message_get_interface(msg),
1120e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz					dbus_message_get_member(msg));
1121e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz		return TRUE;
1122e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	}
1123e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz
1124e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	modem_removed(path);
1125e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz
1126e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	return TRUE;
1127e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz}
1128e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz
1129a34c155f55270b917795d003be24488f53d9b711Forrest Zhaostatic void hal_battery_level_reply(DBusPendingCall *call, void *user_data)
1130a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
1131a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	DBusMessage *reply;
1132a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	DBusError err;
1133a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	dbus_int32_t level;
1134a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	int *value = user_data;
1135a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1136a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	reply = dbus_pending_call_steal_reply(call);
1137a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1138a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	dbus_error_init(&err);
1139a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	if (dbus_set_error_from_message(&err, reply)) {
1140a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		error("hald replied with an error: %s, %s",
1141a34c155f55270b917795d003be24488f53d9b711Forrest Zhao				err.name, err.message);
1142a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		dbus_error_free(&err);
1143a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		goto done;
1144a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	}
1145a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1146463763c080cd72ecd727a218dd68f7c0ba95bc9eLuiz Augusto von Dentz	dbus_error_init(&err);
1147463763c080cd72ecd727a218dd68f7c0ba95bc9eLuiz Augusto von Dentz	if (dbus_message_get_args(reply, &err,
1148a34c155f55270b917795d003be24488f53d9b711Forrest Zhao				DBUS_TYPE_INT32, &level,
1149463763c080cd72ecd727a218dd68f7c0ba95bc9eLuiz Augusto von Dentz				DBUS_TYPE_INVALID) == FALSE) {
1150463763c080cd72ecd727a218dd68f7c0ba95bc9eLuiz Augusto von Dentz		error("Unable to parse GetPropertyInteger reply: %s, %s",
1151463763c080cd72ecd727a218dd68f7c0ba95bc9eLuiz Augusto von Dentz							err.name, err.message);
1152463763c080cd72ecd727a218dd68f7c0ba95bc9eLuiz Augusto von Dentz		dbus_error_free(&err);
1153463763c080cd72ecd727a218dd68f7c0ba95bc9eLuiz Augusto von Dentz		goto done;
1154463763c080cd72ecd727a218dd68f7c0ba95bc9eLuiz Augusto von Dentz	}
1155a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1156a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	*value = (int) level;
1157a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1158a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	if (value == &battchg_last)
11598e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan		DBG("telephony-ofono: battery.charge_level.last_full"
1160a34c155f55270b917795d003be24488f53d9b711Forrest Zhao					" is %d", *value);
1161a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	else if (value == &battchg_design)
11628e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan		DBG("telephony-ofono: battery.charge_level.design"
1163a34c155f55270b917795d003be24488f53d9b711Forrest Zhao					" is %d", *value);
1164a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	else
11658e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan		DBG("telephony-ofono: battery.charge_level.current"
1166a34c155f55270b917795d003be24488f53d9b711Forrest Zhao					" is %d", *value);
1167a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1168a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	if ((battchg_design > 0 || battchg_last > 0) && battchg_cur >= 0) {
11699ff86aa7f2c11cb3198dfcde93f8db3c534ecdb6Johan Hedberg		int new, max;
1170a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1171a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		if (battchg_last > 0)
1172a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			max = battchg_last;
1173a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		else
1174a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			max = battchg_design;
1175a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1176a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		new = battchg_cur * 5 / max;
1177a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
11789ff86aa7f2c11cb3198dfcde93f8db3c534ecdb6Johan Hedberg		telephony_update_indicator(ofono_indicators, "battchg", new);
1179a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	}
1180a34c155f55270b917795d003be24488f53d9b711Forrest Zhaodone:
1181a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	dbus_message_unref(reply);
1182c49dc8c7c815191b5825896f827cac2e2ff395ffLuiz Augusto von Dentz	remove_pending(call);
1183a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
1184a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1185a34c155f55270b917795d003be24488f53d9b711Forrest Zhaostatic void hal_get_integer(const char *path, const char *key, void *user_data)
1186a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
1187a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	send_method_call("org.freedesktop.Hal", path,
1188a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			"org.freedesktop.Hal.Device",
1189a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			"GetPropertyInteger",
1190a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			hal_battery_level_reply, user_data,
1191a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			DBUS_TYPE_STRING, &key,
1192a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			DBUS_TYPE_INVALID);
1193a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
1194a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
11958309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentzstatic gboolean handle_hal_property_modified(DBusConnection *conn,
11968309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz						DBusMessage *msg, void *data)
1197a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
1198a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	const char *path;
1199a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	DBusMessageIter iter, array;
1200a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	dbus_int32_t num_changes;
1201a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1202a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	path = dbus_message_get_path(msg);
1203a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1204a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	dbus_message_iter_init(msg, &iter);
1205a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1206a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_INT32) {
1207a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		error("Unexpected signature in hal PropertyModified signal");
12088309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz		return TRUE;
1209a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	}
1210a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1211a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	dbus_message_iter_get_basic(&iter, &num_changes);
1212a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	dbus_message_iter_next(&iter);
1213a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1214a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY) {
1215a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		error("Unexpected signature in hal PropertyModified signal");
12168309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz		return TRUE;
1217a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	}
1218a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1219a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	dbus_message_iter_recurse(&iter, &array);
1220a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1221a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	while (dbus_message_iter_get_arg_type(&array) != DBUS_TYPE_INVALID) {
1222a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		DBusMessageIter prop;
1223a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		const char *name;
1224a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		dbus_bool_t added, removed;
1225a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1226a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		dbus_message_iter_recurse(&array, &prop);
1227a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1228a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		if (!iter_get_basic_args(&prop,
1229a34c155f55270b917795d003be24488f53d9b711Forrest Zhao					DBUS_TYPE_STRING, &name,
1230a34c155f55270b917795d003be24488f53d9b711Forrest Zhao					DBUS_TYPE_BOOLEAN, &added,
1231a34c155f55270b917795d003be24488f53d9b711Forrest Zhao					DBUS_TYPE_BOOLEAN, &removed,
1232a34c155f55270b917795d003be24488f53d9b711Forrest Zhao					DBUS_TYPE_INVALID)) {
1233a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			error("Invalid hal PropertyModified parameters");
1234a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			break;
1235a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		}
1236a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1237a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		if (g_str_equal(name, "battery.charge_level.last_full"))
1238a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			hal_get_integer(path, name, &battchg_last);
1239a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		else if (g_str_equal(name, "battery.charge_level.current"))
1240a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			hal_get_integer(path, name, &battchg_cur);
1241a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		else if (g_str_equal(name, "battery.charge_level.design"))
1242a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			hal_get_integer(path, name, &battchg_design);
1243a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1244a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		dbus_message_iter_next(&array);
1245a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	}
12468309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz
12478309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	return TRUE;
1248a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
1249a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
12509946e8636c3361dc769c5f8a463b74158018d3ddLuiz Augusto von Dentzstatic void add_watch(const char *sender, const char *path,
12519946e8636c3361dc769c5f8a463b74158018d3ddLuiz Augusto von Dentz				const char *interface, const char *member,
12529946e8636c3361dc769c5f8a463b74158018d3ddLuiz Augusto von Dentz				GDBusSignalFunction function)
12539946e8636c3361dc769c5f8a463b74158018d3ddLuiz Augusto von Dentz{
12549946e8636c3361dc769c5f8a463b74158018d3ddLuiz Augusto von Dentz	guint watch;
12559946e8636c3361dc769c5f8a463b74158018d3ddLuiz Augusto von Dentz
12569946e8636c3361dc769c5f8a463b74158018d3ddLuiz Augusto von Dentz	watch = g_dbus_add_signal_watch(connection, sender, path, interface,
12579946e8636c3361dc769c5f8a463b74158018d3ddLuiz Augusto von Dentz					member, function, NULL, NULL);
12589946e8636c3361dc769c5f8a463b74158018d3ddLuiz Augusto von Dentz
12599946e8636c3361dc769c5f8a463b74158018d3ddLuiz Augusto von Dentz	watches = g_slist_prepend(watches, GUINT_TO_POINTER(watch));
12609946e8636c3361dc769c5f8a463b74158018d3ddLuiz Augusto von Dentz}
12619946e8636c3361dc769c5f8a463b74158018d3ddLuiz Augusto von Dentz
12628309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentzstatic void hal_find_device_reply(DBusPendingCall *call, void *user_data)
1263a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
12648309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	DBusMessage *reply;
12658309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	DBusError err;
12668309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	DBusMessageIter iter, sub;
12678309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	int type;
12688309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	const char *path;
12698309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz
12708e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan	DBG("begin of hal_find_device_reply()");
12718309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	reply = dbus_pending_call_steal_reply(call);
12728309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz
12738309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	dbus_error_init(&err);
12748309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz
12758309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	if (dbus_set_error_from_message(&err, reply)) {
12768309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz		error("hald replied with an error: %s, %s",
12778309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz				err.name, err.message);
12788309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz		dbus_error_free(&err);
12798309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz		goto done;
12808309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	}
12818309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz
12828309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	dbus_message_iter_init(reply, &iter);
12838309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz
12848309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY) {
12858309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz		error("Unexpected signature in hal_find_device_reply()");
12868309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz		goto done;
12878309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	}
12888309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz
12898309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	dbus_message_iter_recurse(&iter, &sub);
12908309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz
12918309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	type = dbus_message_iter_get_arg_type(&sub);
12928309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz
12938309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	if (type != DBUS_TYPE_OBJECT_PATH && type != DBUS_TYPE_STRING) {
12948309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz		error("No hal device with battery capability found");
12958309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz		goto done;
12968309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	}
12978309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz
12988309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	dbus_message_iter_get_basic(&sub, &path);
12998309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz
13008e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan	DBG("telephony-ofono: found battery device at %s", path);
13018309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz
13029946e8636c3361dc769c5f8a463b74158018d3ddLuiz Augusto von Dentz	add_watch(NULL, path, "org.freedesktop.Hal.Device",
13039946e8636c3361dc769c5f8a463b74158018d3ddLuiz Augusto von Dentz			"PropertyModified", handle_hal_property_modified);
13048309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz
13058309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	hal_get_integer(path, "battery.charge_level.last_full", &battchg_last);
13068309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	hal_get_integer(path, "battery.charge_level.current", &battchg_cur);
13078309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	hal_get_integer(path, "battery.charge_level.design", &battchg_design);
13088309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentzdone:
13098309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	dbus_message_unref(reply);
1310c49dc8c7c815191b5825896f827cac2e2ff395ffLuiz Augusto von Dentz	remove_pending(call);
1311a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
1312a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1313c7b0c8e099b8fdfa1ad2a905d6f482beb3aaddaaLuiz Augusto von Dentzstatic void handle_service_connect(DBusConnection *conn, void *user_data)
1314c7b0c8e099b8fdfa1ad2a905d6f482beb3aaddaaLuiz Augusto von Dentz{
1315c7b0c8e099b8fdfa1ad2a905d6f482beb3aaddaaLuiz Augusto von Dentz	DBG("telephony-ofono: %s found", OFONO_BUS_NAME);
1316c7b0c8e099b8fdfa1ad2a905d6f482beb3aaddaaLuiz Augusto von Dentz
1317c7b0c8e099b8fdfa1ad2a905d6f482beb3aaddaaLuiz Augusto von Dentz	send_method_call(OFONO_BUS_NAME, OFONO_PATH,
1318c7b0c8e099b8fdfa1ad2a905d6f482beb3aaddaaLuiz Augusto von Dentz				OFONO_MANAGER_INTERFACE, "GetModems",
1319c7b0c8e099b8fdfa1ad2a905d6f482beb3aaddaaLuiz Augusto von Dentz				get_modems_reply, NULL, DBUS_TYPE_INVALID);
1320c7b0c8e099b8fdfa1ad2a905d6f482beb3aaddaaLuiz Augusto von Dentz}
1321c7b0c8e099b8fdfa1ad2a905d6f482beb3aaddaaLuiz Augusto von Dentz
1322c7b0c8e099b8fdfa1ad2a905d6f482beb3aaddaaLuiz Augusto von Dentzstatic void handle_service_disconnect(DBusConnection *conn, void *user_data)
1323c7b0c8e099b8fdfa1ad2a905d6f482beb3aaddaaLuiz Augusto von Dentz{
1324c7b0c8e099b8fdfa1ad2a905d6f482beb3aaddaaLuiz Augusto von Dentz	DBG("telephony-ofono: %s exitted", OFONO_BUS_NAME);
1325c7b0c8e099b8fdfa1ad2a905d6f482beb3aaddaaLuiz Augusto von Dentz
1326c7b0c8e099b8fdfa1ad2a905d6f482beb3aaddaaLuiz Augusto von Dentz	if (modem_obj_path)
1327c7b0c8e099b8fdfa1ad2a905d6f482beb3aaddaaLuiz Augusto von Dentz		modem_removed(modem_obj_path);
1328c7b0c8e099b8fdfa1ad2a905d6f482beb3aaddaaLuiz Augusto von Dentz}
1329c7b0c8e099b8fdfa1ad2a905d6f482beb3aaddaaLuiz Augusto von Dentz
1330a34c155f55270b917795d003be24488f53d9b711Forrest Zhaoint telephony_init(void)
1331a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
1332a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	const char *battery_cap = "battery";
1333a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	int ret;
1334c7b0c8e099b8fdfa1ad2a905d6f482beb3aaddaaLuiz Augusto von Dentz	guint watch;
1335a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1336a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	connection = dbus_bus_get(DBUS_BUS_SYSTEM, NULL);
1337a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1338806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	add_watch(OFONO_BUS_NAME, NULL, OFONO_MODEM_INTERFACE,
1339806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz			"PropertyChanged", handle_modem_property_changed);
13409946e8636c3361dc769c5f8a463b74158018d3ddLuiz Augusto von Dentz	add_watch(OFONO_BUS_NAME, NULL, OFONO_NETWORKREG_INTERFACE,
13419946e8636c3361dc769c5f8a463b74158018d3ddLuiz Augusto von Dentz			"PropertyChanged", handle_network_property_changed);
13429946e8636c3361dc769c5f8a463b74158018d3ddLuiz Augusto von Dentz	add_watch(OFONO_BUS_NAME, NULL, OFONO_MANAGER_INTERFACE,
13439946e8636c3361dc769c5f8a463b74158018d3ddLuiz Augusto von Dentz			"ModemAdded", handle_manager_modem_added);
13449946e8636c3361dc769c5f8a463b74158018d3ddLuiz Augusto von Dentz	add_watch(OFONO_BUS_NAME, NULL, OFONO_MANAGER_INTERFACE,
13459946e8636c3361dc769c5f8a463b74158018d3ddLuiz Augusto von Dentz			"ModemRemoved", handle_manager_modem_removed);
13469946e8636c3361dc769c5f8a463b74158018d3ddLuiz Augusto von Dentz	add_watch(OFONO_BUS_NAME, NULL, OFONO_VCMANAGER_INTERFACE,
13479946e8636c3361dc769c5f8a463b74158018d3ddLuiz Augusto von Dentz			"CallAdded", handle_vcmanager_call_added);
13489946e8636c3361dc769c5f8a463b74158018d3ddLuiz Augusto von Dentz	add_watch(OFONO_BUS_NAME, NULL, OFONO_VCMANAGER_INTERFACE,
13499946e8636c3361dc769c5f8a463b74158018d3ddLuiz Augusto von Dentz			"CallRemoved", handle_vcmanager_call_removed);
1350a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1351c7b0c8e099b8fdfa1ad2a905d6f482beb3aaddaaLuiz Augusto von Dentz	watch = g_dbus_add_service_watch(connection, OFONO_BUS_NAME,
1352c7b0c8e099b8fdfa1ad2a905d6f482beb3aaddaaLuiz Augusto von Dentz						handle_service_connect,
1353c7b0c8e099b8fdfa1ad2a905d6f482beb3aaddaaLuiz Augusto von Dentz						handle_service_disconnect,
1354c7b0c8e099b8fdfa1ad2a905d6f482beb3aaddaaLuiz Augusto von Dentz						NULL, NULL);
1355c7b0c8e099b8fdfa1ad2a905d6f482beb3aaddaaLuiz Augusto von Dentz	if (watch == 0)
1356c7b0c8e099b8fdfa1ad2a905d6f482beb3aaddaaLuiz Augusto von Dentz		return -ENOMEM;
1357c7b0c8e099b8fdfa1ad2a905d6f482beb3aaddaaLuiz Augusto von Dentz
1358c7b0c8e099b8fdfa1ad2a905d6f482beb3aaddaaLuiz Augusto von Dentz	watches = g_slist_prepend(watches, GUINT_TO_POINTER(watch));
1359a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1360a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	ret = send_method_call("org.freedesktop.Hal",
1361a34c155f55270b917795d003be24488f53d9b711Forrest Zhao				"/org/freedesktop/Hal/Manager",
1362a34c155f55270b917795d003be24488f53d9b711Forrest Zhao				"org.freedesktop.Hal.Manager",
1363a34c155f55270b917795d003be24488f53d9b711Forrest Zhao				"FindDeviceByCapability",
1364a34c155f55270b917795d003be24488f53d9b711Forrest Zhao				hal_find_device_reply, NULL,
1365a34c155f55270b917795d003be24488f53d9b711Forrest Zhao				DBUS_TYPE_STRING, &battery_cap,
1366a34c155f55270b917795d003be24488f53d9b711Forrest Zhao				DBUS_TYPE_INVALID);
1367a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	if (ret < 0)
1368a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		return ret;
1369a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
13708e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan	DBG("telephony_init() successfully");
1371a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1372a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	return ret;
1373a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
1374a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
13759946e8636c3361dc769c5f8a463b74158018d3ddLuiz Augusto von Dentzstatic void remove_watch(gpointer data)
13769946e8636c3361dc769c5f8a463b74158018d3ddLuiz Augusto von Dentz{
13779946e8636c3361dc769c5f8a463b74158018d3ddLuiz Augusto von Dentz	g_dbus_remove_watch(connection, GPOINTER_TO_UINT(data));
13789946e8636c3361dc769c5f8a463b74158018d3ddLuiz Augusto von Dentz}
13799946e8636c3361dc769c5f8a463b74158018d3ddLuiz Augusto von Dentz
1380a34c155f55270b917795d003be24488f53d9b711Forrest Zhaovoid telephony_exit(void)
1381a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
1382e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	DBG("");
1383a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1384a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	g_free(last_dialed_number);
1385e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	last_dialed_number = NULL;
1386a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1387e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	if (modem_obj_path)
1388e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz		modem_removed(modem_obj_path);
1389a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
13909946e8636c3361dc769c5f8a463b74158018d3ddLuiz Augusto von Dentz	g_slist_foreach(watches, (GFunc) remove_watch, NULL);
13919946e8636c3361dc769c5f8a463b74158018d3ddLuiz Augusto von Dentz	g_slist_free(watches);
13929946e8636c3361dc769c5f8a463b74158018d3ddLuiz Augusto von Dentz	watches = NULL;
1393a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1394c49dc8c7c815191b5825896f827cac2e2ff395ffLuiz Augusto von Dentz	g_slist_foreach(pending, (GFunc) dbus_pending_call_cancel, NULL);
1395c49dc8c7c815191b5825896f827cac2e2ff395ffLuiz Augusto von Dentz	g_slist_foreach(pending, (GFunc) dbus_pending_call_unref, NULL);
1396c49dc8c7c815191b5825896f827cac2e2ff395ffLuiz Augusto von Dentz	g_slist_free(pending);
1397c49dc8c7c815191b5825896f827cac2e2ff395ffLuiz Augusto von Dentz	pending = NULL;
1398c49dc8c7c815191b5825896f827cac2e2ff395ffLuiz Augusto von Dentz
1399a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	dbus_connection_unref(connection);
1400a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	connection = NULL;
1401401be3748717fae613041592778a3a7160fb763cJohan Hedberg
1402401be3748717fae613041592778a3a7160fb763cJohan Hedberg	telephony_deinit();
1403a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
1404