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;
519d7109c994bec237bdf1fff158d9400cbfb1b5c9Luiz Augusto von Dentz	gboolean conference;
52a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	char *number;
538309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	guint watch;
54a34c155f55270b917795d003be24488f53d9b711Forrest Zhao};
55a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
56a34c155f55270b917795d003be24488f53d9b711Forrest Zhaostatic DBusConnection *connection = NULL;
57a34c155f55270b917795d003be24488f53d9b711Forrest Zhaostatic char *modem_obj_path = NULL;
58a34c155f55270b917795d003be24488f53d9b711Forrest Zhaostatic char *last_dialed_number = NULL;
59a34c155f55270b917795d003be24488f53d9b711Forrest Zhaostatic GSList *calls = NULL;
609946e8636c3361dc769c5f8a463b74158018d3ddLuiz Augusto von Dentzstatic GSList *watches = NULL;
61c49dc8c7c815191b5825896f827cac2e2ff395ffLuiz Augusto von Dentzstatic GSList *pending = NULL;
62a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
63a34c155f55270b917795d003be24488f53d9b711Forrest Zhao#define OFONO_BUS_NAME "org.ofono"
64a34c155f55270b917795d003be24488f53d9b711Forrest Zhao#define OFONO_PATH "/"
65806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz#define OFONO_MODEM_INTERFACE "org.ofono.Modem"
66d89690657f2634ceb9d4b13257ccc7d60bc0cb5dForrest Zhao#define OFONO_MANAGER_INTERFACE "org.ofono.Manager"
67a34c155f55270b917795d003be24488f53d9b711Forrest Zhao#define OFONO_NETWORKREG_INTERFACE "org.ofono.NetworkRegistration"
68a34c155f55270b917795d003be24488f53d9b711Forrest Zhao#define OFONO_VCMANAGER_INTERFACE "org.ofono.VoiceCallManager"
69a34c155f55270b917795d003be24488f53d9b711Forrest Zhao#define OFONO_VC_INTERFACE "org.ofono.VoiceCall"
70a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
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 Zhaostatic struct indicator ofono_indicators[] =
92a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
93884debf8418651b63b1a5a8918092ba4d230783eJohan Hedberg	{ "battchg",	"0-5",	5,	TRUE },
94884debf8418651b63b1a5a8918092ba4d230783eJohan Hedberg	{ "signal",	"0-5",	5,	TRUE },
95884debf8418651b63b1a5a8918092ba4d230783eJohan Hedberg	{ "service",	"0,1",	1,	TRUE },
96884debf8418651b63b1a5a8918092ba4d230783eJohan Hedberg	{ "call",	"0,1",	0,	TRUE },
97884debf8418651b63b1a5a8918092ba4d230783eJohan Hedberg	{ "callsetup",	"0-3",	0,	TRUE },
98884debf8418651b63b1a5a8918092ba4d230783eJohan Hedberg	{ "callheld",	"0-2",	0,	FALSE },
99884debf8418651b63b1a5a8918092ba4d230783eJohan Hedberg	{ "roam",	"0,1",	0,	TRUE },
100a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	{ NULL }
101a34c155f55270b917795d003be24488f53d9b711Forrest Zhao};
102a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
103a34c155f55270b917795d003be24488f53d9b711Forrest Zhaostatic struct voice_call *find_vc(const char *path)
104a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
105a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	GSList *l;
106a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
107a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	for (l = calls; l != NULL; l = l->next) {
108a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		struct voice_call *vc = l->data;
109a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
110a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		if (g_str_equal(vc->obj_path, path))
111a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			return vc;
112a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	}
113a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
114a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	return NULL;
115a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
116a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
117a34c155f55270b917795d003be24488f53d9b711Forrest Zhaostatic struct voice_call *find_vc_with_status(int status)
118a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
119a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	GSList *l;
120a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
121a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	for (l = calls; l != NULL; l = l->next) {
122a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		struct voice_call *vc = l->data;
123a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
124a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		if (vc->status == status)
125a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			return vc;
126a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	}
127a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
128a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	return NULL;
129a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
130a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
131d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentzstatic struct voice_call *find_vc_without_status(int status)
132d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz{
133d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	GSList *l;
134d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz
135d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	for (l = calls; l != NULL; l = l->next) {
136d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz		struct voice_call *call = l->data;
137d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz
138d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz		if (call->status != status)
139d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz			return call;
140d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	}
141d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz
142d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	return NULL;
143d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz}
144d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz
1451097cfd46e906ddfd8a827ce683c1eddf2d98499Luiz Augusto von Dentzstatic int number_type(const char *number)
1461097cfd46e906ddfd8a827ce683c1eddf2d98499Luiz Augusto von Dentz{
1471097cfd46e906ddfd8a827ce683c1eddf2d98499Luiz Augusto von Dentz	if (number == NULL)
1481097cfd46e906ddfd8a827ce683c1eddf2d98499Luiz Augusto von Dentz		return NUMBER_TYPE_TELEPHONY;
1491097cfd46e906ddfd8a827ce683c1eddf2d98499Luiz Augusto von Dentz
1501097cfd46e906ddfd8a827ce683c1eddf2d98499Luiz Augusto von Dentz	if (number[0] == '+' || strncmp(number, "00", 2) == 0)
1511097cfd46e906ddfd8a827ce683c1eddf2d98499Luiz Augusto von Dentz		return NUMBER_TYPE_INTERNATIONAL;
1521097cfd46e906ddfd8a827ce683c1eddf2d98499Luiz Augusto von Dentz
1531097cfd46e906ddfd8a827ce683c1eddf2d98499Luiz Augusto von Dentz	return NUMBER_TYPE_TELEPHONY;
1541097cfd46e906ddfd8a827ce683c1eddf2d98499Luiz Augusto von Dentz}
1551097cfd46e906ddfd8a827ce683c1eddf2d98499Luiz Augusto von Dentz
156a34c155f55270b917795d003be24488f53d9b711Forrest Zhaovoid telephony_device_connected(void *telephony_device)
157a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
1581097cfd46e906ddfd8a827ce683c1eddf2d98499Luiz Augusto von Dentz	struct voice_call *coming;
1591097cfd46e906ddfd8a827ce683c1eddf2d98499Luiz Augusto von Dentz
1608e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan	DBG("telephony-ofono: device %p connected", telephony_device);
1611097cfd46e906ddfd8a827ce683c1eddf2d98499Luiz Augusto von Dentz
1621097cfd46e906ddfd8a827ce683c1eddf2d98499Luiz Augusto von Dentz	coming = find_vc_with_status(CALL_STATUS_ALERTING);
1631097cfd46e906ddfd8a827ce683c1eddf2d98499Luiz Augusto von Dentz	if (coming) {
1641097cfd46e906ddfd8a827ce683c1eddf2d98499Luiz Augusto von Dentz		if (find_vc_with_status(CALL_STATUS_ACTIVE))
1651097cfd46e906ddfd8a827ce683c1eddf2d98499Luiz Augusto von Dentz			telephony_call_waiting_ind(coming->number,
1661097cfd46e906ddfd8a827ce683c1eddf2d98499Luiz Augusto von Dentz						number_type(coming->number));
1671097cfd46e906ddfd8a827ce683c1eddf2d98499Luiz Augusto von Dentz		else
1681097cfd46e906ddfd8a827ce683c1eddf2d98499Luiz Augusto von Dentz			telephony_incoming_call_ind(coming->number,
1691097cfd46e906ddfd8a827ce683c1eddf2d98499Luiz Augusto von Dentz						number_type(coming->number));
1701097cfd46e906ddfd8a827ce683c1eddf2d98499Luiz Augusto von Dentz	}
171a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
172a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
173a34c155f55270b917795d003be24488f53d9b711Forrest Zhaovoid telephony_device_disconnected(void *telephony_device)
174a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
1758e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan	DBG("telephony-ofono: device %p disconnected", telephony_device);
176a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	events_enabled = FALSE;
177a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
178a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
179a34c155f55270b917795d003be24488f53d9b711Forrest Zhaovoid telephony_event_reporting_req(void *telephony_device, int ind)
180a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
181a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	events_enabled = ind == 1 ? TRUE : FALSE;
182a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
183a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	telephony_event_reporting_rsp(telephony_device, CME_ERROR_NONE);
184a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
185a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
186a34c155f55270b917795d003be24488f53d9b711Forrest Zhaovoid telephony_response_and_hold_req(void *telephony_device, int rh)
187a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
188b0d302d48976920cec7548ec5cc603f3896bbb8cJohan Hedberg	telephony_response_and_hold_rsp(telephony_device,
189b0d302d48976920cec7548ec5cc603f3896bbb8cJohan Hedberg						CME_ERROR_NOT_SUPPORTED);
190a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
191a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
192a34c155f55270b917795d003be24488f53d9b711Forrest Zhaovoid telephony_last_dialed_number_req(void *telephony_device)
193a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
1948e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan	DBG("telephony-ofono: last dialed number request");
195a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
196a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	if (last_dialed_number)
197a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		telephony_dial_number_req(telephony_device, last_dialed_number);
198a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	else
199a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		telephony_last_dialed_number_rsp(telephony_device,
200a34c155f55270b917795d003be24488f53d9b711Forrest Zhao				CME_ERROR_NOT_ALLOWED);
201a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
202a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
203a34c155f55270b917795d003be24488f53d9b711Forrest Zhaostatic int send_method_call(const char *dest, const char *path,
204a34c155f55270b917795d003be24488f53d9b711Forrest Zhao                                const char *interface, const char *method,
205a34c155f55270b917795d003be24488f53d9b711Forrest Zhao                                DBusPendingCallNotifyFunction cb,
206a34c155f55270b917795d003be24488f53d9b711Forrest Zhao                                void *user_data, int type, ...)
207a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
208a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	DBusMessage *msg;
209a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	DBusPendingCall *call;
210a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	va_list args;
211a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
212a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	msg = dbus_message_new_method_call(dest, path, interface, method);
213a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	if (!msg) {
214a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		error("Unable to allocate new D-Bus %s message", method);
215a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		return -ENOMEM;
216a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	}
217a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
218a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	va_start(args, type);
219a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
220a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	if (!dbus_message_append_args_valist(msg, type, args)) {
221a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		dbus_message_unref(msg);
222a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		va_end(args);
223a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		return -EIO;
224a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	}
225a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
226a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	va_end(args);
227a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
228a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	if (!cb) {
229a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		g_dbus_send_message(connection, msg);
230a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		return 0;
231a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	}
232a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
233a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	if (!dbus_connection_send_with_reply(connection, msg, &call, -1)) {
234a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		error("Sending %s failed", method);
235a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		dbus_message_unref(msg);
236a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		return -EIO;
237a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	}
238a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
239a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	dbus_pending_call_set_notify(call, cb, user_data, NULL);
240c49dc8c7c815191b5825896f827cac2e2ff395ffLuiz Augusto von Dentz	pending = g_slist_prepend(pending, call);
241a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	dbus_message_unref(msg);
242a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
243a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	return 0;
244a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
245a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
246d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentzstatic int answer_call(struct voice_call *vc)
247d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz{
248d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	DBG("%s", vc->number);
249d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	return send_method_call(OFONO_BUS_NAME, vc->obj_path,
250d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz						OFONO_VC_INTERFACE, "Answer",
251d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz						NULL, NULL, DBUS_TYPE_INVALID);
252d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz}
253d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz
254d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentzstatic int release_call(struct voice_call *vc)
255d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz{
256d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	DBG("%s", vc->number);
257d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	return send_method_call(OFONO_BUS_NAME, vc->obj_path,
258d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz						OFONO_VC_INTERFACE, "Hangup",
259d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz						NULL, NULL, DBUS_TYPE_INVALID);
260d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz}
261d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz
2623948fb1198bb7aefea995da09940432378965af9Szymon Jancstatic int release_answer_calls(void)
263d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz{
264d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	DBG("");
265d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	return send_method_call(OFONO_BUS_NAME, modem_obj_path,
266d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz						OFONO_VCMANAGER_INTERFACE,
267d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz						"ReleaseAndAnswer",
268d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz						NULL, NULL, DBUS_TYPE_INVALID);
269d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz}
270d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz
271a6099d662b4304e9255c53ab28f23358bb893cbaLuiz Augusto von Dentzstatic int split_call(struct voice_call *call)
272d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz{
273a6099d662b4304e9255c53ab28f23358bb893cbaLuiz Augusto von Dentz	DBG("%s", call->number);
274d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	return send_method_call(OFONO_BUS_NAME, modem_obj_path,
275d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz						OFONO_VCMANAGER_INTERFACE,
276a6099d662b4304e9255c53ab28f23358bb893cbaLuiz Augusto von Dentz						"PrivateChat",
277a6099d662b4304e9255c53ab28f23358bb893cbaLuiz Augusto von Dentz						NULL, NULL,
278a6099d662b4304e9255c53ab28f23358bb893cbaLuiz Augusto von Dentz						DBUS_TYPE_OBJECT_PATH,
279a6099d662b4304e9255c53ab28f23358bb893cbaLuiz Augusto von Dentz						call->obj_path,
280a6099d662b4304e9255c53ab28f23358bb893cbaLuiz Augusto von Dentz						DBUS_TYPE_INVALID);
281a6099d662b4304e9255c53ab28f23358bb893cbaLuiz Augusto von Dentz	return -1;
282d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz}
283d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz
284a6099d662b4304e9255c53ab28f23358bb893cbaLuiz Augusto von Dentzstatic int swap_calls(void)
285d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz{
286d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	DBG("");
287d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	return send_method_call(OFONO_BUS_NAME, modem_obj_path,
288d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz						OFONO_VCMANAGER_INTERFACE,
289a6099d662b4304e9255c53ab28f23358bb893cbaLuiz Augusto von Dentz						"SwapCalls",
290d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz						NULL, NULL, DBUS_TYPE_INVALID);
291d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz}
292d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz
2939d7109c994bec237bdf1fff158d9400cbfb1b5c9Luiz Augusto von Dentzstatic int create_conference(void)
2949d7109c994bec237bdf1fff158d9400cbfb1b5c9Luiz Augusto von Dentz{
2959d7109c994bec237bdf1fff158d9400cbfb1b5c9Luiz Augusto von Dentz	DBG("");
2969d7109c994bec237bdf1fff158d9400cbfb1b5c9Luiz Augusto von Dentz	return send_method_call(OFONO_BUS_NAME, modem_obj_path,
2979d7109c994bec237bdf1fff158d9400cbfb1b5c9Luiz Augusto von Dentz						OFONO_VCMANAGER_INTERFACE,
2989d7109c994bec237bdf1fff158d9400cbfb1b5c9Luiz Augusto von Dentz						"CreateMultiparty",
2999d7109c994bec237bdf1fff158d9400cbfb1b5c9Luiz Augusto von Dentz						NULL, NULL, DBUS_TYPE_INVALID);
3009d7109c994bec237bdf1fff158d9400cbfb1b5c9Luiz Augusto von Dentz}
3019d7109c994bec237bdf1fff158d9400cbfb1b5c9Luiz Augusto von Dentz
3029d7109c994bec237bdf1fff158d9400cbfb1b5c9Luiz Augusto von Dentzstatic int release_conference(void)
3039d7109c994bec237bdf1fff158d9400cbfb1b5c9Luiz Augusto von Dentz{
3049d7109c994bec237bdf1fff158d9400cbfb1b5c9Luiz Augusto von Dentz	DBG("");
3059d7109c994bec237bdf1fff158d9400cbfb1b5c9Luiz Augusto von Dentz	return send_method_call(OFONO_BUS_NAME, modem_obj_path,
3069d7109c994bec237bdf1fff158d9400cbfb1b5c9Luiz Augusto von Dentz						OFONO_VCMANAGER_INTERFACE,
3079d7109c994bec237bdf1fff158d9400cbfb1b5c9Luiz Augusto von Dentz						"HangupMultiparty",
3089d7109c994bec237bdf1fff158d9400cbfb1b5c9Luiz Augusto von Dentz						NULL, NULL, DBUS_TYPE_INVALID);
3099d7109c994bec237bdf1fff158d9400cbfb1b5c9Luiz Augusto von Dentz}
3109d7109c994bec237bdf1fff158d9400cbfb1b5c9Luiz Augusto von Dentz
3119d7109c994bec237bdf1fff158d9400cbfb1b5c9Luiz Augusto von Dentzstatic int call_transfer(void)
3129d7109c994bec237bdf1fff158d9400cbfb1b5c9Luiz Augusto von Dentz{
3139d7109c994bec237bdf1fff158d9400cbfb1b5c9Luiz Augusto von Dentz	DBG("");
3149d7109c994bec237bdf1fff158d9400cbfb1b5c9Luiz Augusto von Dentz	return send_method_call(OFONO_BUS_NAME, modem_obj_path,
3159d7109c994bec237bdf1fff158d9400cbfb1b5c9Luiz Augusto von Dentz						OFONO_VCMANAGER_INTERFACE,
3169d7109c994bec237bdf1fff158d9400cbfb1b5c9Luiz Augusto von Dentz						"Transfer",
3179d7109c994bec237bdf1fff158d9400cbfb1b5c9Luiz Augusto von Dentz						NULL, NULL, DBUS_TYPE_INVALID);
3189d7109c994bec237bdf1fff158d9400cbfb1b5c9Luiz Augusto von Dentz}
3199d7109c994bec237bdf1fff158d9400cbfb1b5c9Luiz Augusto von Dentz
320a34c155f55270b917795d003be24488f53d9b711Forrest Zhaovoid telephony_terminate_call_req(void *telephony_device)
321a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
322d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	struct voice_call *call;
323d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	struct voice_call *alerting;
324d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	int err;
325a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
326d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	call = find_vc_with_status(CALL_STATUS_ACTIVE);
327d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	if (!call)
328d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz		call = calls->data;
329a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
330d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	if (!call) {
331d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz		error("No active call");
332a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		telephony_terminate_call_rsp(telephony_device,
333d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz						CME_ERROR_NOT_ALLOWED);
334a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		return;
335a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	}
336a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
337d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	alerting = find_vc_with_status(CALL_STATUS_ALERTING);
338d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	if (call->status == CALL_STATUS_HELD && alerting)
339d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz		err = release_call(alerting);
3409d7109c994bec237bdf1fff158d9400cbfb1b5c9Luiz Augusto von Dentz	else if (call->conference)
3419d7109c994bec237bdf1fff158d9400cbfb1b5c9Luiz Augusto von Dentz		err = release_conference();
342d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	else
343d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz		err = release_call(call);
344a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
345d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	if (err < 0)
346d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz		telephony_terminate_call_rsp(telephony_device,
347d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz						CME_ERROR_AG_FAILURE);
348d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	else
349d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz		telephony_terminate_call_rsp(telephony_device, CME_ERROR_NONE);
350a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
351a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
352a34c155f55270b917795d003be24488f53d9b711Forrest Zhaovoid telephony_answer_call_req(void *telephony_device)
353a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
35416ec168ac7fdd18cb2cbc7b3be7df349fd84c41cLuiz Augusto von Dentz	struct voice_call *vc;
355a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	int ret;
356a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
35716ec168ac7fdd18cb2cbc7b3be7df349fd84c41cLuiz Augusto von Dentz	vc = find_vc_with_status(CALL_STATUS_INCOMING);
35816ec168ac7fdd18cb2cbc7b3be7df349fd84c41cLuiz Augusto von Dentz	if (!vc)
35916ec168ac7fdd18cb2cbc7b3be7df349fd84c41cLuiz Augusto von Dentz		vc = find_vc_with_status(CALL_STATUS_ALERTING);
36016ec168ac7fdd18cb2cbc7b3be7df349fd84c41cLuiz Augusto von Dentz
36116ec168ac7fdd18cb2cbc7b3be7df349fd84c41cLuiz Augusto von Dentz	if (!vc)
36216ec168ac7fdd18cb2cbc7b3be7df349fd84c41cLuiz Augusto von Dentz		vc = find_vc_with_status(CALL_STATUS_WAITING);
36316ec168ac7fdd18cb2cbc7b3be7df349fd84c41cLuiz Augusto von Dentz
364a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	if (!vc) {
365a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		telephony_answer_call_rsp(telephony_device,
366a34c155f55270b917795d003be24488f53d9b711Forrest Zhao					CME_ERROR_NOT_ALLOWED);
367a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		return;
368a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	}
369a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
370d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	ret = answer_call(vc);
371a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	if (ret < 0) {
372a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		telephony_answer_call_rsp(telephony_device,
373a34c155f55270b917795d003be24488f53d9b711Forrest Zhao					CME_ERROR_AG_FAILURE);
374a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		return;
375a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	}
376a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
377a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	telephony_answer_call_rsp(telephony_device, CME_ERROR_NONE);
378a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
379a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
380a34c155f55270b917795d003be24488f53d9b711Forrest Zhaovoid telephony_dial_number_req(void *telephony_device, const char *number)
381a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
38283003660808c30390f21c569a5ba7dbdd8344a41Claudio Takahasi	const char *clir;
383a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	int ret;
384a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
3858e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan	DBG("telephony-ofono: dial request to %s", number);
386a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
387c5321032b046c39477ab99a05e933b13d0b67a04Forrest Zhao	if (!modem_obj_path) {
388c5321032b046c39477ab99a05e933b13d0b67a04Forrest Zhao		telephony_dial_number_rsp(telephony_device,
389c5321032b046c39477ab99a05e933b13d0b67a04Forrest Zhao					CME_ERROR_AG_FAILURE);
390c5321032b046c39477ab99a05e933b13d0b67a04Forrest Zhao		return;
391c5321032b046c39477ab99a05e933b13d0b67a04Forrest Zhao	}
392c5321032b046c39477ab99a05e933b13d0b67a04Forrest Zhao
393a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	if (!strncmp(number, "*31#", 4)) {
394a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		number += 4;
39583003660808c30390f21c569a5ba7dbdd8344a41Claudio Takahasi		clir = "enabled";
396a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	} else if (!strncmp(number, "#31#", 4)) {
397a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		number += 4;
39883003660808c30390f21c569a5ba7dbdd8344a41Claudio Takahasi		clir =  "disabled";
39983003660808c30390f21c569a5ba7dbdd8344a41Claudio Takahasi	} else
40083003660808c30390f21c569a5ba7dbdd8344a41Claudio Takahasi		clir = "default";
401a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
402a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	ret = send_method_call(OFONO_BUS_NAME, modem_obj_path,
403a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			OFONO_VCMANAGER_INTERFACE,
404a34c155f55270b917795d003be24488f53d9b711Forrest Zhao                        "Dial", NULL, NULL,
405a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			DBUS_TYPE_STRING, &number,
406a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			DBUS_TYPE_STRING, &clir,
407a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			DBUS_TYPE_INVALID);
408a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
409a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	if (ret < 0)
410a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		telephony_dial_number_rsp(telephony_device,
411a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			CME_ERROR_AG_FAILURE);
412a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	else
413a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		telephony_dial_number_rsp(telephony_device, CME_ERROR_NONE);
414a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
415a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
416a34c155f55270b917795d003be24488f53d9b711Forrest Zhaovoid telephony_transmit_dtmf_req(void *telephony_device, char tone)
417a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
418a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	char *tone_string;
419a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	int ret;
420a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
4218e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan	DBG("telephony-ofono: transmit dtmf: %c", tone);
422a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
423c5321032b046c39477ab99a05e933b13d0b67a04Forrest Zhao	if (!modem_obj_path) {
424c5321032b046c39477ab99a05e933b13d0b67a04Forrest Zhao		telephony_transmit_dtmf_rsp(telephony_device,
425c5321032b046c39477ab99a05e933b13d0b67a04Forrest Zhao					CME_ERROR_AG_FAILURE);
426c5321032b046c39477ab99a05e933b13d0b67a04Forrest Zhao		return;
427c5321032b046c39477ab99a05e933b13d0b67a04Forrest Zhao	}
428c5321032b046c39477ab99a05e933b13d0b67a04Forrest Zhao
429a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	tone_string = g_strdup_printf("%c", tone);
430a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	ret = send_method_call(OFONO_BUS_NAME, modem_obj_path,
431a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			OFONO_VCMANAGER_INTERFACE,
432a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			"SendTones", NULL, NULL,
433a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			DBUS_TYPE_STRING, &tone_string,
434a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			DBUS_TYPE_INVALID);
435a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	g_free(tone_string);
436a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
437a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	if (ret < 0)
438a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		telephony_transmit_dtmf_rsp(telephony_device,
439a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			CME_ERROR_AG_FAILURE);
440a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	else
441a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		telephony_transmit_dtmf_rsp(telephony_device, CME_ERROR_NONE);
442a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
443a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
444a34c155f55270b917795d003be24488f53d9b711Forrest Zhaovoid telephony_subscriber_number_req(void *telephony_device)
445a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
4468e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan	DBG("telephony-ofono: subscriber number request");
447a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
448a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	if (subscriber_number)
449a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		telephony_subscriber_number_ind(subscriber_number,
450a34c155f55270b917795d003be24488f53d9b711Forrest Zhao						NUMBER_TYPE_TELEPHONY,
451a34c155f55270b917795d003be24488f53d9b711Forrest Zhao						SUBSCRIBER_SERVICE_VOICE);
452a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	telephony_subscriber_number_rsp(telephony_device, CME_ERROR_NONE);
453a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
454a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
455a34c155f55270b917795d003be24488f53d9b711Forrest Zhaovoid telephony_list_current_calls_req(void *telephony_device)
456a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
457a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	GSList *l;
458a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	int i;
459a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
4608e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan	DBG("telephony-ofono: list current calls request");
461a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
462a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	for (l = calls, i = 1; l != NULL; l = l->next, i++) {
463a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		struct voice_call *vc = l->data;
4649d7109c994bec237bdf1fff158d9400cbfb1b5c9Luiz Augusto von Dentz		int direction, multiparty;
465a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
466a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		direction = vc->originating ?
467a34c155f55270b917795d003be24488f53d9b711Forrest Zhao				CALL_DIR_OUTGOING : CALL_DIR_INCOMING;
468a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
4699d7109c994bec237bdf1fff158d9400cbfb1b5c9Luiz Augusto von Dentz		multiparty = vc->conference ?
4709d7109c994bec237bdf1fff158d9400cbfb1b5c9Luiz Augusto von Dentz				CALL_MULTIPARTY_YES : CALL_MULTIPARTY_NO;
4719d7109c994bec237bdf1fff158d9400cbfb1b5c9Luiz Augusto von Dentz
4729d7109c994bec237bdf1fff158d9400cbfb1b5c9Luiz Augusto von Dentz		DBG("call %s direction %d multiparty %d", vc->number,
4739d7109c994bec237bdf1fff158d9400cbfb1b5c9Luiz Augusto von Dentz							direction, multiparty);
474d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz
475a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		telephony_list_current_call_ind(i, direction, vc->status,
4769d7109c994bec237bdf1fff158d9400cbfb1b5c9Luiz Augusto von Dentz					CALL_MODE_VOICE, multiparty,
477d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz					vc->number, number_type(vc->number));
478a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	}
479d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz
480a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	telephony_list_current_calls_rsp(telephony_device, CME_ERROR_NONE);
481a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
482a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
483a34c155f55270b917795d003be24488f53d9b711Forrest Zhaovoid telephony_operator_selection_req(void *telephony_device)
484a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
4858e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan	DBG("telephony-ofono: operator selection request");
486a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
487a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	telephony_operator_selection_ind(OPERATOR_MODE_AUTO,
488a34c155f55270b917795d003be24488f53d9b711Forrest Zhao				net.operator_name ? net.operator_name : "");
489a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	telephony_operator_selection_rsp(telephony_device, CME_ERROR_NONE);
490a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
491a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
492d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentzstatic void foreach_vc_with_status(int status,
493d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz					int (*func)(struct voice_call *vc))
494d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz{
495d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	GSList *l;
496d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz
497d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	for (l = calls; l != NULL; l = l->next) {
498d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz		struct voice_call *call = l->data;
499d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz
500d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz		if (call->status == status)
501d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz			func(call);
502d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	}
503d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz}
504d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz
505a34c155f55270b917795d003be24488f53d9b711Forrest Zhaovoid telephony_call_hold_req(void *telephony_device, const char *cmd)
506a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
507a6099d662b4304e9255c53ab28f23358bb893cbaLuiz Augusto von Dentz	const char *idx;
508d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	struct voice_call *call;
509d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	int err = 0;
510d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz
5118e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan	DBG("telephony-ofono: got call hold request %s", cmd);
512d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz
513a6099d662b4304e9255c53ab28f23358bb893cbaLuiz Augusto von Dentz	if (strlen(cmd) > 1)
514a6099d662b4304e9255c53ab28f23358bb893cbaLuiz Augusto von Dentz		idx = &cmd[1];
515a6099d662b4304e9255c53ab28f23358bb893cbaLuiz Augusto von Dentz	else
516a6099d662b4304e9255c53ab28f23358bb893cbaLuiz Augusto von Dentz		idx = NULL;
517a6099d662b4304e9255c53ab28f23358bb893cbaLuiz Augusto von Dentz
518a6099d662b4304e9255c53ab28f23358bb893cbaLuiz Augusto von Dentz	if (idx)
519a6099d662b4304e9255c53ab28f23358bb893cbaLuiz Augusto von Dentz		call = g_slist_nth_data(calls, strtol(idx, NULL, 0) - 1);
520a6099d662b4304e9255c53ab28f23358bb893cbaLuiz Augusto von Dentz	else
521a6099d662b4304e9255c53ab28f23358bb893cbaLuiz Augusto von Dentz		call = NULL;
522a6099d662b4304e9255c53ab28f23358bb893cbaLuiz Augusto von Dentz
523d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	switch (cmd[0]) {
524d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	case '0':
525d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz		if (find_vc_with_status(CALL_STATUS_WAITING))
526d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz			foreach_vc_with_status(CALL_STATUS_WAITING,
527d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz								release_call);
528d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz		else
529d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz			foreach_vc_with_status(CALL_STATUS_HELD, release_call);
530d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz		break;
531d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	case '1':
532a6099d662b4304e9255c53ab28f23358bb893cbaLuiz Augusto von Dentz		if (idx) {
533a6099d662b4304e9255c53ab28f23358bb893cbaLuiz Augusto von Dentz			if (call)
534a6099d662b4304e9255c53ab28f23358bb893cbaLuiz Augusto von Dentz				err = release_call(call);
535a6099d662b4304e9255c53ab28f23358bb893cbaLuiz Augusto von Dentz			break;
536a6099d662b4304e9255c53ab28f23358bb893cbaLuiz Augusto von Dentz		}
537d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz		err = release_answer_calls();
538d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz		break;
539d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	case '2':
540a6099d662b4304e9255c53ab28f23358bb893cbaLuiz Augusto von Dentz		if (idx) {
541a6099d662b4304e9255c53ab28f23358bb893cbaLuiz Augusto von Dentz			if (call)
542a6099d662b4304e9255c53ab28f23358bb893cbaLuiz Augusto von Dentz				err = split_call(call);
543a6099d662b4304e9255c53ab28f23358bb893cbaLuiz Augusto von Dentz		} else {
544a6099d662b4304e9255c53ab28f23358bb893cbaLuiz Augusto von Dentz			call = find_vc_with_status(CALL_STATUS_WAITING);
545a6099d662b4304e9255c53ab28f23358bb893cbaLuiz Augusto von Dentz
546a6099d662b4304e9255c53ab28f23358bb893cbaLuiz Augusto von Dentz			if (call)
547a6099d662b4304e9255c53ab28f23358bb893cbaLuiz Augusto von Dentz				err = answer_call(call);
548a6099d662b4304e9255c53ab28f23358bb893cbaLuiz Augusto von Dentz			else
549a6099d662b4304e9255c53ab28f23358bb893cbaLuiz Augusto von Dentz				err = swap_calls();
550a6099d662b4304e9255c53ab28f23358bb893cbaLuiz Augusto von Dentz		}
551d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz		break;
5529d7109c994bec237bdf1fff158d9400cbfb1b5c9Luiz Augusto von Dentz	case '3':
5539d7109c994bec237bdf1fff158d9400cbfb1b5c9Luiz Augusto von Dentz		if (find_vc_with_status(CALL_STATUS_HELD) ||
5549d7109c994bec237bdf1fff158d9400cbfb1b5c9Luiz Augusto von Dentz				find_vc_with_status(CALL_STATUS_WAITING))
5559d7109c994bec237bdf1fff158d9400cbfb1b5c9Luiz Augusto von Dentz			err = create_conference();
5569d7109c994bec237bdf1fff158d9400cbfb1b5c9Luiz Augusto von Dentz		break;
5579d7109c994bec237bdf1fff158d9400cbfb1b5c9Luiz Augusto von Dentz	case '4':
5589d7109c994bec237bdf1fff158d9400cbfb1b5c9Luiz Augusto von Dentz		err = call_transfer();
5599d7109c994bec237bdf1fff158d9400cbfb1b5c9Luiz Augusto von Dentz		break;
560d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	default:
561d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz		DBG("Unknown call hold request");
562d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz		break;
563d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	}
564d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz
565d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	if (err)
566d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz		telephony_call_hold_rsp(telephony_device,
567d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz					CME_ERROR_AG_FAILURE);
568d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	else
569d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz		telephony_call_hold_rsp(telephony_device, CME_ERROR_NONE);
570a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
571a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
572a34c155f55270b917795d003be24488f53d9b711Forrest Zhaovoid telephony_nr_and_ec_req(void *telephony_device, gboolean enable)
573a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
5748e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan	DBG("telephony-ofono: got %s NR and EC request",
575a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			enable ? "enable" : "disable");
576a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
577a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	telephony_nr_and_ec_rsp(telephony_device, CME_ERROR_NONE);
578a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
579a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
580a34c155f55270b917795d003be24488f53d9b711Forrest Zhaovoid telephony_key_press_req(void *telephony_device, const char *keys)
581a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
582e3a27197820b503f16f39bf4071b65a4e5123b42Luiz Augusto von Dentz	struct voice_call *active, *incoming;
583d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	int err;
584d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz
5858e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan	DBG("telephony-ofono: got key press request for %s", keys);
586d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz
587e3a27197820b503f16f39bf4071b65a4e5123b42Luiz Augusto von Dentz	incoming = find_vc_with_status(CALL_STATUS_INCOMING);
588d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz
589d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	active = find_vc_with_status(CALL_STATUS_ACTIVE);
590d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz
591e3a27197820b503f16f39bf4071b65a4e5123b42Luiz Augusto von Dentz	if (incoming)
592e3a27197820b503f16f39bf4071b65a4e5123b42Luiz Augusto von Dentz		err = answer_call(incoming);
593d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	else if (active)
594d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz		err = release_call(active);
595d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	else
596d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz		err = 0;
597d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz
598d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	if (err < 0)
599d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz		telephony_key_press_rsp(telephony_device,
600d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz							CME_ERROR_AG_FAILURE);
601d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	else
602d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz		telephony_key_press_rsp(telephony_device, CME_ERROR_NONE);
603a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
604a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
6050218ab79ea881c593111b7165cd57337c711d2ecPeter Zotovvoid telephony_voice_dial_req(void *telephony_device, gboolean enable)
6060218ab79ea881c593111b7165cd57337c711d2ecPeter Zotov{
6078e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan	DBG("telephony-ofono: got %s voice dial request",
6080218ab79ea881c593111b7165cd57337c711d2ecPeter Zotov			enable ? "enable" : "disable");
6090218ab79ea881c593111b7165cd57337c711d2ecPeter Zotov
6100218ab79ea881c593111b7165cd57337c711d2ecPeter Zotov	telephony_voice_dial_rsp(telephony_device, CME_ERROR_NOT_SUPPORTED);
6110218ab79ea881c593111b7165cd57337c711d2ecPeter Zotov}
6120218ab79ea881c593111b7165cd57337c711d2ecPeter Zotov
613a34c155f55270b917795d003be24488f53d9b711Forrest Zhaostatic gboolean iter_get_basic_args(DBusMessageIter *iter,
614a34c155f55270b917795d003be24488f53d9b711Forrest Zhao					int first_arg_type, ...)
615a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
616a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	int type;
617a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	va_list ap;
618a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
619a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	va_start(ap, first_arg_type);
620a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
621a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	for (type = first_arg_type; type != DBUS_TYPE_INVALID;
622a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		type = va_arg(ap, int)) {
623a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		void *value = va_arg(ap, void *);
624a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		int real_type = dbus_message_iter_get_arg_type(iter);
625a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
626a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		if (real_type != type) {
627a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			error("iter_get_basic_args: expected %c but got %c",
628a34c155f55270b917795d003be24488f53d9b711Forrest Zhao				(char) type, (char) real_type);
629a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			break;
630a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		}
631a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
632a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		dbus_message_iter_get_basic(iter, value);
633a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		dbus_message_iter_next(iter);
634a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	}
635a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
636a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	va_end(ap);
637a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
638a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	return type == DBUS_TYPE_INVALID ? TRUE : FALSE;
639a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
640a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
6419fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentzstatic void call_free(struct voice_call *vc)
6429fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz{
6439fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	DBG("%s", vc->obj_path);
6449fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
64503085e6ba3e636e35e0395b694077635a9b0f563Luiz Augusto von Dentz	if (vc->status == CALL_STATUS_ACTIVE)
64603085e6ba3e636e35e0395b694077635a9b0f563Luiz Augusto von Dentz		telephony_update_indicator(ofono_indicators, "call",
64703085e6ba3e636e35e0395b694077635a9b0f563Luiz Augusto von Dentz							EV_CALL_INACTIVE);
64803085e6ba3e636e35e0395b694077635a9b0f563Luiz Augusto von Dentz	else
64903085e6ba3e636e35e0395b694077635a9b0f563Luiz Augusto von Dentz		telephony_update_indicator(ofono_indicators, "callsetup",
65003085e6ba3e636e35e0395b694077635a9b0f563Luiz Augusto von Dentz							EV_CALLSETUP_INACTIVE);
65103085e6ba3e636e35e0395b694077635a9b0f563Luiz Augusto von Dentz
65203085e6ba3e636e35e0395b694077635a9b0f563Luiz Augusto von Dentz	if (vc->status == CALL_STATUS_INCOMING)
65303085e6ba3e636e35e0395b694077635a9b0f563Luiz Augusto von Dentz		telephony_calling_stopped_ind();
65403085e6ba3e636e35e0395b694077635a9b0f563Luiz Augusto von Dentz
6559fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	g_dbus_remove_watch(connection, vc->watch);
6569fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	g_free(vc->obj_path);
6579fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	g_free(vc->number);
6589fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	g_free(vc);
6599fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz}
6609fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
6619fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentzstatic gboolean handle_vc_property_changed(DBusConnection *conn,
6629fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz					DBusMessage *msg, void *data)
6639fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz{
6649fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	struct voice_call *vc = data;
6659fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	const char *obj_path = dbus_message_get_path(msg);
6669fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	DBusMessageIter iter, sub;
6679fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	const char *property, *state;
6689fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
6699fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	DBG("path %s", obj_path);
6709fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
6719fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	dbus_message_iter_init(msg, &iter);
6729fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
6739fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING) {
6749fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		error("Unexpected signature in vc PropertyChanged signal");
6759fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		return TRUE;
6769fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	}
6779fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
6789fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	dbus_message_iter_get_basic(&iter, &property);
6799fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	DBG("property %s", property);
6809fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
6819fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	dbus_message_iter_next(&iter);
6829fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	dbus_message_iter_recurse(&iter, &sub);
6839fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	if (g_str_equal(property, "State")) {
6849fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		dbus_message_iter_get_basic(&sub, &state);
6859fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		DBG("State %s", state);
6869fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		if (g_str_equal(state, "disconnected")) {
6879fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz			calls = g_slist_remove(calls, vc);
6889fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz			call_free(vc);
6899fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		} else if (g_str_equal(state, "active")) {
6909fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz			telephony_update_indicator(ofono_indicators,
6919fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz							"call", EV_CALL_ACTIVE);
6929fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz			telephony_update_indicator(ofono_indicators,
6939fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz							"callsetup",
6949fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz							EV_CALLSETUP_INACTIVE);
6959fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz			if (vc->status == CALL_STATUS_INCOMING)
6969fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz				telephony_calling_stopped_ind();
6979fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz			vc->status = CALL_STATUS_ACTIVE;
6989fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		} else if (g_str_equal(state, "alerting")) {
6999fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz			telephony_update_indicator(ofono_indicators,
7009fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz					"callsetup", EV_CALLSETUP_ALERTING);
7019fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz			vc->status = CALL_STATUS_ALERTING;
7029fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz			vc->originating = TRUE;
7039fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		} else if (g_str_equal(state, "incoming")) {
7049fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz			/* state change from waiting to incoming */
7059fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz			telephony_update_indicator(ofono_indicators,
7069fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz					"callsetup", EV_CALLSETUP_INCOMING);
7079fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz			telephony_incoming_call_ind(vc->number,
7089fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz						NUMBER_TYPE_TELEPHONY);
7099fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz			vc->status = CALL_STATUS_INCOMING;
7109fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz			vc->originating = FALSE;
711d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz		} else if (g_str_equal(state, "held")) {
712d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz			vc->status = CALL_STATUS_HELD;
713d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz			if (find_vc_without_status(CALL_STATUS_HELD))
714d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz				telephony_update_indicator(ofono_indicators,
715d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz							"callheld",
716d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz							EV_CALLHELD_MULTIPLE);
717d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz			else
718d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz				telephony_update_indicator(ofono_indicators,
719d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz							"callheld",
720d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz							EV_CALLHELD_ON_HOLD);
7219fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		}
7229d7109c994bec237bdf1fff158d9400cbfb1b5c9Luiz Augusto von Dentz	} else if (g_str_equal(property, "Multiparty")) {
7239d7109c994bec237bdf1fff158d9400cbfb1b5c9Luiz Augusto von Dentz		dbus_bool_t multiparty;
7249d7109c994bec237bdf1fff158d9400cbfb1b5c9Luiz Augusto von Dentz
7259d7109c994bec237bdf1fff158d9400cbfb1b5c9Luiz Augusto von Dentz		dbus_message_iter_get_basic(&sub, &multiparty);
7269d7109c994bec237bdf1fff158d9400cbfb1b5c9Luiz Augusto von Dentz		DBG("Multiparty %s", multiparty ? "True" : "False");
7279d7109c994bec237bdf1fff158d9400cbfb1b5c9Luiz Augusto von Dentz		vc->conference = multiparty;
7289fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	}
7299fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
7309fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	return TRUE;
7319fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz}
7329fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
7339fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentzstatic struct voice_call *call_new(const char *path, DBusMessageIter *properties)
7349fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz{
7359fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	struct voice_call *vc;
7369fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
7379fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	DBG("%s", path);
7389fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
7399fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	vc = g_new0(struct voice_call, 1);
7409fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	vc->obj_path = g_strdup(path);
7419fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	vc->watch = g_dbus_add_signal_watch(connection, NULL, path,
7429fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz					OFONO_VC_INTERFACE, "PropertyChanged",
7439fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz					handle_vc_property_changed, vc, NULL);
7449fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
7459fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	while (dbus_message_iter_get_arg_type(properties)
7469fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz						== DBUS_TYPE_DICT_ENTRY) {
7479fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		DBusMessageIter entry, value;
7489fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		const char *property, *cli, *state;
7499d7109c994bec237bdf1fff158d9400cbfb1b5c9Luiz Augusto von Dentz		dbus_bool_t multiparty;
7509fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
7519fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		dbus_message_iter_recurse(properties, &entry);
7529fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		dbus_message_iter_get_basic(&entry, &property);
7539fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
7549fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		dbus_message_iter_next(&entry);
7559fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		dbus_message_iter_recurse(&entry, &value);
7569fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
7579fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		if (g_str_equal(property, "LineIdentification")) {
7589fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz			dbus_message_iter_get_basic(&value, &cli);
7599fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz			DBG("cli %s", cli);
7609fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz			vc->number = g_strdup(cli);
7619fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		} else if (g_str_equal(property, "State")) {
7629fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz			dbus_message_iter_get_basic(&value, &state);
7639fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz			DBG("state %s", state);
7649fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz			if (g_str_equal(state, "incoming"))
7659fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz				vc->status = CALL_STATUS_INCOMING;
7669fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz			else if (g_str_equal(state, "dialing"))
7679fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz				vc->status = CALL_STATUS_DIALING;
7689fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz			else if (g_str_equal(state, "alerting"))
7699fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz				vc->status = CALL_STATUS_ALERTING;
7709fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz			else if (g_str_equal(state, "waiting"))
7719fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz				vc->status = CALL_STATUS_WAITING;
772d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz			else if (g_str_equal(state, "held"))
773d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz				vc->status = CALL_STATUS_HELD;
7749d7109c994bec237bdf1fff158d9400cbfb1b5c9Luiz Augusto von Dentz		} else if (g_str_equal(property, "Multiparty")) {
7759d7109c994bec237bdf1fff158d9400cbfb1b5c9Luiz Augusto von Dentz			dbus_message_iter_get_basic(&value, &multiparty);
7769d7109c994bec237bdf1fff158d9400cbfb1b5c9Luiz Augusto von Dentz			DBG("Multipary %s", multiparty ? "True" : "False");
7779d7109c994bec237bdf1fff158d9400cbfb1b5c9Luiz Augusto von Dentz			vc->conference = multiparty;
7789fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		}
7799fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
7809fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		dbus_message_iter_next(properties);
7819fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	}
7829fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
7839fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	switch (vc->status) {
7849fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	case CALL_STATUS_INCOMING:
7859fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		DBG("CALL_STATUS_INCOMING");
7869fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		vc->originating = FALSE;
7879fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		telephony_update_indicator(ofono_indicators, "callsetup",
7889fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz					EV_CALLSETUP_INCOMING);
7899fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		telephony_incoming_call_ind(vc->number, NUMBER_TYPE_TELEPHONY);
7909fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		break;
7919fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	case CALL_STATUS_DIALING:
7929fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		DBG("CALL_STATUS_DIALING");
7939fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		vc->originating = TRUE;
7949fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		g_free(last_dialed_number);
7959fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		last_dialed_number = g_strdup(vc->number);
7969fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		telephony_update_indicator(ofono_indicators, "callsetup",
7979fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz					EV_CALLSETUP_OUTGOING);
7989fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		break;
7999fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	case CALL_STATUS_ALERTING:
8009fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		DBG("CALL_STATUS_ALERTING");
8019fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		vc->originating = TRUE;
8029fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		g_free(last_dialed_number);
8039fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		last_dialed_number = g_strdup(vc->number);
8049fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		telephony_update_indicator(ofono_indicators, "callsetup",
8059fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz					EV_CALLSETUP_ALERTING);
8069fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		break;
8079fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	case CALL_STATUS_WAITING:
8089fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		DBG("CALL_STATUS_WAITING");
8099fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		vc->originating = FALSE;
8109fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		telephony_update_indicator(ofono_indicators, "callsetup",
8119fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz					EV_CALLSETUP_INCOMING);
8129fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		telephony_call_waiting_ind(vc->number, NUMBER_TYPE_TELEPHONY);
8139fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		break;
8149fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	}
8159fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
8169fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	return vc;
8179fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz}
8189fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
819c49dc8c7c815191b5825896f827cac2e2ff395ffLuiz Augusto von Dentzstatic void remove_pending(DBusPendingCall *call)
820c49dc8c7c815191b5825896f827cac2e2ff395ffLuiz Augusto von Dentz{
821c49dc8c7c815191b5825896f827cac2e2ff395ffLuiz Augusto von Dentz	pending = g_slist_remove(pending, call);
822c49dc8c7c815191b5825896f827cac2e2ff395ffLuiz Augusto von Dentz	dbus_pending_call_unref(call);
823c49dc8c7c815191b5825896f827cac2e2ff395ffLuiz Augusto von Dentz}
824c49dc8c7c815191b5825896f827cac2e2ff395ffLuiz Augusto von Dentz
8259fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentzstatic void call_added(const char *path, DBusMessageIter *properties)
8269fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz{
8279fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	struct voice_call *vc;
8289fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
8299fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	DBG("%s", path);
8309fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
8319fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	vc = find_vc(path);
8329fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	if (vc)
8339fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		return;
8349fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
8359fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	vc = call_new(path, properties);
8369fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	calls = g_slist_prepend(calls, vc);
8379fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz}
8389fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
8399fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentzstatic void get_calls_reply(DBusPendingCall *call, void *user_data)
8409fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz{
8419fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	DBusError err;
8429fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	DBusMessage *reply;
8439fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	DBusMessageIter iter, entry;
8449fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
8459fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	DBG("");
8469fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	reply = dbus_pending_call_steal_reply(call);
8479fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
8489fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	dbus_error_init(&err);
8499fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	if (dbus_set_error_from_message(&err, reply)) {
8509fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		error("ofono replied with an error: %s, %s",
8519fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz				err.name, err.message);
8529fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		dbus_error_free(&err);
8539fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		goto done;
8549fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	}
8559fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
8569fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	dbus_message_iter_init(reply, &iter);
8579fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
8589fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY) {
8599fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		error("Unexpected signature");
8609fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		goto done;
8619fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	}
8629fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
8639fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	dbus_message_iter_recurse(&iter, &entry);
8649fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
8659fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	while (dbus_message_iter_get_arg_type(&entry)
8669fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz						== DBUS_TYPE_STRUCT) {
8679fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		const char *path;
8689fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		DBusMessageIter value, properties;
8699fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
8709fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		dbus_message_iter_recurse(&entry, &value);
8719fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		dbus_message_iter_get_basic(&value, &path);
8729fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
8739fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		dbus_message_iter_next(&value);
8749fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		dbus_message_iter_recurse(&value, &properties);
8759fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
8769fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		call_added(path, &properties);
8779fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
8789fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		dbus_message_iter_next(&entry);
8799fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	}
8809fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
8819fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentzdone:
8829fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	dbus_message_unref(reply);
883c49dc8c7c815191b5825896f827cac2e2ff395ffLuiz Augusto von Dentz	remove_pending(call);
8849fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz}
8859fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
886e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentzstatic void handle_network_property(const char *property, DBusMessageIter *variant)
887a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
88883003660808c30390f21c569a5ba7dbdd8344a41Claudio Takahasi	const char *status, *operator;
889a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	unsigned int signals_bar;
890a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
891a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	if (g_str_equal(property, "Status")) {
892e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz		dbus_message_iter_get_basic(variant, &status);
8938e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan		DBG("Status is %s", status);
894a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		if (g_str_equal(status, "registered")) {
895a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			net.status = NETWORK_REG_STATUS_HOME;
896a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			telephony_update_indicator(ofono_indicators,
897a34c155f55270b917795d003be24488f53d9b711Forrest Zhao						"roam", EV_ROAM_INACTIVE);
898a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			telephony_update_indicator(ofono_indicators,
899a34c155f55270b917795d003be24488f53d9b711Forrest Zhao						"service", EV_SERVICE_PRESENT);
900a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		} else if (g_str_equal(status, "roaming")) {
901a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			net.status = NETWORK_REG_STATUS_ROAM;
902a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			telephony_update_indicator(ofono_indicators,
903a34c155f55270b917795d003be24488f53d9b711Forrest Zhao						"roam", EV_ROAM_ACTIVE);
904a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			telephony_update_indicator(ofono_indicators,
905a34c155f55270b917795d003be24488f53d9b711Forrest Zhao						"service", EV_SERVICE_PRESENT);
906a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		} else {
907a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			net.status = NETWORK_REG_STATUS_NOSERV;
908a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			telephony_update_indicator(ofono_indicators,
909a34c155f55270b917795d003be24488f53d9b711Forrest Zhao						"roam", EV_ROAM_INACTIVE);
910a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			telephony_update_indicator(ofono_indicators,
911a34c155f55270b917795d003be24488f53d9b711Forrest Zhao						"service", EV_SERVICE_NONE);
912a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		}
913e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	} else if (g_str_equal(property, "Name")) {
914e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz		dbus_message_iter_get_basic(variant, &operator);
9158e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan		DBG("Operator is %s", operator);
916a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		g_free(net.operator_name);
917a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		net.operator_name = g_strdup(operator);
918a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	} else if (g_str_equal(property, "SignalStrength")) {
919e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz		dbus_message_iter_get_basic(variant, &signals_bar);
9208e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan		DBG("SignalStrength is %d", signals_bar);
921a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		net.signals_bar = signals_bar;
922a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		telephony_update_indicator(ofono_indicators, "signal",
923a34c155f55270b917795d003be24488f53d9b711Forrest Zhao						(signals_bar + 20) / 21);
924a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	}
925a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
926a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
927e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentzstatic int parse_network_properties(DBusMessageIter *properties)
928a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
929a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	uint32_t features = AG_FEATURE_EC_ANDOR_NR |
9305e072a21aa4d68fdcfa605ef31427411c643e8bdLuiz Augusto von Dentz				AG_FEATURE_INBAND_RINGTONE |
931a34c155f55270b917795d003be24488f53d9b711Forrest Zhao				AG_FEATURE_REJECT_A_CALL |
932a34c155f55270b917795d003be24488f53d9b711Forrest Zhao				AG_FEATURE_ENHANCED_CALL_STATUS |
933d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz				AG_FEATURE_ENHANCED_CALL_CONTROL |
9349d7109c994bec237bdf1fff158d9400cbfb1b5c9Luiz Augusto von Dentz				AG_FEATURE_EXTENDED_ERROR_RESULT_CODES |
9359d7109c994bec237bdf1fff158d9400cbfb1b5c9Luiz Augusto von Dentz				AG_FEATURE_THREE_WAY_CALLING;
936d8fbf5b42f6a7fff8326b1a69d267640db45b367Luiz Augusto von Dentz	int i;
937d8fbf5b42f6a7fff8326b1a69d267640db45b367Luiz Augusto von Dentz
938d8fbf5b42f6a7fff8326b1a69d267640db45b367Luiz Augusto von Dentz	/* Reset indicators */
939d8fbf5b42f6a7fff8326b1a69d267640db45b367Luiz Augusto von Dentz	for (i = 0; ofono_indicators[i].desc != NULL; i++) {
940d8fbf5b42f6a7fff8326b1a69d267640db45b367Luiz Augusto von Dentz		if (g_str_equal(ofono_indicators[i].desc, "battchg"))
941d8fbf5b42f6a7fff8326b1a69d267640db45b367Luiz Augusto von Dentz			ofono_indicators[i].val = 5;
942d8fbf5b42f6a7fff8326b1a69d267640db45b367Luiz Augusto von Dentz		else
943d8fbf5b42f6a7fff8326b1a69d267640db45b367Luiz Augusto von Dentz			ofono_indicators[i].val = 0;
944d8fbf5b42f6a7fff8326b1a69d267640db45b367Luiz Augusto von Dentz	}
945a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
946e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	while (dbus_message_iter_get_arg_type(properties)
947e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz						== DBUS_TYPE_DICT_ENTRY) {
948e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz		const char *key;
949e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz		DBusMessageIter value, entry;
950e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz
951e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz		dbus_message_iter_recurse(properties, &entry);
952e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz		dbus_message_iter_get_basic(&entry, &key);
953e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz
954e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz		dbus_message_iter_next(&entry);
955e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz		dbus_message_iter_recurse(&entry, &value);
956e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz
957e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz		handle_network_property(key, &value);
958e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz
959e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz		dbus_message_iter_next(properties);
960e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	}
961e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz
962e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	telephony_ready_ind(features, ofono_indicators, BTRH_NOT_SUPPORTED,
963e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz								chld_str);
964e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz
965e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	return 0;
966e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz}
967e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz
968e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentzstatic void get_properties_reply(DBusPendingCall *call, void *user_data)
969e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz{
970e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	DBusError err;
971e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	DBusMessage *reply;
972e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	DBusMessageIter iter, properties;
973e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	int ret = 0;
974e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz
975e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	DBG("");
976a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	reply = dbus_pending_call_steal_reply(call);
977a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
978a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	dbus_error_init(&err);
979a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	if (dbus_set_error_from_message(&err, reply)) {
980a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		error("ofono replied with an error: %s, %s",
981a34c155f55270b917795d003be24488f53d9b711Forrest Zhao				err.name, err.message);
982a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		dbus_error_free(&err);
983a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		goto done;
984a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	}
985a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
986a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	dbus_message_iter_init(reply, &iter);
987a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
988a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY) {
989e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz		error("Unexpected signature");
990a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		goto done;
991a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	}
992a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
993e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	dbus_message_iter_recurse(&iter, &properties);
994a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
995e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	ret = parse_network_properties(&properties);
9969fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	if (ret < 0) {
997e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz		error("Unable to parse %s.GetProperty reply",
998e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz						OFONO_NETWORKREG_INTERFACE);
9999fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		goto done;
10009fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	}
10019fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
10029fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	ret = send_method_call(OFONO_BUS_NAME, modem_obj_path,
10039fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz				OFONO_VCMANAGER_INTERFACE, "GetCalls",
10049fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz				get_calls_reply, NULL, DBUS_TYPE_INVALID);
10059fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	if (ret < 0)
10069fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		error("Unable to send %s.GetCalls",
10079fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz						OFONO_VCMANAGER_INTERFACE);
1008a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1009a34c155f55270b917795d003be24488f53d9b711Forrest Zhaodone:
1010a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	dbus_message_unref(reply);
1011c49dc8c7c815191b5825896f827cac2e2ff395ffLuiz Augusto von Dentz	remove_pending(call);
1012a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
1013a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1014806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentzstatic void network_found(const char *path)
1015a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
1016e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	int ret;
1017c5321032b046c39477ab99a05e933b13d0b67a04Forrest Zhao
1018e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	DBG("%s", path);
1019e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz
1020e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	modem_obj_path = g_strdup(path);
1021e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz
1022e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	ret = send_method_call(OFONO_BUS_NAME, path,
1023e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz				OFONO_NETWORKREG_INTERFACE, "GetProperties",
1024e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz				get_properties_reply, NULL, DBUS_TYPE_INVALID);
1025e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	if (ret < 0)
1026e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz		error("Unable to send %s.GetProperties",
1027e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz						OFONO_NETWORKREG_INTERFACE);
1028a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
1029a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1030806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentzstatic void modem_removed(const char *path)
1031806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz{
1032806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	if (g_strcmp0(modem_obj_path, path) != 0)
1033806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		return;
1034806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
1035806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	DBG("%s", path);
1036806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
1037806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	g_slist_foreach(calls, (GFunc) call_free, NULL);
1038806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	g_slist_free(calls);
1039806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	calls = NULL;
1040806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
1041806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	g_free(net.operator_name);
1042806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	net.operator_name = NULL;
1043de8eb4773a1ac878b1b9b8e7306a3c1f4cfe43ebLuiz Augusto von Dentz	net.status = NETWORK_REG_STATUS_NOSERV;
1044de8eb4773a1ac878b1b9b8e7306a3c1f4cfe43ebLuiz Augusto von Dentz	net.signals_bar = 0;
1045806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
1046806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	g_free(modem_obj_path);
1047806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	modem_obj_path = NULL;
1048806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz}
1049806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
1050806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentzstatic void parse_modem_interfaces(const char *path, DBusMessageIter *ifaces)
1051806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz{
1052806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	DBG("%s", path);
1053806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
1054806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	while (dbus_message_iter_get_arg_type(ifaces) == DBUS_TYPE_STRING) {
1055806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		const char *iface;
1056806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
1057806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		dbus_message_iter_get_basic(ifaces, &iface);
1058806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
1059806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		if (g_str_equal(iface, OFONO_NETWORKREG_INTERFACE)) {
1060806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz			network_found(path);
1061806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz			return;
1062806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		}
1063806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
1064806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		dbus_message_iter_next(ifaces);
1065806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	}
1066806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
1067806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	modem_removed(path);
1068806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz}
1069806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
1070806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentzstatic void modem_added(const char *path, DBusMessageIter *properties)
1071806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz{
1072806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	if (modem_obj_path != NULL) {
1073806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		DBG("Ignoring, modem already exist");
1074806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		return;
1075806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	}
1076806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
1077806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	DBG("%s", path);
1078806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
1079806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	while (dbus_message_iter_get_arg_type(properties)
1080806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz						== DBUS_TYPE_DICT_ENTRY) {
1081806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		const char *key;
1082806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		DBusMessageIter interfaces, value, entry;
1083806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
1084806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		dbus_message_iter_recurse(properties, &entry);
1085806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		dbus_message_iter_get_basic(&entry, &key);
1086806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
1087806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		dbus_message_iter_next(&entry);
1088806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		dbus_message_iter_recurse(&entry, &value);
1089806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
1090806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		if (strcasecmp(key, "Interfaces") != 0)
1091806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz			goto next;
1092806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
1093806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		if (dbus_message_iter_get_arg_type(&value)
1094806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz							!= DBUS_TYPE_ARRAY) {
1095806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz			error("Invalid Signature");
1096806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz			return;
1097806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		}
1098806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
1099806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		dbus_message_iter_recurse(&value, &interfaces);
1100806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
1101806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		parse_modem_interfaces(path, &interfaces);
1102806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
1103806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		if (modem_obj_path != NULL)
1104806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz			return;
1105806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
1106806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	next:
1107806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		dbus_message_iter_next(properties);
1108806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	}
1109806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz}
1110806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
1111e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentzstatic void get_modems_reply(DBusPendingCall *call, void *user_data)
1112a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
1113a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	DBusError err;
1114a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	DBusMessage *reply;
1115e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	DBusMessageIter iter, entry;
1116a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1117941eb9973274a7b20411d3e70815c4e78b282ccdAnderson Lizardo	DBG("");
1118a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	reply = dbus_pending_call_steal_reply(call);
1119a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1120a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	dbus_error_init(&err);
1121a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	if (dbus_set_error_from_message(&err, reply)) {
1122a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		error("ofono replied with an error: %s, %s",
1123a34c155f55270b917795d003be24488f53d9b711Forrest Zhao				err.name, err.message);
1124a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		dbus_error_free(&err);
1125a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		goto done;
1126a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	}
1127a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1128806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	/* Skip modem selection if a modem already exist */
1129806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	if (modem_obj_path != NULL)
1130806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		goto done;
1131806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
1132a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	dbus_message_iter_init(reply, &iter);
1133a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1134a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY) {
1135e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz		error("Unexpected signature");
1136a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		goto done;
1137a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	}
1138a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1139e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	dbus_message_iter_recurse(&iter, &entry);
1140a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1141806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	while (dbus_message_iter_get_arg_type(&entry)
1142806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz						== DBUS_TYPE_STRUCT) {
1143806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		const char *path;
1144806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		DBusMessageIter item, properties;
1145806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
1146806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		dbus_message_iter_recurse(&entry, &item);
1147806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		dbus_message_iter_get_basic(&item, &path);
1148806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
1149806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		dbus_message_iter_next(&item);
1150806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		dbus_message_iter_recurse(&item, &properties);
1151a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1152806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		modem_added(path, &properties);
1153806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		if (modem_obj_path != NULL)
1154806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz			break;
1155a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1156806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		dbus_message_iter_next(&entry);
1157806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	}
1158a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1159a34c155f55270b917795d003be24488f53d9b711Forrest Zhaodone:
1160a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	dbus_message_unref(reply);
1161c49dc8c7c815191b5825896f827cac2e2ff395ffLuiz Augusto von Dentz	remove_pending(call);
1162a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
1163a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1164e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentzstatic gboolean handle_network_property_changed(DBusConnection *conn,
11658309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz						DBusMessage *msg, void *data)
1166a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
1167e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	DBusMessageIter iter, variant;
1168a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	const char *property;
1169a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1170a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	dbus_message_iter_init(msg, &iter);
1171a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1172a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING) {
1173a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		error("Unexpected signature in networkregistration"
1174a34c155f55270b917795d003be24488f53d9b711Forrest Zhao					" PropertyChanged signal");
11758309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz		return TRUE;
1176a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	}
1177a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	dbus_message_iter_get_basic(&iter, &property);
11788e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan	DBG("in handle_registration_property_changed(),"
1179a34c155f55270b917795d003be24488f53d9b711Forrest Zhao					" the property is %s", property);
1180a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1181a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	dbus_message_iter_next(&iter);
1182e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	dbus_message_iter_recurse(&iter, &variant);
1183a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1184e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	handle_network_property(property, &variant);
11858309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz
11868309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	return TRUE;
1187a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
1188a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1189806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentzstatic void handle_modem_property(const char *path, const char *property,
1190806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz						DBusMessageIter *variant)
1191806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz{
1192806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	DBG("%s", property);
1193806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
1194806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	if (g_str_equal(property, "Interfaces")) {
1195806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		DBusMessageIter interfaces;
1196806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
1197806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		if (dbus_message_iter_get_arg_type(variant)
1198806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz							!= DBUS_TYPE_ARRAY) {
1199806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz			error("Invalid signature");
1200806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz			return;
1201806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		}
1202806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
1203806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		dbus_message_iter_recurse(variant, &interfaces);
1204806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		parse_modem_interfaces(path, &interfaces);
1205806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	}
1206806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz}
1207806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
1208806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentzstatic gboolean handle_modem_property_changed(DBusConnection *conn,
1209806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz						DBusMessage *msg, void *data)
1210806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz{
1211806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	DBusMessageIter iter, variant;
1212806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	const char *property, *path;
1213806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
1214806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	path = dbus_message_get_path(msg);
1215806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
1216806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	/* Ignore if modem already exist and paths doesn't match */
1217806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	if (modem_obj_path != NULL &&
1218806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz				g_str_equal(path, modem_obj_path) == FALSE)
1219806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		return TRUE;
1220806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
1221806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	dbus_message_iter_init(msg, &iter);
1222806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
1223806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING) {
1224806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		error("Unexpected signature in %s.%s PropertyChanged signal",
1225806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz					dbus_message_get_interface(msg),
1226806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz					dbus_message_get_member(msg));
1227806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		return TRUE;
1228806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	}
1229806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
1230806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	dbus_message_iter_get_basic(&iter, &property);
1231806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
1232806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	dbus_message_iter_next(&iter);
1233806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	dbus_message_iter_recurse(&iter, &variant);
1234806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
1235806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	handle_modem_property(path, property, &variant);
1236806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
1237806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	return TRUE;
1238806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz}
1239806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
12409fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentzstatic gboolean handle_vcmanager_call_added(DBusConnection *conn,
12419fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz						DBusMessage *msg, void *data)
1242a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
12439fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	DBusMessageIter iter, properties;
12449fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	const char *path = dbus_message_get_path(msg);
1245a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
12469fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	/* Ignore call if modem path doesn't math */
12479fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	if (g_strcmp0(modem_obj_path, path) != 0)
12489fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		return TRUE;
1249a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
12509fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	dbus_message_iter_init(msg, &iter);
1251a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
12529fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	if (dbus_message_iter_get_arg_type(&iter)
12539fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz						!= DBUS_TYPE_OBJECT_PATH) {
12549fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		error("Unexpected signature in %s.%s signal",
12559fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz					dbus_message_get_interface(msg),
12569fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz					dbus_message_get_member(msg));
12579fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		return TRUE;
1258a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	}
1259a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
12609fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	dbus_message_iter_get_basic(&iter, &path);
12619fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	dbus_message_iter_next(&iter);
12629fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	dbus_message_iter_recurse(&iter, &properties);
1263a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
12649fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	call_added(path, &properties);
1265a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
12669fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	return TRUE;
1267a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
1268a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
12699fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentzstatic void call_removed(const char *path)
1270a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
12719fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	struct voice_call *vc;
1272a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
12739fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	DBG("%s", path);
1274a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
12759fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	vc = find_vc(path);
12769fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	if (vc == NULL)
12779fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		return;
12788309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz
12799fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	calls = g_slist_remove(calls, vc);
12809fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	call_free(vc);
12818309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz}
12828309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz
12839fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentzstatic gboolean handle_vcmanager_call_removed(DBusConnection *conn,
12848309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz						DBusMessage *msg, void *data)
12858309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz{
12869fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	const char *path = dbus_message_get_path(msg);
12878309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz
12889fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	/* Ignore call if modem path doesn't math */
12899fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	if (g_strcmp0(modem_obj_path, path) != 0)
12908309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz		return TRUE;
12918309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz
12929fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	if (!dbus_message_get_args(msg, NULL,
12939fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz				DBUS_TYPE_OBJECT_PATH, &path,
12949fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz				DBUS_TYPE_INVALID)) {
12959fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		error("Unexpected signature in %s.%s signal",
12969fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz					dbus_message_get_interface(msg),
12979fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz					dbus_message_get_member(msg));
12988309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz		return TRUE;
12998309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	}
13008309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz
13019fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	call_removed(path);
13028309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz
13038309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	return TRUE;
1304a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
1305a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1306e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentzstatic gboolean handle_manager_modem_added(DBusConnection *conn,
1307e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz						DBusMessage *msg, void *data)
1308e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz{
1309e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	DBusMessageIter iter, properties;
1310e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	const char *path;
1311e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz
1312e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	if (modem_obj_path != NULL)
1313e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz		return TRUE;
1314e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz
1315e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	dbus_message_iter_init(msg, &iter);
1316e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz
1317e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	if (dbus_message_iter_get_arg_type(&iter)
1318e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz						!= DBUS_TYPE_OBJECT_PATH) {
1319e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz		error("Unexpected signature in %s.%s signal",
1320e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz					dbus_message_get_interface(msg),
1321e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz					dbus_message_get_member(msg));
1322e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz		return TRUE;
1323e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	}
1324e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz
1325e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	dbus_message_iter_get_basic(&iter, &path);
1326806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	dbus_message_iter_next(&iter);
1327e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	dbus_message_iter_recurse(&iter, &properties);
1328e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz
1329806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	modem_added(path, &properties);
1330e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz
1331e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	return TRUE;
1332e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz}
1333e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz
1334e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentzstatic gboolean handle_manager_modem_removed(DBusConnection *conn,
1335e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz						DBusMessage *msg, void *data)
1336e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz{
1337e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	const char *path;
1338e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz
1339e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	if (!dbus_message_get_args(msg, NULL,
1340e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz				DBUS_TYPE_OBJECT_PATH, &path,
1341e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz				DBUS_TYPE_INVALID)) {
1342e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz		error("Unexpected signature in %s.%s signal",
1343e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz					dbus_message_get_interface(msg),
1344e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz					dbus_message_get_member(msg));
1345e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz		return TRUE;
1346e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	}
1347e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz
1348e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	modem_removed(path);
1349e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz
1350e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	return TRUE;
1351e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz}
1352e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz
1353a34c155f55270b917795d003be24488f53d9b711Forrest Zhaostatic void hal_battery_level_reply(DBusPendingCall *call, void *user_data)
1354a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
1355a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	DBusMessage *reply;
1356a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	DBusError err;
1357a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	dbus_int32_t level;
1358a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	int *value = user_data;
1359a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1360a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	reply = dbus_pending_call_steal_reply(call);
1361a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1362a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	dbus_error_init(&err);
1363a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	if (dbus_set_error_from_message(&err, reply)) {
1364a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		error("hald replied with an error: %s, %s",
1365a34c155f55270b917795d003be24488f53d9b711Forrest Zhao				err.name, err.message);
1366a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		dbus_error_free(&err);
1367a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		goto done;
1368a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	}
1369a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1370463763c080cd72ecd727a218dd68f7c0ba95bc9eLuiz Augusto von Dentz	dbus_error_init(&err);
1371463763c080cd72ecd727a218dd68f7c0ba95bc9eLuiz Augusto von Dentz	if (dbus_message_get_args(reply, &err,
1372a34c155f55270b917795d003be24488f53d9b711Forrest Zhao				DBUS_TYPE_INT32, &level,
1373463763c080cd72ecd727a218dd68f7c0ba95bc9eLuiz Augusto von Dentz				DBUS_TYPE_INVALID) == FALSE) {
1374463763c080cd72ecd727a218dd68f7c0ba95bc9eLuiz Augusto von Dentz		error("Unable to parse GetPropertyInteger reply: %s, %s",
1375463763c080cd72ecd727a218dd68f7c0ba95bc9eLuiz Augusto von Dentz							err.name, err.message);
1376463763c080cd72ecd727a218dd68f7c0ba95bc9eLuiz Augusto von Dentz		dbus_error_free(&err);
1377463763c080cd72ecd727a218dd68f7c0ba95bc9eLuiz Augusto von Dentz		goto done;
1378463763c080cd72ecd727a218dd68f7c0ba95bc9eLuiz Augusto von Dentz	}
1379a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1380a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	*value = (int) level;
1381a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1382a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	if (value == &battchg_last)
13838e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan		DBG("telephony-ofono: battery.charge_level.last_full"
1384a34c155f55270b917795d003be24488f53d9b711Forrest Zhao					" is %d", *value);
1385a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	else if (value == &battchg_design)
13868e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan		DBG("telephony-ofono: battery.charge_level.design"
1387a34c155f55270b917795d003be24488f53d9b711Forrest Zhao					" is %d", *value);
1388a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	else
13898e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan		DBG("telephony-ofono: battery.charge_level.current"
1390a34c155f55270b917795d003be24488f53d9b711Forrest Zhao					" is %d", *value);
1391a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1392a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	if ((battchg_design > 0 || battchg_last > 0) && battchg_cur >= 0) {
13939ff86aa7f2c11cb3198dfcde93f8db3c534ecdb6Johan Hedberg		int new, max;
1394a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1395a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		if (battchg_last > 0)
1396a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			max = battchg_last;
1397a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		else
1398a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			max = battchg_design;
1399a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1400a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		new = battchg_cur * 5 / max;
1401a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
14029ff86aa7f2c11cb3198dfcde93f8db3c534ecdb6Johan Hedberg		telephony_update_indicator(ofono_indicators, "battchg", new);
1403a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	}
1404a34c155f55270b917795d003be24488f53d9b711Forrest Zhaodone:
1405a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	dbus_message_unref(reply);
1406c49dc8c7c815191b5825896f827cac2e2ff395ffLuiz Augusto von Dentz	remove_pending(call);
1407a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
1408a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1409a34c155f55270b917795d003be24488f53d9b711Forrest Zhaostatic void hal_get_integer(const char *path, const char *key, void *user_data)
1410a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
1411a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	send_method_call("org.freedesktop.Hal", path,
1412a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			"org.freedesktop.Hal.Device",
1413a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			"GetPropertyInteger",
1414a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			hal_battery_level_reply, user_data,
1415a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			DBUS_TYPE_STRING, &key,
1416a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			DBUS_TYPE_INVALID);
1417a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
1418a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
14198309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentzstatic gboolean handle_hal_property_modified(DBusConnection *conn,
14208309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz						DBusMessage *msg, void *data)
1421a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
1422a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	const char *path;
1423a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	DBusMessageIter iter, array;
1424a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	dbus_int32_t num_changes;
1425a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1426a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	path = dbus_message_get_path(msg);
1427a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1428a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	dbus_message_iter_init(msg, &iter);
1429a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1430a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_INT32) {
1431a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		error("Unexpected signature in hal PropertyModified signal");
14328309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz		return TRUE;
1433a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	}
1434a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1435a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	dbus_message_iter_get_basic(&iter, &num_changes);
1436a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	dbus_message_iter_next(&iter);
1437a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1438a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY) {
1439a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		error("Unexpected signature in hal PropertyModified signal");
14408309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz		return TRUE;
1441a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	}
1442a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1443a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	dbus_message_iter_recurse(&iter, &array);
1444a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1445a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	while (dbus_message_iter_get_arg_type(&array) != DBUS_TYPE_INVALID) {
1446a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		DBusMessageIter prop;
1447a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		const char *name;
1448a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		dbus_bool_t added, removed;
1449a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1450a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		dbus_message_iter_recurse(&array, &prop);
1451a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1452a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		if (!iter_get_basic_args(&prop,
1453a34c155f55270b917795d003be24488f53d9b711Forrest Zhao					DBUS_TYPE_STRING, &name,
1454a34c155f55270b917795d003be24488f53d9b711Forrest Zhao					DBUS_TYPE_BOOLEAN, &added,
1455a34c155f55270b917795d003be24488f53d9b711Forrest Zhao					DBUS_TYPE_BOOLEAN, &removed,
1456a34c155f55270b917795d003be24488f53d9b711Forrest Zhao					DBUS_TYPE_INVALID)) {
1457a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			error("Invalid hal PropertyModified parameters");
1458a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			break;
1459a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		}
1460a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1461a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		if (g_str_equal(name, "battery.charge_level.last_full"))
1462a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			hal_get_integer(path, name, &battchg_last);
1463a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		else if (g_str_equal(name, "battery.charge_level.current"))
1464a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			hal_get_integer(path, name, &battchg_cur);
1465a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		else if (g_str_equal(name, "battery.charge_level.design"))
1466a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			hal_get_integer(path, name, &battchg_design);
1467a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1468a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		dbus_message_iter_next(&array);
1469a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	}
14708309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz
14718309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	return TRUE;
1472a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
1473a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
14749946e8636c3361dc769c5f8a463b74158018d3ddLuiz Augusto von Dentzstatic void add_watch(const char *sender, const char *path,
14759946e8636c3361dc769c5f8a463b74158018d3ddLuiz Augusto von Dentz				const char *interface, const char *member,
14769946e8636c3361dc769c5f8a463b74158018d3ddLuiz Augusto von Dentz				GDBusSignalFunction function)
14779946e8636c3361dc769c5f8a463b74158018d3ddLuiz Augusto von Dentz{
14789946e8636c3361dc769c5f8a463b74158018d3ddLuiz Augusto von Dentz	guint watch;
14799946e8636c3361dc769c5f8a463b74158018d3ddLuiz Augusto von Dentz
14809946e8636c3361dc769c5f8a463b74158018d3ddLuiz Augusto von Dentz	watch = g_dbus_add_signal_watch(connection, sender, path, interface,
14819946e8636c3361dc769c5f8a463b74158018d3ddLuiz Augusto von Dentz					member, function, NULL, NULL);
14829946e8636c3361dc769c5f8a463b74158018d3ddLuiz Augusto von Dentz
14839946e8636c3361dc769c5f8a463b74158018d3ddLuiz Augusto von Dentz	watches = g_slist_prepend(watches, GUINT_TO_POINTER(watch));
14849946e8636c3361dc769c5f8a463b74158018d3ddLuiz Augusto von Dentz}
14859946e8636c3361dc769c5f8a463b74158018d3ddLuiz Augusto von Dentz
14868309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentzstatic void hal_find_device_reply(DBusPendingCall *call, void *user_data)
1487a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
14888309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	DBusMessage *reply;
14898309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	DBusError err;
14908309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	DBusMessageIter iter, sub;
14918309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	int type;
14928309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	const char *path;
14938309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz
14948e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan	DBG("begin of hal_find_device_reply()");
14958309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	reply = dbus_pending_call_steal_reply(call);
14968309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz
14978309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	dbus_error_init(&err);
14988309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz
14998309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	if (dbus_set_error_from_message(&err, reply)) {
15008309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz		error("hald replied with an error: %s, %s",
15018309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz				err.name, err.message);
15028309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz		dbus_error_free(&err);
15038309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz		goto done;
15048309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	}
15058309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz
15068309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	dbus_message_iter_init(reply, &iter);
15078309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz
15088309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY) {
15098309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz		error("Unexpected signature in hal_find_device_reply()");
15108309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz		goto done;
15118309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	}
15128309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz
15138309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	dbus_message_iter_recurse(&iter, &sub);
15148309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz
15158309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	type = dbus_message_iter_get_arg_type(&sub);
15168309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz
15178309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	if (type != DBUS_TYPE_OBJECT_PATH && type != DBUS_TYPE_STRING) {
15188309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz		error("No hal device with battery capability found");
15198309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz		goto done;
15208309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	}
15218309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz
15228309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	dbus_message_iter_get_basic(&sub, &path);
15238309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz
15248e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan	DBG("telephony-ofono: found battery device at %s", path);
15258309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz
15269946e8636c3361dc769c5f8a463b74158018d3ddLuiz Augusto von Dentz	add_watch(NULL, path, "org.freedesktop.Hal.Device",
15279946e8636c3361dc769c5f8a463b74158018d3ddLuiz Augusto von Dentz			"PropertyModified", handle_hal_property_modified);
15288309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz
15298309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	hal_get_integer(path, "battery.charge_level.last_full", &battchg_last);
15308309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	hal_get_integer(path, "battery.charge_level.current", &battchg_cur);
15318309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	hal_get_integer(path, "battery.charge_level.design", &battchg_design);
15328309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentzdone:
15338309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	dbus_message_unref(reply);
1534c49dc8c7c815191b5825896f827cac2e2ff395ffLuiz Augusto von Dentz	remove_pending(call);
1535a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
1536a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1537c7b0c8e099b8fdfa1ad2a905d6f482beb3aaddaaLuiz Augusto von Dentzstatic void handle_service_connect(DBusConnection *conn, void *user_data)
1538c7b0c8e099b8fdfa1ad2a905d6f482beb3aaddaaLuiz Augusto von Dentz{
1539c7b0c8e099b8fdfa1ad2a905d6f482beb3aaddaaLuiz Augusto von Dentz	DBG("telephony-ofono: %s found", OFONO_BUS_NAME);
1540c7b0c8e099b8fdfa1ad2a905d6f482beb3aaddaaLuiz Augusto von Dentz
1541c7b0c8e099b8fdfa1ad2a905d6f482beb3aaddaaLuiz Augusto von Dentz	send_method_call(OFONO_BUS_NAME, OFONO_PATH,
1542c7b0c8e099b8fdfa1ad2a905d6f482beb3aaddaaLuiz Augusto von Dentz				OFONO_MANAGER_INTERFACE, "GetModems",
1543c7b0c8e099b8fdfa1ad2a905d6f482beb3aaddaaLuiz Augusto von Dentz				get_modems_reply, NULL, DBUS_TYPE_INVALID);
1544c7b0c8e099b8fdfa1ad2a905d6f482beb3aaddaaLuiz Augusto von Dentz}
1545c7b0c8e099b8fdfa1ad2a905d6f482beb3aaddaaLuiz Augusto von Dentz
1546c7b0c8e099b8fdfa1ad2a905d6f482beb3aaddaaLuiz Augusto von Dentzstatic void handle_service_disconnect(DBusConnection *conn, void *user_data)
1547c7b0c8e099b8fdfa1ad2a905d6f482beb3aaddaaLuiz Augusto von Dentz{
1548c7b0c8e099b8fdfa1ad2a905d6f482beb3aaddaaLuiz Augusto von Dentz	DBG("telephony-ofono: %s exitted", OFONO_BUS_NAME);
1549c7b0c8e099b8fdfa1ad2a905d6f482beb3aaddaaLuiz Augusto von Dentz
1550c7b0c8e099b8fdfa1ad2a905d6f482beb3aaddaaLuiz Augusto von Dentz	if (modem_obj_path)
1551c7b0c8e099b8fdfa1ad2a905d6f482beb3aaddaaLuiz Augusto von Dentz		modem_removed(modem_obj_path);
1552c7b0c8e099b8fdfa1ad2a905d6f482beb3aaddaaLuiz Augusto von Dentz}
1553c7b0c8e099b8fdfa1ad2a905d6f482beb3aaddaaLuiz Augusto von Dentz
1554a34c155f55270b917795d003be24488f53d9b711Forrest Zhaoint telephony_init(void)
1555a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
1556a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	const char *battery_cap = "battery";
1557a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	int ret;
1558c7b0c8e099b8fdfa1ad2a905d6f482beb3aaddaaLuiz Augusto von Dentz	guint watch;
1559a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1560a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	connection = dbus_bus_get(DBUS_BUS_SYSTEM, NULL);
1561a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1562806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	add_watch(OFONO_BUS_NAME, NULL, OFONO_MODEM_INTERFACE,
1563806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz			"PropertyChanged", handle_modem_property_changed);
15649946e8636c3361dc769c5f8a463b74158018d3ddLuiz Augusto von Dentz	add_watch(OFONO_BUS_NAME, NULL, OFONO_NETWORKREG_INTERFACE,
15659946e8636c3361dc769c5f8a463b74158018d3ddLuiz Augusto von Dentz			"PropertyChanged", handle_network_property_changed);
15669946e8636c3361dc769c5f8a463b74158018d3ddLuiz Augusto von Dentz	add_watch(OFONO_BUS_NAME, NULL, OFONO_MANAGER_INTERFACE,
15679946e8636c3361dc769c5f8a463b74158018d3ddLuiz Augusto von Dentz			"ModemAdded", handle_manager_modem_added);
15689946e8636c3361dc769c5f8a463b74158018d3ddLuiz Augusto von Dentz	add_watch(OFONO_BUS_NAME, NULL, OFONO_MANAGER_INTERFACE,
15699946e8636c3361dc769c5f8a463b74158018d3ddLuiz Augusto von Dentz			"ModemRemoved", handle_manager_modem_removed);
15709946e8636c3361dc769c5f8a463b74158018d3ddLuiz Augusto von Dentz	add_watch(OFONO_BUS_NAME, NULL, OFONO_VCMANAGER_INTERFACE,
15719946e8636c3361dc769c5f8a463b74158018d3ddLuiz Augusto von Dentz			"CallAdded", handle_vcmanager_call_added);
15729946e8636c3361dc769c5f8a463b74158018d3ddLuiz Augusto von Dentz	add_watch(OFONO_BUS_NAME, NULL, OFONO_VCMANAGER_INTERFACE,
15739946e8636c3361dc769c5f8a463b74158018d3ddLuiz Augusto von Dentz			"CallRemoved", handle_vcmanager_call_removed);
1574a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1575c7b0c8e099b8fdfa1ad2a905d6f482beb3aaddaaLuiz Augusto von Dentz	watch = g_dbus_add_service_watch(connection, OFONO_BUS_NAME,
1576c7b0c8e099b8fdfa1ad2a905d6f482beb3aaddaaLuiz Augusto von Dentz						handle_service_connect,
1577c7b0c8e099b8fdfa1ad2a905d6f482beb3aaddaaLuiz Augusto von Dentz						handle_service_disconnect,
1578c7b0c8e099b8fdfa1ad2a905d6f482beb3aaddaaLuiz Augusto von Dentz						NULL, NULL);
1579c7b0c8e099b8fdfa1ad2a905d6f482beb3aaddaaLuiz Augusto von Dentz	if (watch == 0)
1580c7b0c8e099b8fdfa1ad2a905d6f482beb3aaddaaLuiz Augusto von Dentz		return -ENOMEM;
1581c7b0c8e099b8fdfa1ad2a905d6f482beb3aaddaaLuiz Augusto von Dentz
1582c7b0c8e099b8fdfa1ad2a905d6f482beb3aaddaaLuiz Augusto von Dentz	watches = g_slist_prepend(watches, GUINT_TO_POINTER(watch));
1583a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1584a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	ret = send_method_call("org.freedesktop.Hal",
1585a34c155f55270b917795d003be24488f53d9b711Forrest Zhao				"/org/freedesktop/Hal/Manager",
1586a34c155f55270b917795d003be24488f53d9b711Forrest Zhao				"org.freedesktop.Hal.Manager",
1587a34c155f55270b917795d003be24488f53d9b711Forrest Zhao				"FindDeviceByCapability",
1588a34c155f55270b917795d003be24488f53d9b711Forrest Zhao				hal_find_device_reply, NULL,
1589a34c155f55270b917795d003be24488f53d9b711Forrest Zhao				DBUS_TYPE_STRING, &battery_cap,
1590a34c155f55270b917795d003be24488f53d9b711Forrest Zhao				DBUS_TYPE_INVALID);
1591a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	if (ret < 0)
1592a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		return ret;
1593a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
15948e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan	DBG("telephony_init() successfully");
1595a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1596a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	return ret;
1597a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
1598a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
15999946e8636c3361dc769c5f8a463b74158018d3ddLuiz Augusto von Dentzstatic void remove_watch(gpointer data)
16009946e8636c3361dc769c5f8a463b74158018d3ddLuiz Augusto von Dentz{
16019946e8636c3361dc769c5f8a463b74158018d3ddLuiz Augusto von Dentz	g_dbus_remove_watch(connection, GPOINTER_TO_UINT(data));
16029946e8636c3361dc769c5f8a463b74158018d3ddLuiz Augusto von Dentz}
16039946e8636c3361dc769c5f8a463b74158018d3ddLuiz Augusto von Dentz
1604a34c155f55270b917795d003be24488f53d9b711Forrest Zhaovoid telephony_exit(void)
1605a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
1606e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	DBG("");
1607a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1608a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	g_free(last_dialed_number);
1609e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	last_dialed_number = NULL;
1610a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1611e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	if (modem_obj_path)
1612e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz		modem_removed(modem_obj_path);
1613a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
16149946e8636c3361dc769c5f8a463b74158018d3ddLuiz Augusto von Dentz	g_slist_foreach(watches, (GFunc) remove_watch, NULL);
16159946e8636c3361dc769c5f8a463b74158018d3ddLuiz Augusto von Dentz	g_slist_free(watches);
16169946e8636c3361dc769c5f8a463b74158018d3ddLuiz Augusto von Dentz	watches = NULL;
1617a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1618c49dc8c7c815191b5825896f827cac2e2ff395ffLuiz Augusto von Dentz	g_slist_foreach(pending, (GFunc) dbus_pending_call_cancel, NULL);
1619c49dc8c7c815191b5825896f827cac2e2ff395ffLuiz Augusto von Dentz	g_slist_foreach(pending, (GFunc) dbus_pending_call_unref, NULL);
1620c49dc8c7c815191b5825896f827cac2e2ff395ffLuiz Augusto von Dentz	g_slist_free(pending);
1621c49dc8c7c815191b5825896f827cac2e2ff395ffLuiz Augusto von Dentz	pending = NULL;
1622c49dc8c7c815191b5825896f827cac2e2ff395ffLuiz Augusto von Dentz
1623a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	dbus_connection_unref(connection);
1624a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	connection = NULL;
1625401be3748717fae613041592778a3a7160fb763cJohan Hedberg
1626401be3748717fae613041592778a3a7160fb763cJohan Hedberg	telephony_deinit();
1627a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
1628