telephony-ofono.c revision 8e58667ef0a4cda88ac64137728da28d8fdf3f0f
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;
59a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
60a34c155f55270b917795d003be24488f53d9b711Forrest Zhao#define OFONO_BUS_NAME "org.ofono"
61a34c155f55270b917795d003be24488f53d9b711Forrest Zhao#define OFONO_PATH "/"
62d89690657f2634ceb9d4b13257ccc7d60bc0cb5dForrest Zhao#define OFONO_MANAGER_INTERFACE "org.ofono.Manager"
63a34c155f55270b917795d003be24488f53d9b711Forrest Zhao#define OFONO_NETWORKREG_INTERFACE "org.ofono.NetworkRegistration"
64a34c155f55270b917795d003be24488f53d9b711Forrest Zhao#define OFONO_VCMANAGER_INTERFACE "org.ofono.VoiceCallManager"
65a34c155f55270b917795d003be24488f53d9b711Forrest Zhao#define OFONO_VC_INTERFACE "org.ofono.VoiceCall"
66a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
678309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentzstatic guint registration_watch = 0;
688309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentzstatic guint voice_watch = 0;
698309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentzstatic guint device_watch = 0;
708309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz
71a34c155f55270b917795d003be24488f53d9b711Forrest Zhao/* HAL battery namespace key values */
72a34c155f55270b917795d003be24488f53d9b711Forrest Zhaostatic int battchg_cur = -1;    /* "battery.charge_level.current" */
73a34c155f55270b917795d003be24488f53d9b711Forrest Zhaostatic int battchg_last = -1;   /* "battery.charge_level.last_full" */
74a34c155f55270b917795d003be24488f53d9b711Forrest Zhaostatic int battchg_design = -1; /* "battery.charge_level.design" */
75a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
76a34c155f55270b917795d003be24488f53d9b711Forrest Zhaostatic struct {
77a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	uint8_t status;
78a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	uint32_t signals_bar;
79a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	char *operator_name;
80a34c155f55270b917795d003be24488f53d9b711Forrest Zhao} net = {
81a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	.status = NETWORK_REG_STATUS_NOSERV,
82a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	.signals_bar = 0,
83a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	.operator_name = NULL,
84a34c155f55270b917795d003be24488f53d9b711Forrest Zhao};
85a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
86a34c155f55270b917795d003be24488f53d9b711Forrest Zhaostatic const char *chld_str = "0,1,1x,2,2x,3,4";
87a34c155f55270b917795d003be24488f53d9b711Forrest Zhaostatic char *subscriber_number = NULL;
88a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
89a34c155f55270b917795d003be24488f53d9b711Forrest Zhaostatic gboolean events_enabled = FALSE;
90a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
91a34c155f55270b917795d003be24488f53d9b711Forrest Zhao/* Response and hold state
92a34c155f55270b917795d003be24488f53d9b711Forrest Zhao * -1 = none
93a34c155f55270b917795d003be24488f53d9b711Forrest Zhao *  0 = incoming call is put on hold in the AG
94a34c155f55270b917795d003be24488f53d9b711Forrest Zhao *  1 = held incoming call is accepted in the AG
95a34c155f55270b917795d003be24488f53d9b711Forrest Zhao *  2 = held incoming call is rejected in the AG
96a34c155f55270b917795d003be24488f53d9b711Forrest Zhao */
97a34c155f55270b917795d003be24488f53d9b711Forrest Zhaostatic int response_and_hold = -1;
98a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
99a34c155f55270b917795d003be24488f53d9b711Forrest Zhaostatic struct indicator ofono_indicators[] =
100a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
101884debf8418651b63b1a5a8918092ba4d230783eJohan Hedberg	{ "battchg",	"0-5",	5,	TRUE },
102884debf8418651b63b1a5a8918092ba4d230783eJohan Hedberg	{ "signal",	"0-5",	5,	TRUE },
103884debf8418651b63b1a5a8918092ba4d230783eJohan Hedberg	{ "service",	"0,1",	1,	TRUE },
104884debf8418651b63b1a5a8918092ba4d230783eJohan Hedberg	{ "call",	"0,1",	0,	TRUE },
105884debf8418651b63b1a5a8918092ba4d230783eJohan Hedberg	{ "callsetup",	"0-3",	0,	TRUE },
106884debf8418651b63b1a5a8918092ba4d230783eJohan Hedberg	{ "callheld",	"0-2",	0,	FALSE },
107884debf8418651b63b1a5a8918092ba4d230783eJohan Hedberg	{ "roam",	"0,1",	0,	TRUE },
108a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	{ NULL }
109a34c155f55270b917795d003be24488f53d9b711Forrest Zhao};
110a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
111a34c155f55270b917795d003be24488f53d9b711Forrest Zhaostatic struct voice_call *find_vc(const char *path)
112a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
113a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	GSList *l;
114a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
115a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	for (l = calls; l != NULL; l = l->next) {
116a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		struct voice_call *vc = l->data;
117a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
118a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		if (g_str_equal(vc->obj_path, path))
119a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			return vc;
120a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	}
121a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
122a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	return NULL;
123a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
124a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
125a34c155f55270b917795d003be24488f53d9b711Forrest Zhaostatic struct voice_call *find_vc_with_status(int status)
126a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
127a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	GSList *l;
128a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
129a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	for (l = calls; l != NULL; l = l->next) {
130a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		struct voice_call *vc = l->data;
131a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
132a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		if (vc->status == status)
133a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			return vc;
134a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	}
135a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
136a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	return NULL;
137a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
138a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
139a34c155f55270b917795d003be24488f53d9b711Forrest Zhaovoid telephony_device_connected(void *telephony_device)
140a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
1418e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan	DBG("telephony-ofono: device %p connected", telephony_device);
142a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
143a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
144a34c155f55270b917795d003be24488f53d9b711Forrest Zhaovoid telephony_device_disconnected(void *telephony_device)
145a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
1468e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan	DBG("telephony-ofono: device %p disconnected", telephony_device);
147a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	events_enabled = FALSE;
148a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
149a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
150a34c155f55270b917795d003be24488f53d9b711Forrest Zhaovoid telephony_event_reporting_req(void *telephony_device, int ind)
151a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
152a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	events_enabled = ind == 1 ? TRUE : FALSE;
153a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
154a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	telephony_event_reporting_rsp(telephony_device, CME_ERROR_NONE);
155a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
156a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
157a34c155f55270b917795d003be24488f53d9b711Forrest Zhaovoid telephony_response_and_hold_req(void *telephony_device, int rh)
158a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
159a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	response_and_hold = rh;
160a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
161a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	telephony_response_and_hold_ind(response_and_hold);
162a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
163a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	telephony_response_and_hold_rsp(telephony_device, CME_ERROR_NONE);
164a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
165a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
166a34c155f55270b917795d003be24488f53d9b711Forrest Zhaovoid telephony_last_dialed_number_req(void *telephony_device)
167a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
1688e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan	DBG("telephony-ofono: last dialed number request");
169a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
170a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	if (last_dialed_number)
171a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		telephony_dial_number_req(telephony_device, last_dialed_number);
172a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	else
173a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		telephony_last_dialed_number_rsp(telephony_device,
174a34c155f55270b917795d003be24488f53d9b711Forrest Zhao				CME_ERROR_NOT_ALLOWED);
175a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
176a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
177a34c155f55270b917795d003be24488f53d9b711Forrest Zhaostatic int send_method_call(const char *dest, const char *path,
178a34c155f55270b917795d003be24488f53d9b711Forrest Zhao                                const char *interface, const char *method,
179a34c155f55270b917795d003be24488f53d9b711Forrest Zhao                                DBusPendingCallNotifyFunction cb,
180a34c155f55270b917795d003be24488f53d9b711Forrest Zhao                                void *user_data, int type, ...)
181a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
182a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	DBusMessage *msg;
183a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	DBusPendingCall *call;
184a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	va_list args;
185a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
186a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	msg = dbus_message_new_method_call(dest, path, interface, method);
187a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	if (!msg) {
188a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		error("Unable to allocate new D-Bus %s message", method);
189a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		return -ENOMEM;
190a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	}
191a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
192a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	va_start(args, type);
193a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
194a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	if (!dbus_message_append_args_valist(msg, type, args)) {
195a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		dbus_message_unref(msg);
196a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		va_end(args);
197a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		return -EIO;
198a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	}
199a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
200a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	va_end(args);
201a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
202a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	if (!cb) {
203a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		g_dbus_send_message(connection, msg);
204a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		return 0;
205a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	}
206a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
207a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	if (!dbus_connection_send_with_reply(connection, msg, &call, -1)) {
208a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		error("Sending %s failed", method);
209a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		dbus_message_unref(msg);
210a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		return -EIO;
211a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	}
212a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
213a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	dbus_pending_call_set_notify(call, cb, user_data, NULL);
214a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	dbus_pending_call_unref(call);
215a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	dbus_message_unref(msg);
216a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
217a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	return 0;
218a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
219a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
220a34c155f55270b917795d003be24488f53d9b711Forrest Zhaovoid telephony_terminate_call_req(void *telephony_device)
221a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
222a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	struct voice_call *vc;
223a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	int ret;
224a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
225e925c22367a6b5c501c6635691d3e3399f492e78Marcel Holtmann	if ((vc = find_vc_with_status(CALL_STATUS_ACTIVE))) {
226e925c22367a6b5c501c6635691d3e3399f492e78Marcel Holtmann	} else if ((vc = find_vc_with_status(CALL_STATUS_DIALING))) {
227e925c22367a6b5c501c6635691d3e3399f492e78Marcel Holtmann	} else if ((vc = find_vc_with_status(CALL_STATUS_ALERTING))) {
228e925c22367a6b5c501c6635691d3e3399f492e78Marcel Holtmann	} else if ((vc = find_vc_with_status(CALL_STATUS_INCOMING))) {
229e925c22367a6b5c501c6635691d3e3399f492e78Marcel Holtmann	}
230a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
231a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	if (!vc) {
232a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		error("in telephony_terminate_call_req, no active call");
233a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		telephony_terminate_call_rsp(telephony_device,
234a34c155f55270b917795d003be24488f53d9b711Forrest Zhao					CME_ERROR_NOT_ALLOWED);
235a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		return;
236a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	}
237a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
238a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	ret = send_method_call(OFONO_BUS_NAME, vc->obj_path,
239a34c155f55270b917795d003be24488f53d9b711Forrest Zhao					OFONO_VC_INTERFACE,
240a34c155f55270b917795d003be24488f53d9b711Forrest Zhao					"Hangup", NULL,
241a34c155f55270b917795d003be24488f53d9b711Forrest Zhao					NULL, DBUS_TYPE_INVALID);
242a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
243a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	if (ret < 0) {
244a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		telephony_answer_call_rsp(telephony_device,
245a34c155f55270b917795d003be24488f53d9b711Forrest Zhao					CME_ERROR_AG_FAILURE);
246a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		return;
247a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	}
248a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
249a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	telephony_answer_call_rsp(telephony_device, CME_ERROR_NONE);
250a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
251a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
252a34c155f55270b917795d003be24488f53d9b711Forrest Zhaovoid telephony_answer_call_req(void *telephony_device)
253a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
254a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	struct voice_call *vc = find_vc_with_status(CALL_STATUS_INCOMING);
255a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	int ret;
256a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
257a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	if (!vc) {
258a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		telephony_answer_call_rsp(telephony_device,
259a34c155f55270b917795d003be24488f53d9b711Forrest Zhao					CME_ERROR_NOT_ALLOWED);
260a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		return;
261a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	}
262a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
263a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	ret = send_method_call(OFONO_BUS_NAME, vc->obj_path,
264a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			OFONO_VC_INTERFACE,
265a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			"Answer", NULL,
266a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			NULL, DBUS_TYPE_INVALID);
267a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
268a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	if (ret < 0) {
269a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		telephony_answer_call_rsp(telephony_device,
270a34c155f55270b917795d003be24488f53d9b711Forrest Zhao					CME_ERROR_AG_FAILURE);
271a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		return;
272a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	}
273a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
274a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	telephony_answer_call_rsp(telephony_device, CME_ERROR_NONE);
275a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
276a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
277a34c155f55270b917795d003be24488f53d9b711Forrest Zhaovoid telephony_dial_number_req(void *telephony_device, const char *number)
278a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
27983003660808c30390f21c569a5ba7dbdd8344a41Claudio Takahasi	const char *clir;
280a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	int ret;
281a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
2828e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan	DBG("telephony-ofono: dial request to %s", number);
283a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
284c5321032b046c39477ab99a05e933b13d0b67a04Forrest Zhao	if (!modem_obj_path) {
285c5321032b046c39477ab99a05e933b13d0b67a04Forrest Zhao		telephony_dial_number_rsp(telephony_device,
286c5321032b046c39477ab99a05e933b13d0b67a04Forrest Zhao					CME_ERROR_AG_FAILURE);
287c5321032b046c39477ab99a05e933b13d0b67a04Forrest Zhao		return;
288c5321032b046c39477ab99a05e933b13d0b67a04Forrest Zhao	}
289c5321032b046c39477ab99a05e933b13d0b67a04Forrest Zhao
290a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	if (!strncmp(number, "*31#", 4)) {
291a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		number += 4;
29283003660808c30390f21c569a5ba7dbdd8344a41Claudio Takahasi		clir = "enabled";
293a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	} else if (!strncmp(number, "#31#", 4)) {
294a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		number += 4;
29583003660808c30390f21c569a5ba7dbdd8344a41Claudio Takahasi		clir =  "disabled";
29683003660808c30390f21c569a5ba7dbdd8344a41Claudio Takahasi	} else
29783003660808c30390f21c569a5ba7dbdd8344a41Claudio Takahasi		clir = "default";
298a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
299a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	ret = send_method_call(OFONO_BUS_NAME, modem_obj_path,
300a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			OFONO_VCMANAGER_INTERFACE,
301a34c155f55270b917795d003be24488f53d9b711Forrest Zhao                        "Dial", NULL, NULL,
302a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			DBUS_TYPE_STRING, &number,
303a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			DBUS_TYPE_STRING, &clir,
304a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			DBUS_TYPE_INVALID);
305a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
306a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	if (ret < 0)
307a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		telephony_dial_number_rsp(telephony_device,
308a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			CME_ERROR_AG_FAILURE);
309a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	else
310a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		telephony_dial_number_rsp(telephony_device, CME_ERROR_NONE);
311a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
312a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
313a34c155f55270b917795d003be24488f53d9b711Forrest Zhaovoid telephony_transmit_dtmf_req(void *telephony_device, char tone)
314a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
315a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	char *tone_string;
316a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	int ret;
317a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
3188e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan	DBG("telephony-ofono: transmit dtmf: %c", tone);
319a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
320c5321032b046c39477ab99a05e933b13d0b67a04Forrest Zhao	if (!modem_obj_path) {
321c5321032b046c39477ab99a05e933b13d0b67a04Forrest Zhao		telephony_transmit_dtmf_rsp(telephony_device,
322c5321032b046c39477ab99a05e933b13d0b67a04Forrest Zhao					CME_ERROR_AG_FAILURE);
323c5321032b046c39477ab99a05e933b13d0b67a04Forrest Zhao		return;
324c5321032b046c39477ab99a05e933b13d0b67a04Forrest Zhao	}
325c5321032b046c39477ab99a05e933b13d0b67a04Forrest Zhao
326a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	tone_string = g_strdup_printf("%c", tone);
327a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	ret = send_method_call(OFONO_BUS_NAME, modem_obj_path,
328a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			OFONO_VCMANAGER_INTERFACE,
329a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			"SendTones", NULL, NULL,
330a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			DBUS_TYPE_STRING, &tone_string,
331a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			DBUS_TYPE_INVALID);
332a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	g_free(tone_string);
333a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
334a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	if (ret < 0)
335a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		telephony_transmit_dtmf_rsp(telephony_device,
336a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			CME_ERROR_AG_FAILURE);
337a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	else
338a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		telephony_transmit_dtmf_rsp(telephony_device, CME_ERROR_NONE);
339a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
340a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
341a34c155f55270b917795d003be24488f53d9b711Forrest Zhaovoid telephony_subscriber_number_req(void *telephony_device)
342a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
3438e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan	DBG("telephony-ofono: subscriber number request");
344a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
345a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	if (subscriber_number)
346a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		telephony_subscriber_number_ind(subscriber_number,
347a34c155f55270b917795d003be24488f53d9b711Forrest Zhao						NUMBER_TYPE_TELEPHONY,
348a34c155f55270b917795d003be24488f53d9b711Forrest Zhao						SUBSCRIBER_SERVICE_VOICE);
349a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	telephony_subscriber_number_rsp(telephony_device, CME_ERROR_NONE);
350a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
351a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
352a34c155f55270b917795d003be24488f53d9b711Forrest Zhaovoid telephony_list_current_calls_req(void *telephony_device)
353a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
354a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	GSList *l;
355a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	int i;
356a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
3578e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan	DBG("telephony-ofono: list current calls request");
358a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
359a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	for (l = calls, i = 1; l != NULL; l = l->next, i++) {
360a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		struct voice_call *vc = l->data;
361a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		int direction;
362a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
363a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		direction = vc->originating ?
364a34c155f55270b917795d003be24488f53d9b711Forrest Zhao				CALL_DIR_OUTGOING : CALL_DIR_INCOMING;
365a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
366a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		telephony_list_current_call_ind(i, direction, vc->status,
367a34c155f55270b917795d003be24488f53d9b711Forrest Zhao					CALL_MODE_VOICE, CALL_MULTIPARTY_NO,
368a34c155f55270b917795d003be24488f53d9b711Forrest Zhao					vc->number, NUMBER_TYPE_TELEPHONY);
369a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	}
370a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	telephony_list_current_calls_rsp(telephony_device, CME_ERROR_NONE);
371a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
372a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
373a34c155f55270b917795d003be24488f53d9b711Forrest Zhaovoid telephony_operator_selection_req(void *telephony_device)
374a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
3758e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan	DBG("telephony-ofono: operator selection request");
376a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
377a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	telephony_operator_selection_ind(OPERATOR_MODE_AUTO,
378a34c155f55270b917795d003be24488f53d9b711Forrest Zhao				net.operator_name ? net.operator_name : "");
379a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	telephony_operator_selection_rsp(telephony_device, CME_ERROR_NONE);
380a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
381a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
382a34c155f55270b917795d003be24488f53d9b711Forrest Zhaovoid telephony_call_hold_req(void *telephony_device, const char *cmd)
383a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
3848e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan	DBG("telephony-ofono: got call hold request %s", cmd);
385a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	telephony_call_hold_rsp(telephony_device, CME_ERROR_NONE);
386a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
387a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
388a34c155f55270b917795d003be24488f53d9b711Forrest Zhaovoid telephony_nr_and_ec_req(void *telephony_device, gboolean enable)
389a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
3908e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan	DBG("telephony-ofono: got %s NR and EC request",
391a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			enable ? "enable" : "disable");
392a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
393a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	telephony_nr_and_ec_rsp(telephony_device, CME_ERROR_NONE);
394a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
395a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
396a34c155f55270b917795d003be24488f53d9b711Forrest Zhaovoid telephony_key_press_req(void *telephony_device, const char *keys)
397a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
3988e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan	DBG("telephony-ofono: got key press request for %s", keys);
399a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	telephony_key_press_rsp(telephony_device, CME_ERROR_NONE);
400a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
401a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
4020218ab79ea881c593111b7165cd57337c711d2ecPeter Zotovvoid telephony_voice_dial_req(void *telephony_device, gboolean enable)
4030218ab79ea881c593111b7165cd57337c711d2ecPeter Zotov{
4048e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan	DBG("telephony-ofono: got %s voice dial request",
4050218ab79ea881c593111b7165cd57337c711d2ecPeter Zotov			enable ? "enable" : "disable");
4060218ab79ea881c593111b7165cd57337c711d2ecPeter Zotov
4070218ab79ea881c593111b7165cd57337c711d2ecPeter Zotov	telephony_voice_dial_rsp(telephony_device, CME_ERROR_NOT_SUPPORTED);
4080218ab79ea881c593111b7165cd57337c711d2ecPeter Zotov}
4090218ab79ea881c593111b7165cd57337c711d2ecPeter Zotov
410a34c155f55270b917795d003be24488f53d9b711Forrest Zhaostatic gboolean iter_get_basic_args(DBusMessageIter *iter,
411a34c155f55270b917795d003be24488f53d9b711Forrest Zhao					int first_arg_type, ...)
412a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
413a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	int type;
414a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	va_list ap;
415a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
416a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	va_start(ap, first_arg_type);
417a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
418a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	for (type = first_arg_type; type != DBUS_TYPE_INVALID;
419a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		type = va_arg(ap, int)) {
420a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		void *value = va_arg(ap, void *);
421a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		int real_type = dbus_message_iter_get_arg_type(iter);
422a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
423a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		if (real_type != type) {
424a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			error("iter_get_basic_args: expected %c but got %c",
425a34c155f55270b917795d003be24488f53d9b711Forrest Zhao				(char) type, (char) real_type);
426a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			break;
427a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		}
428a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
429a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		dbus_message_iter_get_basic(iter, value);
430a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		dbus_message_iter_next(iter);
431a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	}
432a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
433a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	va_end(ap);
434a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
435a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	return type == DBUS_TYPE_INVALID ? TRUE : FALSE;
436a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
437a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
438e925c22367a6b5c501c6635691d3e3399f492e78Marcel Holtmannstatic void handle_registration_property(const char *property, DBusMessageIter sub)
439a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
44083003660808c30390f21c569a5ba7dbdd8344a41Claudio Takahasi	const char *status, *operator;
441a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	unsigned int signals_bar;
442a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
443a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	if (g_str_equal(property, "Status")) {
444a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		dbus_message_iter_get_basic(&sub, &status);
4458e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan		DBG("Status is %s", status);
446a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		if (g_str_equal(status, "registered")) {
447a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			net.status = NETWORK_REG_STATUS_HOME;
448a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			telephony_update_indicator(ofono_indicators,
449a34c155f55270b917795d003be24488f53d9b711Forrest Zhao						"roam", EV_ROAM_INACTIVE);
450a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			telephony_update_indicator(ofono_indicators,
451a34c155f55270b917795d003be24488f53d9b711Forrest Zhao						"service", EV_SERVICE_PRESENT);
452a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		} else if (g_str_equal(status, "roaming")) {
453a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			net.status = NETWORK_REG_STATUS_ROAM;
454a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			telephony_update_indicator(ofono_indicators,
455a34c155f55270b917795d003be24488f53d9b711Forrest Zhao						"roam", EV_ROAM_ACTIVE);
456a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			telephony_update_indicator(ofono_indicators,
457a34c155f55270b917795d003be24488f53d9b711Forrest Zhao						"service", EV_SERVICE_PRESENT);
458a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		} else {
459a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			net.status = NETWORK_REG_STATUS_NOSERV;
460a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			telephony_update_indicator(ofono_indicators,
461a34c155f55270b917795d003be24488f53d9b711Forrest Zhao						"roam", EV_ROAM_INACTIVE);
462a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			telephony_update_indicator(ofono_indicators,
463a34c155f55270b917795d003be24488f53d9b711Forrest Zhao						"service", EV_SERVICE_NONE);
464a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		}
465a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	} else if (g_str_equal(property, "Operator")) {
466a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		dbus_message_iter_get_basic(&sub, &operator);
4678e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan		DBG("Operator is %s", operator);
468a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		g_free(net.operator_name);
469a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		net.operator_name = g_strdup(operator);
470a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	} else if (g_str_equal(property, "SignalStrength")) {
471a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		dbus_message_iter_get_basic(&sub, &signals_bar);
4728e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan		DBG("SignalStrength is %d", signals_bar);
473a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		net.signals_bar = signals_bar;
474a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		telephony_update_indicator(ofono_indicators, "signal",
475a34c155f55270b917795d003be24488f53d9b711Forrest Zhao						(signals_bar + 20) / 21);
476a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	}
477a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
478a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
479a34c155f55270b917795d003be24488f53d9b711Forrest Zhaostatic void get_registration_reply(DBusPendingCall *call, void *user_data)
480a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
481a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	DBusError err;
482a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	DBusMessage *reply;
483a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	DBusMessageIter iter, iter_entry;
484a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	uint32_t features = AG_FEATURE_EC_ANDOR_NR |
485a34c155f55270b917795d003be24488f53d9b711Forrest Zhao				AG_FEATURE_REJECT_A_CALL |
486a34c155f55270b917795d003be24488f53d9b711Forrest Zhao				AG_FEATURE_ENHANCED_CALL_STATUS |
487a34c155f55270b917795d003be24488f53d9b711Forrest Zhao				AG_FEATURE_EXTENDED_ERROR_RESULT_CODES;
488a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
489a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	reply = dbus_pending_call_steal_reply(call);
490a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
491a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	dbus_error_init(&err);
492a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	if (dbus_set_error_from_message(&err, reply)) {
493a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		error("ofono replied with an error: %s, %s",
494a34c155f55270b917795d003be24488f53d9b711Forrest Zhao				err.name, err.message);
495a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		dbus_error_free(&err);
496a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		goto done;
497a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	}
498a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
499a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	dbus_message_iter_init(reply, &iter);
500a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
5014ebb87203d438ea2672cc406813807e227b760e2Johan Hedberg	/* ARRAY -> ENTRY -> VARIANT */
502a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY) {
503a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		error("Unexpected signature in GetProperties return");
504a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		goto done;
505a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	}
506a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
507a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	dbus_message_iter_recurse(&iter, &iter_entry);
508a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
509a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	if (dbus_message_iter_get_arg_type(&iter_entry)
510a34c155f55270b917795d003be24488f53d9b711Forrest Zhao					!= DBUS_TYPE_DICT_ENTRY) {
511a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		error("Unexpected signature in GetProperties return");
512a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		goto done;
513a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	}
514a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
515a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	while (dbus_message_iter_get_arg_type(&iter_entry)
516a34c155f55270b917795d003be24488f53d9b711Forrest Zhao					!= DBUS_TYPE_INVALID) {
517a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		DBusMessageIter iter_property, sub;
518a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		char *property;
519a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
520a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		dbus_message_iter_recurse(&iter_entry, &iter_property);
521a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		if (dbus_message_iter_get_arg_type(&iter_property)
522a34c155f55270b917795d003be24488f53d9b711Forrest Zhao					!= DBUS_TYPE_STRING) {
523a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			error("Unexpected signature in GetProperties return");
524a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			goto done;
525a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		}
526a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
527a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		dbus_message_iter_get_basic(&iter_property, &property);
528a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
529a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		dbus_message_iter_next(&iter_property);
530a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		dbus_message_iter_recurse(&iter_property, &sub);
531a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
532a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		handle_registration_property(property, sub);
533a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
534a34c155f55270b917795d003be24488f53d9b711Forrest Zhao                dbus_message_iter_next(&iter_entry);
535a34c155f55270b917795d003be24488f53d9b711Forrest Zhao        }
536a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
537a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	telephony_ready_ind(features, ofono_indicators,
538a34c155f55270b917795d003be24488f53d9b711Forrest Zhao				response_and_hold, chld_str);
539a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
540a34c155f55270b917795d003be24488f53d9b711Forrest Zhaodone:
541a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	dbus_message_unref(reply);
542a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
543a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
544a34c155f55270b917795d003be24488f53d9b711Forrest Zhaostatic int get_registration_and_signal_status()
545a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
546c5321032b046c39477ab99a05e933b13d0b67a04Forrest Zhao	if (!modem_obj_path)
547c5321032b046c39477ab99a05e933b13d0b67a04Forrest Zhao		return -ENOENT;
548c5321032b046c39477ab99a05e933b13d0b67a04Forrest Zhao
549a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	return send_method_call(OFONO_BUS_NAME, modem_obj_path,
550a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			OFONO_NETWORKREG_INTERFACE,
551a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			"GetProperties", get_registration_reply,
552a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			NULL, DBUS_TYPE_INVALID);
553a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
554a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
555a34c155f55270b917795d003be24488f53d9b711Forrest Zhaostatic void list_modem_reply(DBusPendingCall *call, void *user_data)
556a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
557a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	DBusError err;
558a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	DBusMessage *reply;
559a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	DBusMessageIter iter, iter_entry, iter_property, iter_arrary, sub;
560a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	char *property, *modem_obj_path_local;
561a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	int ret;
562a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
5638e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan	DBG("list_modem_reply is called\n");
564a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	reply = dbus_pending_call_steal_reply(call);
565a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
566a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	dbus_error_init(&err);
567a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	if (dbus_set_error_from_message(&err, reply)) {
568a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		error("ofono replied with an error: %s, %s",
569a34c155f55270b917795d003be24488f53d9b711Forrest Zhao				err.name, err.message);
570a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		dbus_error_free(&err);
571a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		goto done;
572a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	}
573a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
574a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	dbus_message_iter_init(reply, &iter);
575a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
576a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY) {
577a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		error("Unexpected signature in ListModems return");
578a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		goto done;
579a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	}
580a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
581a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	dbus_message_iter_recurse(&iter, &iter_entry);
582a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
583a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	if (dbus_message_iter_get_arg_type(&iter_entry)
584a34c155f55270b917795d003be24488f53d9b711Forrest Zhao					!= DBUS_TYPE_DICT_ENTRY) {
585a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		error("Unexpected signature in ListModems return 2, %c",
586a34c155f55270b917795d003be24488f53d9b711Forrest Zhao				dbus_message_iter_get_arg_type(&iter_entry));
587a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		goto done;
588a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	}
589a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
590a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	dbus_message_iter_recurse(&iter_entry, &iter_property);
591a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
592a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	dbus_message_iter_get_basic(&iter_property, &property);
593a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
594a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	dbus_message_iter_next(&iter_property);
595a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	dbus_message_iter_recurse(&iter_property, &iter_arrary);
596a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	dbus_message_iter_recurse(&iter_arrary, &sub);
597a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	while (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) {
598a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
599a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		dbus_message_iter_get_basic(&sub, &modem_obj_path_local);
600a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		modem_obj_path = g_strdup(modem_obj_path_local);
6018e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan		DBG("modem_obj_path is %p, %s\n", modem_obj_path,
602a34c155f55270b917795d003be24488f53d9b711Forrest Zhao						modem_obj_path);
603a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		dbus_message_iter_next(&sub);
604a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	}
605a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
606a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	ret = get_registration_and_signal_status();
607a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	if (ret < 0)
608a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		error("get_registration_and_signal_status() failed(%d)", ret);
609a34c155f55270b917795d003be24488f53d9b711Forrest Zhaodone:
610a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	dbus_message_unref(reply);
611a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
612a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
6138309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentzstatic gboolean handle_registration_property_changed(DBusConnection *conn,
6148309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz						DBusMessage *msg, void *data)
615a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
616a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	DBusMessageIter iter, sub;
617a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	const char *property;
618a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
619a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	dbus_message_iter_init(msg, &iter);
620a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
621a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING) {
622a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		error("Unexpected signature in networkregistration"
623a34c155f55270b917795d003be24488f53d9b711Forrest Zhao					" PropertyChanged signal");
6248309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz		return TRUE;
625a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	}
626a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	dbus_message_iter_get_basic(&iter, &property);
6278e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan	DBG("in handle_registration_property_changed(),"
628a34c155f55270b917795d003be24488f53d9b711Forrest Zhao					" the property is %s", property);
629a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
630a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	dbus_message_iter_next(&iter);
631a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	dbus_message_iter_recurse(&iter, &sub);
632a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
633a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	handle_registration_property(property, sub);
6348309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz
6358309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	return TRUE;
636a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
637a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
638a34c155f55270b917795d003be24488f53d9b711Forrest Zhaostatic void vc_getproperties_reply(DBusPendingCall *call, void *user_data)
639a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
640a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	DBusMessage *reply;
641a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	DBusError err;
642a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	DBusMessageIter iter, iter_entry;
643a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	const char *path = user_data;
644a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	struct voice_call *vc;
645a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
6468e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan	DBG("in vc_getproperties_reply");
647a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
648a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	reply = dbus_pending_call_steal_reply(call);
649a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	dbus_error_init(&err);
650a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	if (dbus_set_error_from_message(&err, reply)) {
651a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		error("ofono replied with an error: %s, %s",
652a34c155f55270b917795d003be24488f53d9b711Forrest Zhao				err.name, err.message);
653a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		dbus_error_free(&err);
654a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		goto done;
65583003660808c30390f21c569a5ba7dbdd8344a41Claudio Takahasi	}
656a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
657a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	vc = find_vc(path);
658a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	if (!vc) {
659a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		error("in vc_getproperties_reply, vc is NULL");
660a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		goto done;
661a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	}
662a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
663a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	dbus_message_iter_init(reply, &iter);
664a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
665a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY) {
666a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		error("Unexpected signature in vc_getproperties_reply()");
667a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		goto done;
66883003660808c30390f21c569a5ba7dbdd8344a41Claudio Takahasi	}
669a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
670a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	dbus_message_iter_recurse(&iter, &iter_entry);
671a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
672a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	if (dbus_message_iter_get_arg_type(&iter_entry)
67383003660808c30390f21c569a5ba7dbdd8344a41Claudio Takahasi			!= DBUS_TYPE_DICT_ENTRY) {
674a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		error("Unexpected signature in vc_getproperties_reply()");
675a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		goto done;
67683003660808c30390f21c569a5ba7dbdd8344a41Claudio Takahasi	}
677a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
678a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	while (dbus_message_iter_get_arg_type(&iter_entry)
67983003660808c30390f21c569a5ba7dbdd8344a41Claudio Takahasi			!= DBUS_TYPE_INVALID) {
680a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		DBusMessageIter iter_property, sub;
681a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		char *property, *cli, *state;
682a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
683a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		dbus_message_iter_recurse(&iter_entry, &iter_property);
684a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		if (dbus_message_iter_get_arg_type(&iter_property)
68583003660808c30390f21c569a5ba7dbdd8344a41Claudio Takahasi				!= DBUS_TYPE_STRING) {
686a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			error("Unexpected signature in"
687a34c155f55270b917795d003be24488f53d9b711Forrest Zhao					" vc_getproperties_reply()");
688a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			goto done;
68983003660808c30390f21c569a5ba7dbdd8344a41Claudio Takahasi		}
690a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
691a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		dbus_message_iter_get_basic(&iter_property, &property);
692a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
693a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		dbus_message_iter_next(&iter_property);
694a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		dbus_message_iter_recurse(&iter_property, &sub);
695a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		if (g_str_equal(property, "LineIdentification")) {
696a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			dbus_message_iter_get_basic(&sub, &cli);
6978e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan			DBG("in vc_getproperties_reply(), cli is %s", cli);
698a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			vc->number = g_strdup(cli);
699a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		} else if (g_str_equal(property, "State")) {
700a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			dbus_message_iter_get_basic(&sub, &state);
7018e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan			DBG("in vc_getproperties_reply(),"
702a34c155f55270b917795d003be24488f53d9b711Forrest Zhao					" state is %s", state);
703a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			if (g_str_equal(state, "incoming"))
704a34c155f55270b917795d003be24488f53d9b711Forrest Zhao				vc->status = CALL_STATUS_INCOMING;
705a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			else if (g_str_equal(state, "dialing"))
706a34c155f55270b917795d003be24488f53d9b711Forrest Zhao				vc->status = CALL_STATUS_DIALING;
707a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			else if (g_str_equal(state, "alerting"))
708a34c155f55270b917795d003be24488f53d9b711Forrest Zhao				vc->status = CALL_STATUS_ALERTING;
709a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			else if (g_str_equal(state, "waiting"))
710a34c155f55270b917795d003be24488f53d9b711Forrest Zhao				vc->status = CALL_STATUS_WAITING;
711a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		}
712a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
713a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		dbus_message_iter_next(&iter_entry);
714a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	}
715a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
716a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	switch (vc->status) {
717a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	case CALL_STATUS_INCOMING:
718a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		printf("in CALL_STATUS_INCOMING: case\n");
719a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		vc->originating = FALSE;
720a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		telephony_update_indicator(ofono_indicators, "callsetup",
721a34c155f55270b917795d003be24488f53d9b711Forrest Zhao					EV_CALLSETUP_INCOMING);
722a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		telephony_incoming_call_ind(vc->number, NUMBER_TYPE_TELEPHONY);
723a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		break;
724a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	case CALL_STATUS_DIALING:
725a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		printf("in CALL_STATUS_DIALING: case\n");
726a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		vc->originating = TRUE;
727a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		g_free(last_dialed_number);
728a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		last_dialed_number = g_strdup(vc->number);
729a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		telephony_update_indicator(ofono_indicators, "callsetup",
730a34c155f55270b917795d003be24488f53d9b711Forrest Zhao					EV_CALLSETUP_OUTGOING);
731a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		break;
732a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	case CALL_STATUS_ALERTING:
733a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		printf("in CALL_STATUS_ALERTING: case\n");
734a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		vc->originating = TRUE;
735a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		g_free(last_dialed_number);
736a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		last_dialed_number = g_strdup(vc->number);
737a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		telephony_update_indicator(ofono_indicators, "callsetup",
738a34c155f55270b917795d003be24488f53d9b711Forrest Zhao					EV_CALLSETUP_ALERTING);
739a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		break;
740a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	case CALL_STATUS_WAITING:
7418e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan		DBG("in CALL_STATUS_WAITING: case");
742a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		vc->originating = FALSE;
743a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		telephony_update_indicator(ofono_indicators, "callsetup",
744a34c155f55270b917795d003be24488f53d9b711Forrest Zhao					EV_CALLSETUP_INCOMING);
745a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		telephony_call_waiting_ind(vc->number, NUMBER_TYPE_TELEPHONY);
746a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		break;
747a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	}
748a34c155f55270b917795d003be24488f53d9b711Forrest Zhaodone:
749a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	dbus_message_unref(reply);
750a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
751a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
752a34c155f55270b917795d003be24488f53d9b711Forrest Zhaostatic void vc_free(struct voice_call *vc)
753a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
754a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	if (!vc)
755a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		return;
756a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
7578309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	g_dbus_remove_watch(connection, vc->watch);
758a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	g_free(vc->obj_path);
759a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	g_free(vc->number);
760a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	g_free(vc);
761a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
762a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
7638309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentzstatic gboolean handle_vc_property_changed(DBusConnection *conn,
7648309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz					DBusMessage *msg, void *data)
765a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
7668309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	struct voice_call *vc = data;
7678309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	const char *obj_path = dbus_message_get_path(msg);
768a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	DBusMessageIter iter, sub;
769a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	const char *property, *state;
770a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
7718e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan	DBG("in handle_vc_property_changed, obj_path is %s", obj_path);
772a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
773a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	dbus_message_iter_init(msg, &iter);
774a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
775a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING) {
776a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		error("Unexpected signature in vc PropertyChanged signal");
7778309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz		return TRUE;
778a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	}
779a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
780a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	dbus_message_iter_get_basic(&iter, &property);
7818e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan	DBG("in handle_vc_property_changed(), the property is %s", property);
782a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
783a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	dbus_message_iter_next(&iter);
784a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	dbus_message_iter_recurse(&iter, &sub);
785a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	if (g_str_equal(property, "State")) {
786a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		dbus_message_iter_get_basic(&sub, &state);
7878e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan		DBG("in handle_vc_property_changed(), State is %s", state);
788a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		if (g_str_equal(state, "disconnected")) {
789a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			printf("in disconnected case\n");
790a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			if (vc->status == CALL_STATUS_ACTIVE)
791a34c155f55270b917795d003be24488f53d9b711Forrest Zhao				telephony_update_indicator(ofono_indicators,
792a34c155f55270b917795d003be24488f53d9b711Forrest Zhao						"call", EV_CALL_INACTIVE);
793a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			else
794a34c155f55270b917795d003be24488f53d9b711Forrest Zhao				telephony_update_indicator(ofono_indicators,
795a34c155f55270b917795d003be24488f53d9b711Forrest Zhao					"callsetup", EV_CALLSETUP_INACTIVE);
796a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			if (vc->status == CALL_STATUS_INCOMING)
797a34c155f55270b917795d003be24488f53d9b711Forrest Zhao				telephony_calling_stopped_ind();
798a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			calls = g_slist_remove(calls, vc);
799a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			vc_free(vc);
800a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		} else if (g_str_equal(state, "active")) {
801a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			telephony_update_indicator(ofono_indicators,
802a34c155f55270b917795d003be24488f53d9b711Forrest Zhao							"call", EV_CALL_ACTIVE);
803a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			telephony_update_indicator(ofono_indicators,
804a34c155f55270b917795d003be24488f53d9b711Forrest Zhao							"callsetup",
805a34c155f55270b917795d003be24488f53d9b711Forrest Zhao							EV_CALLSETUP_INACTIVE);
8064ebb87203d438ea2672cc406813807e227b760e2Johan Hedberg			if (vc->status == CALL_STATUS_INCOMING)
807a34c155f55270b917795d003be24488f53d9b711Forrest Zhao				telephony_calling_stopped_ind();
808a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			vc->status = CALL_STATUS_ACTIVE;
8098e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan			DBG("vc status is CALL_STATUS_ACTIVE");
810a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		} else if (g_str_equal(state, "alerting")) {
811a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			telephony_update_indicator(ofono_indicators,
8124ebb87203d438ea2672cc406813807e227b760e2Johan Hedberg					"callsetup", EV_CALLSETUP_ALERTING);
813a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			vc->status = CALL_STATUS_ALERTING;
8148e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan			DBG("vc status is CALL_STATUS_ALERTING");
815a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		} else if (g_str_equal(state, "incoming")) {
816a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			/* state change from waiting to incoming */
817a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			telephony_update_indicator(ofono_indicators,
818a34c155f55270b917795d003be24488f53d9b711Forrest Zhao					"callsetup", EV_CALLSETUP_INCOMING);
819a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			telephony_incoming_call_ind(vc->number,
820a34c155f55270b917795d003be24488f53d9b711Forrest Zhao						NUMBER_TYPE_TELEPHONY);
821a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			vc->status = CALL_STATUS_INCOMING;
8228e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan			DBG("vc status is CALL_STATUS_INCOMING");
823a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		}
824a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	}
8258309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz
8268309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	return TRUE;
8278309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz}
8288309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz
8298309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentzstatic gboolean handle_vcmanager_property_changed(DBusConnection *conn,
8308309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz						DBusMessage *msg, void *data)
8318309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz{
8328309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	DBusMessageIter iter, sub, array;
8338309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	const char *property, *vc_obj_path = NULL;
8348309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	struct voice_call *vc, *vc_new = NULL;
8358309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz
8368e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan	DBG("in handle_vcmanager_property_changed");
8378309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz
8388309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	dbus_message_iter_init(msg, &iter);
8398309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz
8408309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING) {
8418309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz		error("Unexpected signature in vcmanager"
8428309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz					" PropertyChanged signal");
8438309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz		return TRUE;
8448309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	}
8458309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz
8468309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	dbus_message_iter_get_basic(&iter, &property);
8478e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan	DBG("in handle_vcmanager_property_changed(),"
8488309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz				" the property is %s", property);
8498309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz
8508309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	dbus_message_iter_next(&iter);
8518309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	dbus_message_iter_recurse(&iter, &sub);
8528309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_ARRAY) {
8538309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz		error("Unexpected signature in vcmanager"
8548309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz					" PropertyChanged signal");
8558309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz		return TRUE;
8568309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	}
8578309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	dbus_message_iter_recurse(&sub, &array);
8588309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	while (dbus_message_iter_get_arg_type(&array) != DBUS_TYPE_INVALID) {
8598309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz		dbus_message_iter_get_basic(&array, &vc_obj_path);
8608309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz		vc = find_vc(vc_obj_path);
8618309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz		if (vc) {
8628e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan			DBG("in handle_vcmanager_property_changed,"
8638309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz					" found an existing vc");
8648309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz		} else {
8658309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz			vc_new = g_new0(struct voice_call, 1);
8668309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz			vc_new->obj_path = g_strdup(vc_obj_path);
8678309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz			calls = g_slist_append(calls, vc_new);
868ffcc20892f771c6bb604497e8f28e53914fce96dForrest Zhao			vc_new->watch = g_dbus_add_signal_watch(connection,
8698309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz					NULL, vc_obj_path,
8708309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz					OFONO_VC_INTERFACE,
8718309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz					"PropertyChanged",
8728309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz					handle_vc_property_changed,
8738309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz					vc_new, NULL);
8748309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz		}
8758309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz		dbus_message_iter_next(&array);
8768309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	}
8778309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz
8788309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	if (!vc_new)
8798309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz		return TRUE;
8808309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz
8818309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	send_method_call(OFONO_BUS_NAME, vc_new->obj_path,
8828309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz				OFONO_VC_INTERFACE,
8838309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz				"GetProperties", vc_getproperties_reply,
8848309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz				vc_new->obj_path, DBUS_TYPE_INVALID);
8858309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz
8868309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	return TRUE;
887a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
888a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
889a34c155f55270b917795d003be24488f53d9b711Forrest Zhaostatic void hal_battery_level_reply(DBusPendingCall *call, void *user_data)
890a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
891a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	DBusMessage *reply;
892a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	DBusError err;
893a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	dbus_int32_t level;
894a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	int *value = user_data;
895a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
896a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	reply = dbus_pending_call_steal_reply(call);
897a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
898a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	dbus_error_init(&err);
899a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	if (dbus_set_error_from_message(&err, reply)) {
900a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		error("hald replied with an error: %s, %s",
901a34c155f55270b917795d003be24488f53d9b711Forrest Zhao				err.name, err.message);
902a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		dbus_error_free(&err);
903a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		goto done;
904a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	}
905a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
906463763c080cd72ecd727a218dd68f7c0ba95bc9eLuiz Augusto von Dentz	dbus_error_init(&err);
907463763c080cd72ecd727a218dd68f7c0ba95bc9eLuiz Augusto von Dentz	if (dbus_message_get_args(reply, &err,
908a34c155f55270b917795d003be24488f53d9b711Forrest Zhao				DBUS_TYPE_INT32, &level,
909463763c080cd72ecd727a218dd68f7c0ba95bc9eLuiz Augusto von Dentz				DBUS_TYPE_INVALID) == FALSE) {
910463763c080cd72ecd727a218dd68f7c0ba95bc9eLuiz Augusto von Dentz		error("Unable to parse GetPropertyInteger reply: %s, %s",
911463763c080cd72ecd727a218dd68f7c0ba95bc9eLuiz Augusto von Dentz							err.name, err.message);
912463763c080cd72ecd727a218dd68f7c0ba95bc9eLuiz Augusto von Dentz		dbus_error_free(&err);
913463763c080cd72ecd727a218dd68f7c0ba95bc9eLuiz Augusto von Dentz		goto done;
914463763c080cd72ecd727a218dd68f7c0ba95bc9eLuiz Augusto von Dentz	}
915a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
916a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	*value = (int) level;
917a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
918a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	if (value == &battchg_last)
9198e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan		DBG("telephony-ofono: battery.charge_level.last_full"
920a34c155f55270b917795d003be24488f53d9b711Forrest Zhao					" is %d", *value);
921a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	else if (value == &battchg_design)
9228e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan		DBG("telephony-ofono: battery.charge_level.design"
923a34c155f55270b917795d003be24488f53d9b711Forrest Zhao					" is %d", *value);
924a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	else
9258e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan		DBG("telephony-ofono: battery.charge_level.current"
926a34c155f55270b917795d003be24488f53d9b711Forrest Zhao					" is %d", *value);
927a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
928a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	if ((battchg_design > 0 || battchg_last > 0) && battchg_cur >= 0) {
9299ff86aa7f2c11cb3198dfcde93f8db3c534ecdb6Johan Hedberg		int new, max;
930a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
931a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		if (battchg_last > 0)
932a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			max = battchg_last;
933a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		else
934a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			max = battchg_design;
935a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
936a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		new = battchg_cur * 5 / max;
937a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
9389ff86aa7f2c11cb3198dfcde93f8db3c534ecdb6Johan Hedberg		telephony_update_indicator(ofono_indicators, "battchg", new);
939a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	}
940a34c155f55270b917795d003be24488f53d9b711Forrest Zhaodone:
941a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	dbus_message_unref(reply);
942a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
943a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
944a34c155f55270b917795d003be24488f53d9b711Forrest Zhaostatic void hal_get_integer(const char *path, const char *key, void *user_data)
945a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
946a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	send_method_call("org.freedesktop.Hal", path,
947a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			"org.freedesktop.Hal.Device",
948a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			"GetPropertyInteger",
949a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			hal_battery_level_reply, user_data,
950a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			DBUS_TYPE_STRING, &key,
951a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			DBUS_TYPE_INVALID);
952a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
953a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
9548309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentzstatic gboolean handle_hal_property_modified(DBusConnection *conn,
9558309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz						DBusMessage *msg, void *data)
956a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
957a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	const char *path;
958a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	DBusMessageIter iter, array;
959a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	dbus_int32_t num_changes;
960a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
961a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	path = dbus_message_get_path(msg);
962a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
963a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	dbus_message_iter_init(msg, &iter);
964a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
965a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_INT32) {
966a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		error("Unexpected signature in hal PropertyModified signal");
9678309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz		return TRUE;
968a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	}
969a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
970a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	dbus_message_iter_get_basic(&iter, &num_changes);
971a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	dbus_message_iter_next(&iter);
972a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
973a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY) {
974a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		error("Unexpected signature in hal PropertyModified signal");
9758309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz		return TRUE;
976a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	}
977a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
978a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	dbus_message_iter_recurse(&iter, &array);
979a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
980a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	while (dbus_message_iter_get_arg_type(&array) != DBUS_TYPE_INVALID) {
981a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		DBusMessageIter prop;
982a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		const char *name;
983a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		dbus_bool_t added, removed;
984a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
985a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		dbus_message_iter_recurse(&array, &prop);
986a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
987a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		if (!iter_get_basic_args(&prop,
988a34c155f55270b917795d003be24488f53d9b711Forrest Zhao					DBUS_TYPE_STRING, &name,
989a34c155f55270b917795d003be24488f53d9b711Forrest Zhao					DBUS_TYPE_BOOLEAN, &added,
990a34c155f55270b917795d003be24488f53d9b711Forrest Zhao					DBUS_TYPE_BOOLEAN, &removed,
991a34c155f55270b917795d003be24488f53d9b711Forrest Zhao					DBUS_TYPE_INVALID)) {
992a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			error("Invalid hal PropertyModified parameters");
993a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			break;
994a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		}
995a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
996a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		if (g_str_equal(name, "battery.charge_level.last_full"))
997a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			hal_get_integer(path, name, &battchg_last);
998a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		else if (g_str_equal(name, "battery.charge_level.current"))
999a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			hal_get_integer(path, name, &battchg_cur);
1000a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		else if (g_str_equal(name, "battery.charge_level.design"))
1001a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			hal_get_integer(path, name, &battchg_design);
1002a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1003a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		dbus_message_iter_next(&array);
1004a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	}
10058309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz
10068309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	return TRUE;
1007a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
1008a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
10098309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentzstatic void hal_find_device_reply(DBusPendingCall *call, void *user_data)
1010a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
10118309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	DBusMessage *reply;
10128309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	DBusError err;
10138309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	DBusMessageIter iter, sub;
10148309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	int type;
10158309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	const char *path;
10168309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz
10178e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan	DBG("begin of hal_find_device_reply()");
10188309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	reply = dbus_pending_call_steal_reply(call);
10198309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz
10208309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	dbus_error_init(&err);
10218309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz
10228309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	if (dbus_set_error_from_message(&err, reply)) {
10238309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz		error("hald replied with an error: %s, %s",
10248309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz				err.name, err.message);
10258309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz		dbus_error_free(&err);
10268309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz		goto done;
10278309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	}
10288309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz
10298309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	dbus_message_iter_init(reply, &iter);
10308309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz
10318309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY) {
10328309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz		error("Unexpected signature in hal_find_device_reply()");
10338309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz		goto done;
10348309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	}
10358309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz
10368309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	dbus_message_iter_recurse(&iter, &sub);
10378309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz
10388309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	type = dbus_message_iter_get_arg_type(&sub);
10398309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz
10408309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	if (type != DBUS_TYPE_OBJECT_PATH && type != DBUS_TYPE_STRING) {
10418309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz		error("No hal device with battery capability found");
10428309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz		goto done;
10438309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	}
10448309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz
10458309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	dbus_message_iter_get_basic(&sub, &path);
10468309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz
10478e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan	DBG("telephony-ofono: found battery device at %s", path);
10488309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz
10498309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	device_watch = g_dbus_add_signal_watch(connection, NULL, path,
10508309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz					"org.freedesktop.Hal.Device",
10518309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz					"PropertyModified",
10528309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz					handle_hal_property_modified,
10538309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz					NULL, NULL);
10548309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz
10558309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	hal_get_integer(path, "battery.charge_level.last_full", &battchg_last);
10568309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	hal_get_integer(path, "battery.charge_level.current", &battchg_cur);
10578309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	hal_get_integer(path, "battery.charge_level.design", &battchg_design);
10588309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentzdone:
10598309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	dbus_message_unref(reply);
1060a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
1061a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1062a34c155f55270b917795d003be24488f53d9b711Forrest Zhaoint telephony_init(void)
1063a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
1064a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	const char *battery_cap = "battery";
1065a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	int ret;
1066a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1067a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	connection = dbus_bus_get(DBUS_BUS_SYSTEM, NULL);
1068a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
10698309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	registration_watch = g_dbus_add_signal_watch(connection, NULL, NULL,
10708309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz					OFONO_NETWORKREG_INTERFACE,
10718309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz					"PropertyChanged",
10728309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz					handle_registration_property_changed,
10738309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz					NULL, NULL);
1074a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
10758309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	voice_watch = g_dbus_add_signal_watch(connection, NULL, NULL,
10768309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz					OFONO_VCMANAGER_INTERFACE,
10778309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz					"PropertyChanged",
10788309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz					handle_vcmanager_property_changed,
10798309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz					NULL, NULL);
1080a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1081a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	ret = send_method_call(OFONO_BUS_NAME, OFONO_PATH,
1082a34c155f55270b917795d003be24488f53d9b711Forrest Zhao				OFONO_MANAGER_INTERFACE, "GetProperties",
1083a34c155f55270b917795d003be24488f53d9b711Forrest Zhao				list_modem_reply, NULL, DBUS_TYPE_INVALID);
1084a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	if (ret < 0)
1085a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		return ret;
1086a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1087a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	ret = send_method_call("org.freedesktop.Hal",
1088a34c155f55270b917795d003be24488f53d9b711Forrest Zhao				"/org/freedesktop/Hal/Manager",
1089a34c155f55270b917795d003be24488f53d9b711Forrest Zhao				"org.freedesktop.Hal.Manager",
1090a34c155f55270b917795d003be24488f53d9b711Forrest Zhao				"FindDeviceByCapability",
1091a34c155f55270b917795d003be24488f53d9b711Forrest Zhao				hal_find_device_reply, NULL,
1092a34c155f55270b917795d003be24488f53d9b711Forrest Zhao				DBUS_TYPE_STRING, &battery_cap,
1093a34c155f55270b917795d003be24488f53d9b711Forrest Zhao				DBUS_TYPE_INVALID);
1094a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	if (ret < 0)
1095a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		return ret;
1096a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
10978e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan	DBG("telephony_init() successfully");
1098a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1099a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	return ret;
1100a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
1101a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1102a34c155f55270b917795d003be24488f53d9b711Forrest Zhaovoid telephony_exit(void)
1103a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
1104a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	g_free(net.operator_name);
1105a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1106a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	g_free(modem_obj_path);
1107a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	g_free(last_dialed_number);
1108a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1109a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	g_slist_foreach(calls, (GFunc) vc_free, NULL);
1110a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	g_slist_free(calls);
1111a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	calls = NULL;
1112a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
11138309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	g_dbus_remove_watch(connection, registration_watch);
11148309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	g_dbus_remove_watch(connection, voice_watch);
11158309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	g_dbus_remove_watch(connection, device_watch);
1116a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1117a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	dbus_connection_unref(connection);
1118a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	connection = NULL;
1119a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
1120