telephony-ofono.c revision d8ee95eb6d31fa715398a785b4b79846ca0a1f70
1a34c155f55270b917795d003be24488f53d9b711Forrest Zhao/*
2a34c155f55270b917795d003be24488f53d9b711Forrest Zhao *
3a34c155f55270b917795d003be24488f53d9b711Forrest Zhao *  BlueZ - Bluetooth protocol stack for Linux
4a34c155f55270b917795d003be24488f53d9b711Forrest Zhao *
5d3b613c392352f59fd6b18becf80e6504ad2423cMarcel Holtmann *  Copyright (C) 2009-2010  Intel Corporation
65592142cb9383df0556b27ac59e96547b380310bJohan Hedberg *  Copyright (C) 2006-2009  Nokia Corporation
79184e2eeb7b97371c6b83b747c8984e2340d2b47Marcel Holtmann *  Copyright (C) 2004-2010  Marcel Holtmann <marcel@holtmann.org>
8a34c155f55270b917795d003be24488f53d9b711Forrest Zhao *
9a34c155f55270b917795d003be24488f53d9b711Forrest Zhao *
10a34c155f55270b917795d003be24488f53d9b711Forrest Zhao *  This program is free software; you can redistribute it and/or modify
11a34c155f55270b917795d003be24488f53d9b711Forrest Zhao *  it under the terms of the GNU General Public License as published by
12a34c155f55270b917795d003be24488f53d9b711Forrest Zhao *  the Free Software Foundation; either version 2 of the License, or
13a34c155f55270b917795d003be24488f53d9b711Forrest Zhao *  (at your option) any later version.
14a34c155f55270b917795d003be24488f53d9b711Forrest Zhao *
15a34c155f55270b917795d003be24488f53d9b711Forrest Zhao *  This program is distributed in the hope that it will be useful,
16a34c155f55270b917795d003be24488f53d9b711Forrest Zhao *  but WITHOUT ANY WARRANTY; without even the implied warranty of
17a34c155f55270b917795d003be24488f53d9b711Forrest Zhao *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18a34c155f55270b917795d003be24488f53d9b711Forrest Zhao *  GNU General Public License for more details.
19a34c155f55270b917795d003be24488f53d9b711Forrest Zhao *
20a34c155f55270b917795d003be24488f53d9b711Forrest Zhao *  You should have received a copy of the GNU General Public License
21a34c155f55270b917795d003be24488f53d9b711Forrest Zhao *  along with this program; if not, write to the Free Software
22a34c155f55270b917795d003be24488f53d9b711Forrest Zhao *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
23a34c155f55270b917795d003be24488f53d9b711Forrest Zhao *
24a34c155f55270b917795d003be24488f53d9b711Forrest Zhao */
25a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
26a34c155f55270b917795d003be24488f53d9b711Forrest Zhao#ifdef HAVE_CONFIG_H
27a34c155f55270b917795d003be24488f53d9b711Forrest Zhao#include <config.h>
28a34c155f55270b917795d003be24488f53d9b711Forrest Zhao#endif
29a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
30a34c155f55270b917795d003be24488f53d9b711Forrest Zhao#include <stdlib.h>
31a34c155f55270b917795d003be24488f53d9b711Forrest Zhao#include <stdio.h>
32a34c155f55270b917795d003be24488f53d9b711Forrest Zhao#include <string.h>
33a34c155f55270b917795d003be24488f53d9b711Forrest Zhao#include <stdint.h>
34a34c155f55270b917795d003be24488f53d9b711Forrest Zhao#include <glib.h>
35a34c155f55270b917795d003be24488f53d9b711Forrest Zhao#include <dbus/dbus.h>
36a34c155f55270b917795d003be24488f53d9b711Forrest Zhao#include <gdbus.h>
37a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
38e891f7df6225c758da0d95f7554c6cc67f72f31eGustavo F. Padovan#include "log.h"
39a34c155f55270b917795d003be24488f53d9b711Forrest Zhao#include "telephony.h"
40a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
41a34c155f55270b917795d003be24488f53d9b711Forrest Zhaoenum net_registration_status {
42a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	NETWORK_REG_STATUS_HOME = 0x00,
43a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	NETWORK_REG_STATUS_ROAM,
44a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	NETWORK_REG_STATUS_NOSERV
45a34c155f55270b917795d003be24488f53d9b711Forrest Zhao};
46a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
47a34c155f55270b917795d003be24488f53d9b711Forrest Zhaostruct voice_call {
48a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	char *obj_path;
49a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	int status;
50a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	gboolean originating;
51a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	char *number;
528309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	guint watch;
53a34c155f55270b917795d003be24488f53d9b711Forrest Zhao};
54a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
55a34c155f55270b917795d003be24488f53d9b711Forrest Zhaostatic DBusConnection *connection = NULL;
56a34c155f55270b917795d003be24488f53d9b711Forrest Zhaostatic char *modem_obj_path = NULL;
57a34c155f55270b917795d003be24488f53d9b711Forrest Zhaostatic char *last_dialed_number = NULL;
58a34c155f55270b917795d003be24488f53d9b711Forrest Zhaostatic GSList *calls = NULL;
599946e8636c3361dc769c5f8a463b74158018d3ddLuiz Augusto von Dentzstatic GSList *watches = NULL;
60c49dc8c7c815191b5825896f827cac2e2ff395ffLuiz Augusto von Dentzstatic GSList *pending = NULL;
61a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
62a34c155f55270b917795d003be24488f53d9b711Forrest Zhao#define OFONO_BUS_NAME "org.ofono"
63a34c155f55270b917795d003be24488f53d9b711Forrest Zhao#define OFONO_PATH "/"
64806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz#define OFONO_MODEM_INTERFACE "org.ofono.Modem"
65d89690657f2634ceb9d4b13257ccc7d60bc0cb5dForrest Zhao#define OFONO_MANAGER_INTERFACE "org.ofono.Manager"
66a34c155f55270b917795d003be24488f53d9b711Forrest Zhao#define OFONO_NETWORKREG_INTERFACE "org.ofono.NetworkRegistration"
67a34c155f55270b917795d003be24488f53d9b711Forrest Zhao#define OFONO_VCMANAGER_INTERFACE "org.ofono.VoiceCallManager"
68a34c155f55270b917795d003be24488f53d9b711Forrest Zhao#define OFONO_VC_INTERFACE "org.ofono.VoiceCall"
69a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
70a34c155f55270b917795d003be24488f53d9b711Forrest Zhao/* HAL battery namespace key values */
71a34c155f55270b917795d003be24488f53d9b711Forrest Zhaostatic int battchg_cur = -1;    /* "battery.charge_level.current" */
72a34c155f55270b917795d003be24488f53d9b711Forrest Zhaostatic int battchg_last = -1;   /* "battery.charge_level.last_full" */
73a34c155f55270b917795d003be24488f53d9b711Forrest Zhaostatic int battchg_design = -1; /* "battery.charge_level.design" */
74a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
75a34c155f55270b917795d003be24488f53d9b711Forrest Zhaostatic struct {
76a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	uint8_t status;
77a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	uint32_t signals_bar;
78a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	char *operator_name;
79a34c155f55270b917795d003be24488f53d9b711Forrest Zhao} net = {
80a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	.status = NETWORK_REG_STATUS_NOSERV,
81a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	.signals_bar = 0,
82a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	.operator_name = NULL,
83a34c155f55270b917795d003be24488f53d9b711Forrest Zhao};
84a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
85a34c155f55270b917795d003be24488f53d9b711Forrest Zhaostatic const char *chld_str = "0,1,1x,2,2x,3,4";
86a34c155f55270b917795d003be24488f53d9b711Forrest Zhaostatic char *subscriber_number = NULL;
87a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
88a34c155f55270b917795d003be24488f53d9b711Forrest Zhaostatic gboolean events_enabled = FALSE;
89a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
90a34c155f55270b917795d003be24488f53d9b711Forrest Zhaostatic struct indicator ofono_indicators[] =
91a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
92884debf8418651b63b1a5a8918092ba4d230783eJohan Hedberg	{ "battchg",	"0-5",	5,	TRUE },
93884debf8418651b63b1a5a8918092ba4d230783eJohan Hedberg	{ "signal",	"0-5",	5,	TRUE },
94884debf8418651b63b1a5a8918092ba4d230783eJohan Hedberg	{ "service",	"0,1",	1,	TRUE },
95884debf8418651b63b1a5a8918092ba4d230783eJohan Hedberg	{ "call",	"0,1",	0,	TRUE },
96884debf8418651b63b1a5a8918092ba4d230783eJohan Hedberg	{ "callsetup",	"0-3",	0,	TRUE },
97884debf8418651b63b1a5a8918092ba4d230783eJohan Hedberg	{ "callheld",	"0-2",	0,	FALSE },
98884debf8418651b63b1a5a8918092ba4d230783eJohan Hedberg	{ "roam",	"0,1",	0,	TRUE },
99a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	{ NULL }
100a34c155f55270b917795d003be24488f53d9b711Forrest Zhao};
101a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
102a34c155f55270b917795d003be24488f53d9b711Forrest Zhaostatic struct voice_call *find_vc(const char *path)
103a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
104a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	GSList *l;
105a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
106a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	for (l = calls; l != NULL; l = l->next) {
107a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		struct voice_call *vc = l->data;
108a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
109a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		if (g_str_equal(vc->obj_path, path))
110a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			return vc;
111a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	}
112a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
113a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	return NULL;
114a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
115a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
116a34c155f55270b917795d003be24488f53d9b711Forrest Zhaostatic struct voice_call *find_vc_with_status(int status)
117a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
118a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	GSList *l;
119a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
120a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	for (l = calls; l != NULL; l = l->next) {
121a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		struct voice_call *vc = l->data;
122a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
123a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		if (vc->status == status)
124a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			return vc;
125a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	}
126a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
127a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	return NULL;
128a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
129a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
130d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentzstatic struct voice_call *find_vc_without_status(int status)
131d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz{
132d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	GSList *l;
133d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz
134d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	for (l = calls; l != NULL; l = l->next) {
135d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz		struct voice_call *call = l->data;
136d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz
137d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz		if (call->status != status)
138d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz			return call;
139d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	}
140d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz
141d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	return NULL;
142d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz}
143d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz
1441097cfd46e906ddfd8a827ce683c1eddf2d98499Luiz Augusto von Dentzstatic int number_type(const char *number)
1451097cfd46e906ddfd8a827ce683c1eddf2d98499Luiz Augusto von Dentz{
1461097cfd46e906ddfd8a827ce683c1eddf2d98499Luiz Augusto von Dentz	if (number == NULL)
1471097cfd46e906ddfd8a827ce683c1eddf2d98499Luiz Augusto von Dentz		return NUMBER_TYPE_TELEPHONY;
1481097cfd46e906ddfd8a827ce683c1eddf2d98499Luiz Augusto von Dentz
1491097cfd46e906ddfd8a827ce683c1eddf2d98499Luiz Augusto von Dentz	if (number[0] == '+' || strncmp(number, "00", 2) == 0)
1501097cfd46e906ddfd8a827ce683c1eddf2d98499Luiz Augusto von Dentz		return NUMBER_TYPE_INTERNATIONAL;
1511097cfd46e906ddfd8a827ce683c1eddf2d98499Luiz Augusto von Dentz
1521097cfd46e906ddfd8a827ce683c1eddf2d98499Luiz Augusto von Dentz	return NUMBER_TYPE_TELEPHONY;
1531097cfd46e906ddfd8a827ce683c1eddf2d98499Luiz Augusto von Dentz}
1541097cfd46e906ddfd8a827ce683c1eddf2d98499Luiz Augusto von Dentz
155a34c155f55270b917795d003be24488f53d9b711Forrest Zhaovoid telephony_device_connected(void *telephony_device)
156a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
1571097cfd46e906ddfd8a827ce683c1eddf2d98499Luiz Augusto von Dentz	struct voice_call *coming;
1581097cfd46e906ddfd8a827ce683c1eddf2d98499Luiz Augusto von Dentz
1598e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan	DBG("telephony-ofono: device %p connected", telephony_device);
1601097cfd46e906ddfd8a827ce683c1eddf2d98499Luiz Augusto von Dentz
1611097cfd46e906ddfd8a827ce683c1eddf2d98499Luiz Augusto von Dentz	coming = find_vc_with_status(CALL_STATUS_ALERTING);
1621097cfd46e906ddfd8a827ce683c1eddf2d98499Luiz Augusto von Dentz	if (coming) {
1631097cfd46e906ddfd8a827ce683c1eddf2d98499Luiz Augusto von Dentz		if (find_vc_with_status(CALL_STATUS_ACTIVE))
1641097cfd46e906ddfd8a827ce683c1eddf2d98499Luiz Augusto von Dentz			telephony_call_waiting_ind(coming->number,
1651097cfd46e906ddfd8a827ce683c1eddf2d98499Luiz Augusto von Dentz						number_type(coming->number));
1661097cfd46e906ddfd8a827ce683c1eddf2d98499Luiz Augusto von Dentz		else
1671097cfd46e906ddfd8a827ce683c1eddf2d98499Luiz Augusto von Dentz			telephony_incoming_call_ind(coming->number,
1681097cfd46e906ddfd8a827ce683c1eddf2d98499Luiz Augusto von Dentz						number_type(coming->number));
1691097cfd46e906ddfd8a827ce683c1eddf2d98499Luiz Augusto von Dentz	}
170a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
171a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
172a34c155f55270b917795d003be24488f53d9b711Forrest Zhaovoid telephony_device_disconnected(void *telephony_device)
173a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
1748e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan	DBG("telephony-ofono: device %p disconnected", telephony_device);
175a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	events_enabled = FALSE;
176a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
177a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
178a34c155f55270b917795d003be24488f53d9b711Forrest Zhaovoid telephony_event_reporting_req(void *telephony_device, int ind)
179a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
180a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	events_enabled = ind == 1 ? TRUE : FALSE;
181a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
182a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	telephony_event_reporting_rsp(telephony_device, CME_ERROR_NONE);
183a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
184a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
185a34c155f55270b917795d003be24488f53d9b711Forrest Zhaovoid telephony_response_and_hold_req(void *telephony_device, int rh)
186a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
187b0d302d48976920cec7548ec5cc603f3896bbb8cJohan Hedberg	telephony_response_and_hold_rsp(telephony_device,
188b0d302d48976920cec7548ec5cc603f3896bbb8cJohan Hedberg						CME_ERROR_NOT_SUPPORTED);
189a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
190a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
191a34c155f55270b917795d003be24488f53d9b711Forrest Zhaovoid telephony_last_dialed_number_req(void *telephony_device)
192a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
1938e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan	DBG("telephony-ofono: last dialed number request");
194a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
195a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	if (last_dialed_number)
196a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		telephony_dial_number_req(telephony_device, last_dialed_number);
197a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	else
198a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		telephony_last_dialed_number_rsp(telephony_device,
199a34c155f55270b917795d003be24488f53d9b711Forrest Zhao				CME_ERROR_NOT_ALLOWED);
200a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
201a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
202a34c155f55270b917795d003be24488f53d9b711Forrest Zhaostatic int send_method_call(const char *dest, const char *path,
203a34c155f55270b917795d003be24488f53d9b711Forrest Zhao                                const char *interface, const char *method,
204a34c155f55270b917795d003be24488f53d9b711Forrest Zhao                                DBusPendingCallNotifyFunction cb,
205a34c155f55270b917795d003be24488f53d9b711Forrest Zhao                                void *user_data, int type, ...)
206a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
207a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	DBusMessage *msg;
208a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	DBusPendingCall *call;
209a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	va_list args;
210a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
211a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	msg = dbus_message_new_method_call(dest, path, interface, method);
212a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	if (!msg) {
213a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		error("Unable to allocate new D-Bus %s message", method);
214a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		return -ENOMEM;
215a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	}
216a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
217a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	va_start(args, type);
218a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
219a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	if (!dbus_message_append_args_valist(msg, type, args)) {
220a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		dbus_message_unref(msg);
221a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		va_end(args);
222a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		return -EIO;
223a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	}
224a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
225a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	va_end(args);
226a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
227a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	if (!cb) {
228a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		g_dbus_send_message(connection, msg);
229a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		return 0;
230a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	}
231a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
232a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	if (!dbus_connection_send_with_reply(connection, msg, &call, -1)) {
233a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		error("Sending %s failed", method);
234a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		dbus_message_unref(msg);
235a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		return -EIO;
236a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	}
237a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
238a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	dbus_pending_call_set_notify(call, cb, user_data, NULL);
239c49dc8c7c815191b5825896f827cac2e2ff395ffLuiz Augusto von Dentz	pending = g_slist_prepend(pending, call);
240a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	dbus_message_unref(msg);
241a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
242a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	return 0;
243a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
244a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
245d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentzstatic int answer_call(struct voice_call *vc)
246d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz{
247d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	DBG("%s", vc->number);
248d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	return send_method_call(OFONO_BUS_NAME, vc->obj_path,
249d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz						OFONO_VC_INTERFACE, "Answer",
250d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz						NULL, NULL, DBUS_TYPE_INVALID);
251d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz}
252d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz
253d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentzstatic int release_call(struct voice_call *vc)
254d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz{
255d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	DBG("%s", vc->number);
256d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	return send_method_call(OFONO_BUS_NAME, vc->obj_path,
257d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz						OFONO_VC_INTERFACE, "Hangup",
258d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz						NULL, NULL, DBUS_TYPE_INVALID);
259d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz}
260d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz
261d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentzstatic int release_answer_calls()
262d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz{
263d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	DBG("");
264d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	return send_method_call(OFONO_BUS_NAME, modem_obj_path,
265d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz						OFONO_VCMANAGER_INTERFACE,
266d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz						"ReleaseAndAnswer",
267d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz						NULL, NULL, DBUS_TYPE_INVALID);
268d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz}
269d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz
270d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentzstatic int swap_calls(void)
271d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz{
272d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	DBG("");
273d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	return send_method_call(OFONO_BUS_NAME, modem_obj_path,
274d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz						OFONO_VCMANAGER_INTERFACE,
275d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz						"SwapCalls",
276d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz						NULL, NULL, DBUS_TYPE_INVALID);
277d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz}
278d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz
279d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentzstatic int call_transfer(void)
280d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz{
281d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	DBG("");
282d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	return send_method_call(OFONO_BUS_NAME, modem_obj_path,
283d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz						OFONO_VCMANAGER_INTERFACE,
284d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz						"Transfer",
285d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz						NULL, NULL, DBUS_TYPE_INVALID);
286d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz}
287d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz
288a34c155f55270b917795d003be24488f53d9b711Forrest Zhaovoid telephony_terminate_call_req(void *telephony_device)
289a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
290d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	struct voice_call *call;
291d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	struct voice_call *alerting;
292d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	int err;
293a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
294d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	call = find_vc_with_status(CALL_STATUS_ACTIVE);
295d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	if (!call)
296d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz		call = calls->data;
297a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
298d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	if (!call) {
299d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz		error("No active call");
300a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		telephony_terminate_call_rsp(telephony_device,
301d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz						CME_ERROR_NOT_ALLOWED);
302a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		return;
303a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	}
304a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
305d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	alerting = find_vc_with_status(CALL_STATUS_ALERTING);
306d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	if (call->status == CALL_STATUS_HELD && alerting)
307d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz		err = release_call(alerting);
308d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	else
309d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz		err = release_call(call);
310a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
311d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	if (err < 0)
312d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz		telephony_terminate_call_rsp(telephony_device,
313d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz						CME_ERROR_AG_FAILURE);
314d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	else
315d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz		telephony_terminate_call_rsp(telephony_device, CME_ERROR_NONE);
316a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
317a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
318a34c155f55270b917795d003be24488f53d9b711Forrest Zhaovoid telephony_answer_call_req(void *telephony_device)
319a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
32016ec168ac7fdd18cb2cbc7b3be7df349fd84c41cLuiz Augusto von Dentz	struct voice_call *vc;
321a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	int ret;
322a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
32316ec168ac7fdd18cb2cbc7b3be7df349fd84c41cLuiz Augusto von Dentz	vc = find_vc_with_status(CALL_STATUS_INCOMING);
32416ec168ac7fdd18cb2cbc7b3be7df349fd84c41cLuiz Augusto von Dentz	if (!vc)
32516ec168ac7fdd18cb2cbc7b3be7df349fd84c41cLuiz Augusto von Dentz		vc = find_vc_with_status(CALL_STATUS_ALERTING);
32616ec168ac7fdd18cb2cbc7b3be7df349fd84c41cLuiz Augusto von Dentz
32716ec168ac7fdd18cb2cbc7b3be7df349fd84c41cLuiz Augusto von Dentz	if (!vc)
32816ec168ac7fdd18cb2cbc7b3be7df349fd84c41cLuiz Augusto von Dentz		vc = find_vc_with_status(CALL_STATUS_WAITING);
32916ec168ac7fdd18cb2cbc7b3be7df349fd84c41cLuiz Augusto von Dentz
330a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	if (!vc) {
331a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		telephony_answer_call_rsp(telephony_device,
332a34c155f55270b917795d003be24488f53d9b711Forrest Zhao					CME_ERROR_NOT_ALLOWED);
333a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		return;
334a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	}
335a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
336d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	ret = answer_call(vc);
337a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	if (ret < 0) {
338a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		telephony_answer_call_rsp(telephony_device,
339a34c155f55270b917795d003be24488f53d9b711Forrest Zhao					CME_ERROR_AG_FAILURE);
340a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		return;
341a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	}
342a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
343a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	telephony_answer_call_rsp(telephony_device, CME_ERROR_NONE);
344a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
345a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
346a34c155f55270b917795d003be24488f53d9b711Forrest Zhaovoid telephony_dial_number_req(void *telephony_device, const char *number)
347a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
34883003660808c30390f21c569a5ba7dbdd8344a41Claudio Takahasi	const char *clir;
349a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	int ret;
350a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
3518e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan	DBG("telephony-ofono: dial request to %s", number);
352a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
353c5321032b046c39477ab99a05e933b13d0b67a04Forrest Zhao	if (!modem_obj_path) {
354c5321032b046c39477ab99a05e933b13d0b67a04Forrest Zhao		telephony_dial_number_rsp(telephony_device,
355c5321032b046c39477ab99a05e933b13d0b67a04Forrest Zhao					CME_ERROR_AG_FAILURE);
356c5321032b046c39477ab99a05e933b13d0b67a04Forrest Zhao		return;
357c5321032b046c39477ab99a05e933b13d0b67a04Forrest Zhao	}
358c5321032b046c39477ab99a05e933b13d0b67a04Forrest Zhao
359a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	if (!strncmp(number, "*31#", 4)) {
360a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		number += 4;
36183003660808c30390f21c569a5ba7dbdd8344a41Claudio Takahasi		clir = "enabled";
362a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	} else if (!strncmp(number, "#31#", 4)) {
363a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		number += 4;
36483003660808c30390f21c569a5ba7dbdd8344a41Claudio Takahasi		clir =  "disabled";
36583003660808c30390f21c569a5ba7dbdd8344a41Claudio Takahasi	} else
36683003660808c30390f21c569a5ba7dbdd8344a41Claudio Takahasi		clir = "default";
367a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
368a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	ret = send_method_call(OFONO_BUS_NAME, modem_obj_path,
369a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			OFONO_VCMANAGER_INTERFACE,
370a34c155f55270b917795d003be24488f53d9b711Forrest Zhao                        "Dial", NULL, NULL,
371a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			DBUS_TYPE_STRING, &number,
372a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			DBUS_TYPE_STRING, &clir,
373a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			DBUS_TYPE_INVALID);
374a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
375a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	if (ret < 0)
376a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		telephony_dial_number_rsp(telephony_device,
377a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			CME_ERROR_AG_FAILURE);
378a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	else
379a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		telephony_dial_number_rsp(telephony_device, CME_ERROR_NONE);
380a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
381a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
382a34c155f55270b917795d003be24488f53d9b711Forrest Zhaovoid telephony_transmit_dtmf_req(void *telephony_device, char tone)
383a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
384a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	char *tone_string;
385a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	int ret;
386a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
3878e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan	DBG("telephony-ofono: transmit dtmf: %c", tone);
388a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
389c5321032b046c39477ab99a05e933b13d0b67a04Forrest Zhao	if (!modem_obj_path) {
390c5321032b046c39477ab99a05e933b13d0b67a04Forrest Zhao		telephony_transmit_dtmf_rsp(telephony_device,
391c5321032b046c39477ab99a05e933b13d0b67a04Forrest Zhao					CME_ERROR_AG_FAILURE);
392c5321032b046c39477ab99a05e933b13d0b67a04Forrest Zhao		return;
393c5321032b046c39477ab99a05e933b13d0b67a04Forrest Zhao	}
394c5321032b046c39477ab99a05e933b13d0b67a04Forrest Zhao
395a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	tone_string = g_strdup_printf("%c", tone);
396a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	ret = send_method_call(OFONO_BUS_NAME, modem_obj_path,
397a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			OFONO_VCMANAGER_INTERFACE,
398a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			"SendTones", NULL, NULL,
399a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			DBUS_TYPE_STRING, &tone_string,
400a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			DBUS_TYPE_INVALID);
401a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	g_free(tone_string);
402a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
403a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	if (ret < 0)
404a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		telephony_transmit_dtmf_rsp(telephony_device,
405a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			CME_ERROR_AG_FAILURE);
406a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	else
407a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		telephony_transmit_dtmf_rsp(telephony_device, CME_ERROR_NONE);
408a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
409a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
410a34c155f55270b917795d003be24488f53d9b711Forrest Zhaovoid telephony_subscriber_number_req(void *telephony_device)
411a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
4128e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan	DBG("telephony-ofono: subscriber number request");
413a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
414a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	if (subscriber_number)
415a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		telephony_subscriber_number_ind(subscriber_number,
416a34c155f55270b917795d003be24488f53d9b711Forrest Zhao						NUMBER_TYPE_TELEPHONY,
417a34c155f55270b917795d003be24488f53d9b711Forrest Zhao						SUBSCRIBER_SERVICE_VOICE);
418a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	telephony_subscriber_number_rsp(telephony_device, CME_ERROR_NONE);
419a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
420a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
421a34c155f55270b917795d003be24488f53d9b711Forrest Zhaovoid telephony_list_current_calls_req(void *telephony_device)
422a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
423a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	GSList *l;
424a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	int i;
425a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
4268e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan	DBG("telephony-ofono: list current calls request");
427a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
428a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	for (l = calls, i = 1; l != NULL; l = l->next, i++) {
429a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		struct voice_call *vc = l->data;
430a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		int direction;
431a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
432a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		direction = vc->originating ?
433a34c155f55270b917795d003be24488f53d9b711Forrest Zhao				CALL_DIR_OUTGOING : CALL_DIR_INCOMING;
434a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
435d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz		DBG("call %s direction %d", vc->number, direction);
436d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz
437a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		telephony_list_current_call_ind(i, direction, vc->status,
438a34c155f55270b917795d003be24488f53d9b711Forrest Zhao					CALL_MODE_VOICE, CALL_MULTIPARTY_NO,
439d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz					vc->number, number_type(vc->number));
440a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	}
441d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz
442a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	telephony_list_current_calls_rsp(telephony_device, CME_ERROR_NONE);
443a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
444a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
445a34c155f55270b917795d003be24488f53d9b711Forrest Zhaovoid telephony_operator_selection_req(void *telephony_device)
446a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
4478e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan	DBG("telephony-ofono: operator selection request");
448a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
449a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	telephony_operator_selection_ind(OPERATOR_MODE_AUTO,
450a34c155f55270b917795d003be24488f53d9b711Forrest Zhao				net.operator_name ? net.operator_name : "");
451a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	telephony_operator_selection_rsp(telephony_device, CME_ERROR_NONE);
452a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
453a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
454d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentzstatic void foreach_vc_with_status(int status,
455d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz					int (*func)(struct voice_call *vc))
456d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz{
457d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	GSList *l;
458d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz
459d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	for (l = calls; l != NULL; l = l->next) {
460d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz		struct voice_call *call = l->data;
461d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz
462d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz		if (call->status == status)
463d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz			func(call);
464d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	}
465d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz}
466d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz
467a34c155f55270b917795d003be24488f53d9b711Forrest Zhaovoid telephony_call_hold_req(void *telephony_device, const char *cmd)
468a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
469d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	struct voice_call *call;
470d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	int err = 0;
471d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz
4728e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan	DBG("telephony-ofono: got call hold request %s", cmd);
473d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz
474d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	switch (cmd[0]) {
475d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	case '0':
476d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz		if (find_vc_with_status(CALL_STATUS_WAITING))
477d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz			foreach_vc_with_status(CALL_STATUS_WAITING,
478d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz								release_call);
479d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz		else
480d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz			foreach_vc_with_status(CALL_STATUS_HELD, release_call);
481d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz		break;
482d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	case '1':
483d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz		err = release_answer_calls();
484d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz		break;
485d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	case '2':
486d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz		call = find_vc_with_status(CALL_STATUS_WAITING);
487d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz
488d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz		if (call)
489d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz			err = answer_call(call);
490d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz		else
491d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz			err = swap_calls();
492d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz		break;
493d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	case '4':
494d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz		err = call_transfer();
495d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz		break;
496d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	default:
497d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz		DBG("Unknown call hold request");
498d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz		break;
499d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	}
500d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz
501d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	if (err)
502d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz		telephony_call_hold_rsp(telephony_device,
503d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz					CME_ERROR_AG_FAILURE);
504d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	else
505d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz		telephony_call_hold_rsp(telephony_device, CME_ERROR_NONE);
506a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
507a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
508a34c155f55270b917795d003be24488f53d9b711Forrest Zhaovoid telephony_nr_and_ec_req(void *telephony_device, gboolean enable)
509a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
5108e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan	DBG("telephony-ofono: got %s NR and EC request",
511a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			enable ? "enable" : "disable");
512a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
513a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	telephony_nr_and_ec_rsp(telephony_device, CME_ERROR_NONE);
514a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
515a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
516a34c155f55270b917795d003be24488f53d9b711Forrest Zhaovoid telephony_key_press_req(void *telephony_device, const char *keys)
517a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
518d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	struct voice_call *active, *waiting;
519d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	int err;
520d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz
5218e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan	DBG("telephony-ofono: got key press request for %s", keys);
522d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz
523d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	waiting = find_vc_with_status(CALL_STATUS_INCOMING);
524d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	if (!waiting)
525d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz		waiting = find_vc_with_status(CALL_STATUS_DIALING);
526d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz
527d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	active = find_vc_with_status(CALL_STATUS_ACTIVE);
528d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz
529d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	if (waiting)
530d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz		err = answer_call(waiting);
531d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	else if (active)
532d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz		err = release_call(active);
533d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	else
534d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz		err = 0;
535d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz
536d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	if (err < 0)
537d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz		telephony_key_press_rsp(telephony_device,
538d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz							CME_ERROR_AG_FAILURE);
539d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	else
540d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz		telephony_key_press_rsp(telephony_device, CME_ERROR_NONE);
541a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
542a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
5430218ab79ea881c593111b7165cd57337c711d2ecPeter Zotovvoid telephony_voice_dial_req(void *telephony_device, gboolean enable)
5440218ab79ea881c593111b7165cd57337c711d2ecPeter Zotov{
5458e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan	DBG("telephony-ofono: got %s voice dial request",
5460218ab79ea881c593111b7165cd57337c711d2ecPeter Zotov			enable ? "enable" : "disable");
5470218ab79ea881c593111b7165cd57337c711d2ecPeter Zotov
5480218ab79ea881c593111b7165cd57337c711d2ecPeter Zotov	telephony_voice_dial_rsp(telephony_device, CME_ERROR_NOT_SUPPORTED);
5490218ab79ea881c593111b7165cd57337c711d2ecPeter Zotov}
5500218ab79ea881c593111b7165cd57337c711d2ecPeter Zotov
551a34c155f55270b917795d003be24488f53d9b711Forrest Zhaostatic gboolean iter_get_basic_args(DBusMessageIter *iter,
552a34c155f55270b917795d003be24488f53d9b711Forrest Zhao					int first_arg_type, ...)
553a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
554a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	int type;
555a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	va_list ap;
556a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
557a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	va_start(ap, first_arg_type);
558a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
559a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	for (type = first_arg_type; type != DBUS_TYPE_INVALID;
560a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		type = va_arg(ap, int)) {
561a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		void *value = va_arg(ap, void *);
562a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		int real_type = dbus_message_iter_get_arg_type(iter);
563a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
564a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		if (real_type != type) {
565a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			error("iter_get_basic_args: expected %c but got %c",
566a34c155f55270b917795d003be24488f53d9b711Forrest Zhao				(char) type, (char) real_type);
567a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			break;
568a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		}
569a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
570a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		dbus_message_iter_get_basic(iter, value);
571a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		dbus_message_iter_next(iter);
572a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	}
573a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
574a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	va_end(ap);
575a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
576a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	return type == DBUS_TYPE_INVALID ? TRUE : FALSE;
577a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
578a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
5799fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentzstatic void call_free(struct voice_call *vc)
5809fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz{
5819fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	DBG("%s", vc->obj_path);
5829fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
58303085e6ba3e636e35e0395b694077635a9b0f563Luiz Augusto von Dentz	if (vc->status == CALL_STATUS_ACTIVE)
58403085e6ba3e636e35e0395b694077635a9b0f563Luiz Augusto von Dentz		telephony_update_indicator(ofono_indicators, "call",
58503085e6ba3e636e35e0395b694077635a9b0f563Luiz Augusto von Dentz							EV_CALL_INACTIVE);
58603085e6ba3e636e35e0395b694077635a9b0f563Luiz Augusto von Dentz	else
58703085e6ba3e636e35e0395b694077635a9b0f563Luiz Augusto von Dentz		telephony_update_indicator(ofono_indicators, "callsetup",
58803085e6ba3e636e35e0395b694077635a9b0f563Luiz Augusto von Dentz							EV_CALLSETUP_INACTIVE);
58903085e6ba3e636e35e0395b694077635a9b0f563Luiz Augusto von Dentz
59003085e6ba3e636e35e0395b694077635a9b0f563Luiz Augusto von Dentz	if (vc->status == CALL_STATUS_INCOMING)
59103085e6ba3e636e35e0395b694077635a9b0f563Luiz Augusto von Dentz		telephony_calling_stopped_ind();
59203085e6ba3e636e35e0395b694077635a9b0f563Luiz Augusto von Dentz
5939fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	g_dbus_remove_watch(connection, vc->watch);
5949fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	g_free(vc->obj_path);
5959fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	g_free(vc->number);
5969fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	g_free(vc);
5979fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz}
5989fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
5999fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentzstatic gboolean handle_vc_property_changed(DBusConnection *conn,
6009fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz					DBusMessage *msg, void *data)
6019fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz{
6029fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	struct voice_call *vc = data;
6039fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	const char *obj_path = dbus_message_get_path(msg);
6049fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	DBusMessageIter iter, sub;
6059fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	const char *property, *state;
6069fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
6079fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	DBG("path %s", obj_path);
6089fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
6099fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	dbus_message_iter_init(msg, &iter);
6109fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
6119fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING) {
6129fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		error("Unexpected signature in vc PropertyChanged signal");
6139fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		return TRUE;
6149fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	}
6159fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
6169fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	dbus_message_iter_get_basic(&iter, &property);
6179fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	DBG("property %s", property);
6189fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
6199fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	dbus_message_iter_next(&iter);
6209fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	dbus_message_iter_recurse(&iter, &sub);
6219fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	if (g_str_equal(property, "State")) {
6229fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		dbus_message_iter_get_basic(&sub, &state);
6239fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		DBG("State %s", state);
6249fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		if (g_str_equal(state, "disconnected")) {
6259fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz			calls = g_slist_remove(calls, vc);
6269fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz			call_free(vc);
6279fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		} else if (g_str_equal(state, "active")) {
6289fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz			telephony_update_indicator(ofono_indicators,
6299fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz							"call", EV_CALL_ACTIVE);
6309fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz			telephony_update_indicator(ofono_indicators,
6319fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz							"callsetup",
6329fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz							EV_CALLSETUP_INACTIVE);
6339fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz			if (vc->status == CALL_STATUS_INCOMING)
6349fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz				telephony_calling_stopped_ind();
6359fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz			vc->status = CALL_STATUS_ACTIVE;
6369fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		} else if (g_str_equal(state, "alerting")) {
6379fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz			telephony_update_indicator(ofono_indicators,
6389fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz					"callsetup", EV_CALLSETUP_ALERTING);
6399fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz			vc->status = CALL_STATUS_ALERTING;
6409fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz			vc->originating = TRUE;
6419fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		} else if (g_str_equal(state, "incoming")) {
6429fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz			/* state change from waiting to incoming */
6439fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz			telephony_update_indicator(ofono_indicators,
6449fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz					"callsetup", EV_CALLSETUP_INCOMING);
6459fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz			telephony_incoming_call_ind(vc->number,
6469fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz						NUMBER_TYPE_TELEPHONY);
6479fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz			vc->status = CALL_STATUS_INCOMING;
6489fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz			vc->originating = FALSE;
649d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz		} else if (g_str_equal(state, "held")) {
650d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz			vc->status = CALL_STATUS_HELD;
651d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz			if (find_vc_without_status(CALL_STATUS_HELD))
652d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz				telephony_update_indicator(ofono_indicators,
653d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz							"callheld",
654d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz							EV_CALLHELD_MULTIPLE);
655d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz			else
656d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz				telephony_update_indicator(ofono_indicators,
657d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz							"callheld",
658d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz							EV_CALLHELD_ON_HOLD);
6599fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		}
6609fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	}
6619fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
6629fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	return TRUE;
6639fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz}
6649fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
6659fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentzstatic struct voice_call *call_new(const char *path, DBusMessageIter *properties)
6669fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz{
6679fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	struct voice_call *vc;
6689fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
6699fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	DBG("%s", path);
6709fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
6719fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	vc = g_new0(struct voice_call, 1);
6729fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	vc->obj_path = g_strdup(path);
6739fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	vc->watch = g_dbus_add_signal_watch(connection, NULL, path,
6749fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz					OFONO_VC_INTERFACE, "PropertyChanged",
6759fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz					handle_vc_property_changed, vc, NULL);
6769fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
6779fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	while (dbus_message_iter_get_arg_type(properties)
6789fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz						== DBUS_TYPE_DICT_ENTRY) {
6799fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		DBusMessageIter entry, value;
6809fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		const char *property, *cli, *state;
6819fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
6829fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		dbus_message_iter_recurse(properties, &entry);
6839fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		dbus_message_iter_get_basic(&entry, &property);
6849fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
6859fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		dbus_message_iter_next(&entry);
6869fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		dbus_message_iter_recurse(&entry, &value);
6879fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
6889fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		if (g_str_equal(property, "LineIdentification")) {
6899fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz			dbus_message_iter_get_basic(&value, &cli);
6909fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz			DBG("cli %s", cli);
6919fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz			vc->number = g_strdup(cli);
6929fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		} else if (g_str_equal(property, "State")) {
6939fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz			dbus_message_iter_get_basic(&value, &state);
6949fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz			DBG("state %s", state);
6959fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz			if (g_str_equal(state, "incoming"))
6969fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz				vc->status = CALL_STATUS_INCOMING;
6979fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz			else if (g_str_equal(state, "dialing"))
6989fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz				vc->status = CALL_STATUS_DIALING;
6999fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz			else if (g_str_equal(state, "alerting"))
7009fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz				vc->status = CALL_STATUS_ALERTING;
7019fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz			else if (g_str_equal(state, "waiting"))
7029fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz				vc->status = CALL_STATUS_WAITING;
703d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz			else if (g_str_equal(state, "held"))
704d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz				vc->status = CALL_STATUS_HELD;
7059fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		}
7069fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
7079fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		dbus_message_iter_next(properties);
7089fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	}
7099fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
7109fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	switch (vc->status) {
7119fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	case CALL_STATUS_INCOMING:
7129fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		DBG("CALL_STATUS_INCOMING");
7139fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		vc->originating = FALSE;
7149fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		telephony_update_indicator(ofono_indicators, "callsetup",
7159fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz					EV_CALLSETUP_INCOMING);
7169fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		telephony_incoming_call_ind(vc->number, NUMBER_TYPE_TELEPHONY);
7179fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		break;
7189fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	case CALL_STATUS_DIALING:
7199fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		DBG("CALL_STATUS_DIALING");
7209fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		vc->originating = TRUE;
7219fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		g_free(last_dialed_number);
7229fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		last_dialed_number = g_strdup(vc->number);
7239fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		telephony_update_indicator(ofono_indicators, "callsetup",
7249fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz					EV_CALLSETUP_OUTGOING);
7259fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		break;
7269fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	case CALL_STATUS_ALERTING:
7279fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		DBG("CALL_STATUS_ALERTING");
7289fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		vc->originating = TRUE;
7299fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		g_free(last_dialed_number);
7309fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		last_dialed_number = g_strdup(vc->number);
7319fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		telephony_update_indicator(ofono_indicators, "callsetup",
7329fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz					EV_CALLSETUP_ALERTING);
7339fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		break;
7349fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	case CALL_STATUS_WAITING:
7359fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		DBG("CALL_STATUS_WAITING");
7369fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		vc->originating = FALSE;
7379fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		telephony_update_indicator(ofono_indicators, "callsetup",
7389fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz					EV_CALLSETUP_INCOMING);
7399fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		telephony_call_waiting_ind(vc->number, NUMBER_TYPE_TELEPHONY);
7409fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		break;
7419fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	}
7429fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
7439fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	return vc;
7449fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz}
7459fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
746c49dc8c7c815191b5825896f827cac2e2ff395ffLuiz Augusto von Dentzstatic void remove_pending(DBusPendingCall *call)
747c49dc8c7c815191b5825896f827cac2e2ff395ffLuiz Augusto von Dentz{
748c49dc8c7c815191b5825896f827cac2e2ff395ffLuiz Augusto von Dentz	pending = g_slist_remove(pending, call);
749c49dc8c7c815191b5825896f827cac2e2ff395ffLuiz Augusto von Dentz	dbus_pending_call_unref(call);
750c49dc8c7c815191b5825896f827cac2e2ff395ffLuiz Augusto von Dentz}
751c49dc8c7c815191b5825896f827cac2e2ff395ffLuiz Augusto von Dentz
7529fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentzstatic void call_added(const char *path, DBusMessageIter *properties)
7539fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz{
7549fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	struct voice_call *vc;
7559fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
7569fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	DBG("%s", path);
7579fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
7589fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	vc = find_vc(path);
7599fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	if (vc)
7609fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		return;
7619fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
7629fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	vc = call_new(path, properties);
7639fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	calls = g_slist_prepend(calls, vc);
7649fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz}
7659fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
7669fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentzstatic void get_calls_reply(DBusPendingCall *call, void *user_data)
7679fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz{
7689fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	DBusError err;
7699fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	DBusMessage *reply;
7709fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	DBusMessageIter iter, entry;
7719fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
7729fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	DBG("");
7739fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	reply = dbus_pending_call_steal_reply(call);
7749fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
7759fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	dbus_error_init(&err);
7769fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	if (dbus_set_error_from_message(&err, reply)) {
7779fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		error("ofono replied with an error: %s, %s",
7789fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz				err.name, err.message);
7799fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		dbus_error_free(&err);
7809fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		goto done;
7819fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	}
7829fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
7839fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	dbus_message_iter_init(reply, &iter);
7849fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
7859fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY) {
7869fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		error("Unexpected signature");
7879fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		goto done;
7889fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	}
7899fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
7909fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	dbus_message_iter_recurse(&iter, &entry);
7919fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
7929fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	while (dbus_message_iter_get_arg_type(&entry)
7939fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz						== DBUS_TYPE_STRUCT) {
7949fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		const char *path;
7959fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		DBusMessageIter value, properties;
7969fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
7979fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		dbus_message_iter_recurse(&entry, &value);
7989fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		dbus_message_iter_get_basic(&value, &path);
7999fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
8009fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		dbus_message_iter_next(&value);
8019fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		dbus_message_iter_recurse(&value, &properties);
8029fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
8039fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		call_added(path, &properties);
8049fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
8059fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		dbus_message_iter_next(&entry);
8069fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	}
8079fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
8089fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentzdone:
8099fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	dbus_message_unref(reply);
810c49dc8c7c815191b5825896f827cac2e2ff395ffLuiz Augusto von Dentz	remove_pending(call);
8119fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz}
8129fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
813e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentzstatic void handle_network_property(const char *property, DBusMessageIter *variant)
814a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
81583003660808c30390f21c569a5ba7dbdd8344a41Claudio Takahasi	const char *status, *operator;
816a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	unsigned int signals_bar;
817a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
818a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	if (g_str_equal(property, "Status")) {
819e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz		dbus_message_iter_get_basic(variant, &status);
8208e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan		DBG("Status is %s", status);
821a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		if (g_str_equal(status, "registered")) {
822a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			net.status = NETWORK_REG_STATUS_HOME;
823a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			telephony_update_indicator(ofono_indicators,
824a34c155f55270b917795d003be24488f53d9b711Forrest Zhao						"roam", EV_ROAM_INACTIVE);
825a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			telephony_update_indicator(ofono_indicators,
826a34c155f55270b917795d003be24488f53d9b711Forrest Zhao						"service", EV_SERVICE_PRESENT);
827a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		} else if (g_str_equal(status, "roaming")) {
828a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			net.status = NETWORK_REG_STATUS_ROAM;
829a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			telephony_update_indicator(ofono_indicators,
830a34c155f55270b917795d003be24488f53d9b711Forrest Zhao						"roam", EV_ROAM_ACTIVE);
831a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			telephony_update_indicator(ofono_indicators,
832a34c155f55270b917795d003be24488f53d9b711Forrest Zhao						"service", EV_SERVICE_PRESENT);
833a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		} else {
834a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			net.status = NETWORK_REG_STATUS_NOSERV;
835a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			telephony_update_indicator(ofono_indicators,
836a34c155f55270b917795d003be24488f53d9b711Forrest Zhao						"roam", EV_ROAM_INACTIVE);
837a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			telephony_update_indicator(ofono_indicators,
838a34c155f55270b917795d003be24488f53d9b711Forrest Zhao						"service", EV_SERVICE_NONE);
839a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		}
840e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	} else if (g_str_equal(property, "Name")) {
841e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz		dbus_message_iter_get_basic(variant, &operator);
8428e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan		DBG("Operator is %s", operator);
843a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		g_free(net.operator_name);
844a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		net.operator_name = g_strdup(operator);
845a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	} else if (g_str_equal(property, "SignalStrength")) {
846e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz		dbus_message_iter_get_basic(variant, &signals_bar);
8478e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan		DBG("SignalStrength is %d", signals_bar);
848a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		net.signals_bar = signals_bar;
849a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		telephony_update_indicator(ofono_indicators, "signal",
850a34c155f55270b917795d003be24488f53d9b711Forrest Zhao						(signals_bar + 20) / 21);
851a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	}
852a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
853a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
854e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentzstatic int parse_network_properties(DBusMessageIter *properties)
855a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
856a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	uint32_t features = AG_FEATURE_EC_ANDOR_NR |
8575e072a21aa4d68fdcfa605ef31427411c643e8bdLuiz Augusto von Dentz				AG_FEATURE_INBAND_RINGTONE |
858a34c155f55270b917795d003be24488f53d9b711Forrest Zhao				AG_FEATURE_REJECT_A_CALL |
859a34c155f55270b917795d003be24488f53d9b711Forrest Zhao				AG_FEATURE_ENHANCED_CALL_STATUS |
860d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz				AG_FEATURE_ENHANCED_CALL_CONTROL |
861a34c155f55270b917795d003be24488f53d9b711Forrest Zhao				AG_FEATURE_EXTENDED_ERROR_RESULT_CODES;
862a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
863e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	while (dbus_message_iter_get_arg_type(properties)
864e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz						== DBUS_TYPE_DICT_ENTRY) {
865e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz		const char *key;
866e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz		DBusMessageIter value, entry;
867e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz
868e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz		dbus_message_iter_recurse(properties, &entry);
869e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz		dbus_message_iter_get_basic(&entry, &key);
870e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz
871e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz		dbus_message_iter_next(&entry);
872e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz		dbus_message_iter_recurse(&entry, &value);
873e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz
874e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz		handle_network_property(key, &value);
875e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz
876e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz		dbus_message_iter_next(properties);
877e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	}
878e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz
879e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	telephony_ready_ind(features, ofono_indicators, BTRH_NOT_SUPPORTED,
880e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz								chld_str);
881e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz
882e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	return 0;
883e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz}
884e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz
885e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentzstatic void get_properties_reply(DBusPendingCall *call, void *user_data)
886e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz{
887e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	DBusError err;
888e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	DBusMessage *reply;
889e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	DBusMessageIter iter, properties;
890e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	int ret = 0;
891e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz
892e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	DBG("");
893a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	reply = dbus_pending_call_steal_reply(call);
894a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
895a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	dbus_error_init(&err);
896a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	if (dbus_set_error_from_message(&err, reply)) {
897a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		error("ofono replied with an error: %s, %s",
898a34c155f55270b917795d003be24488f53d9b711Forrest Zhao				err.name, err.message);
899a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		dbus_error_free(&err);
900a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		goto done;
901a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	}
902a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
903a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	dbus_message_iter_init(reply, &iter);
904a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
905a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY) {
906e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz		error("Unexpected signature");
907a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		goto done;
908a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	}
909a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
910e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	dbus_message_iter_recurse(&iter, &properties);
911a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
912e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	ret = parse_network_properties(&properties);
9139fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	if (ret < 0) {
914e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz		error("Unable to parse %s.GetProperty reply",
915e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz						OFONO_NETWORKREG_INTERFACE);
9169fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		goto done;
9179fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	}
9189fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
9199fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	ret = send_method_call(OFONO_BUS_NAME, modem_obj_path,
9209fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz				OFONO_VCMANAGER_INTERFACE, "GetCalls",
9219fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz				get_calls_reply, NULL, DBUS_TYPE_INVALID);
9229fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	if (ret < 0)
9239fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		error("Unable to send %s.GetCalls",
9249fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz						OFONO_VCMANAGER_INTERFACE);
925a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
926a34c155f55270b917795d003be24488f53d9b711Forrest Zhaodone:
927a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	dbus_message_unref(reply);
928c49dc8c7c815191b5825896f827cac2e2ff395ffLuiz Augusto von Dentz	remove_pending(call);
929a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
930a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
931806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentzstatic void network_found(const char *path)
932a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
933e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	int ret;
934c5321032b046c39477ab99a05e933b13d0b67a04Forrest Zhao
935e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	DBG("%s", path);
936e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz
937e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	modem_obj_path = g_strdup(path);
938e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz
939e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	ret = send_method_call(OFONO_BUS_NAME, path,
940e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz				OFONO_NETWORKREG_INTERFACE, "GetProperties",
941e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz				get_properties_reply, NULL, DBUS_TYPE_INVALID);
942e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	if (ret < 0)
943e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz		error("Unable to send %s.GetProperties",
944e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz						OFONO_NETWORKREG_INTERFACE);
945a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
946a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
947806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentzstatic void modem_removed(const char *path)
948806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz{
949806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	if (g_strcmp0(modem_obj_path, path) != 0)
950806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		return;
951806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
952806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	DBG("%s", path);
953806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
954806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	g_slist_foreach(calls, (GFunc) call_free, NULL);
955806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	g_slist_free(calls);
956806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	calls = NULL;
957806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
958806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	g_free(net.operator_name);
959806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	net.operator_name = NULL;
960806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
961806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	g_free(modem_obj_path);
962806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	modem_obj_path = NULL;
963806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz}
964806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
965806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentzstatic void parse_modem_interfaces(const char *path, DBusMessageIter *ifaces)
966806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz{
967806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	DBG("%s", path);
968806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
969806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	while (dbus_message_iter_get_arg_type(ifaces) == DBUS_TYPE_STRING) {
970806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		const char *iface;
971806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
972806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		dbus_message_iter_get_basic(ifaces, &iface);
973806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
974806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		if (g_str_equal(iface, OFONO_NETWORKREG_INTERFACE)) {
975806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz			network_found(path);
976806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz			return;
977806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		}
978806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
979806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		dbus_message_iter_next(ifaces);
980806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	}
981806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
982806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	modem_removed(path);
983806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz}
984806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
985806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentzstatic void modem_added(const char *path, DBusMessageIter *properties)
986806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz{
987806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	if (modem_obj_path != NULL) {
988806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		DBG("Ignoring, modem already exist");
989806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		return;
990806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	}
991806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
992806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	DBG("%s", path);
993806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
994806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	while (dbus_message_iter_get_arg_type(properties)
995806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz						== DBUS_TYPE_DICT_ENTRY) {
996806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		const char *key;
997806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		DBusMessageIter interfaces, value, entry;
998806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
999806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		dbus_message_iter_recurse(properties, &entry);
1000806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		dbus_message_iter_get_basic(&entry, &key);
1001806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
1002806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		dbus_message_iter_next(&entry);
1003806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		dbus_message_iter_recurse(&entry, &value);
1004806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
1005806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		if (strcasecmp(key, "Interfaces") != 0)
1006806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz			goto next;
1007806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
1008806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		if (dbus_message_iter_get_arg_type(&value)
1009806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz							!= DBUS_TYPE_ARRAY) {
1010806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz			error("Invalid Signature");
1011806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz			return;
1012806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		}
1013806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
1014806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		dbus_message_iter_recurse(&value, &interfaces);
1015806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
1016806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		parse_modem_interfaces(path, &interfaces);
1017806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
1018806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		if (modem_obj_path != NULL)
1019806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz			return;
1020806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
1021806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	next:
1022806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		dbus_message_iter_next(properties);
1023806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	}
1024806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz}
1025806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
1026e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentzstatic void get_modems_reply(DBusPendingCall *call, void *user_data)
1027a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
1028a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	DBusError err;
1029a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	DBusMessage *reply;
1030e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	DBusMessageIter iter, entry;
1031a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
10328e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan	DBG("list_modem_reply is called\n");
1033a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	reply = dbus_pending_call_steal_reply(call);
1034a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1035a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	dbus_error_init(&err);
1036a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	if (dbus_set_error_from_message(&err, reply)) {
1037a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		error("ofono replied with an error: %s, %s",
1038a34c155f55270b917795d003be24488f53d9b711Forrest Zhao				err.name, err.message);
1039a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		dbus_error_free(&err);
1040a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		goto done;
1041a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	}
1042a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1043806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	/* Skip modem selection if a modem already exist */
1044806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	if (modem_obj_path != NULL)
1045806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		goto done;
1046806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
1047a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	dbus_message_iter_init(reply, &iter);
1048a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1049a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY) {
1050e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz		error("Unexpected signature");
1051a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		goto done;
1052a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	}
1053a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1054e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	dbus_message_iter_recurse(&iter, &entry);
1055a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1056806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	while (dbus_message_iter_get_arg_type(&entry)
1057806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz						== DBUS_TYPE_STRUCT) {
1058806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		const char *path;
1059806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		DBusMessageIter item, properties;
1060806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
1061806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		dbus_message_iter_recurse(&entry, &item);
1062806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		dbus_message_iter_get_basic(&item, &path);
1063806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
1064806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		dbus_message_iter_next(&item);
1065806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		dbus_message_iter_recurse(&item, &properties);
1066a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1067806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		modem_added(path, &properties);
1068806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		if (modem_obj_path != NULL)
1069806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz			break;
1070a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1071806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		dbus_message_iter_next(&entry);
1072806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	}
1073a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1074a34c155f55270b917795d003be24488f53d9b711Forrest Zhaodone:
1075a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	dbus_message_unref(reply);
1076c49dc8c7c815191b5825896f827cac2e2ff395ffLuiz Augusto von Dentz	remove_pending(call);
1077a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
1078a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1079e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentzstatic gboolean handle_network_property_changed(DBusConnection *conn,
10808309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz						DBusMessage *msg, void *data)
1081a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
1082e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	DBusMessageIter iter, variant;
1083a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	const char *property;
1084a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1085a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	dbus_message_iter_init(msg, &iter);
1086a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1087a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING) {
1088a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		error("Unexpected signature in networkregistration"
1089a34c155f55270b917795d003be24488f53d9b711Forrest Zhao					" PropertyChanged signal");
10908309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz		return TRUE;
1091a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	}
1092a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	dbus_message_iter_get_basic(&iter, &property);
10938e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan	DBG("in handle_registration_property_changed(),"
1094a34c155f55270b917795d003be24488f53d9b711Forrest Zhao					" the property is %s", property);
1095a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1096a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	dbus_message_iter_next(&iter);
1097e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	dbus_message_iter_recurse(&iter, &variant);
1098a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1099e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	handle_network_property(property, &variant);
11008309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz
11018309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	return TRUE;
1102a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
1103a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1104806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentzstatic void handle_modem_property(const char *path, const char *property,
1105806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz						DBusMessageIter *variant)
1106806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz{
1107806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	DBG("%s", property);
1108806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
1109806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	if (g_str_equal(property, "Interfaces")) {
1110806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		DBusMessageIter interfaces;
1111806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
1112806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		if (dbus_message_iter_get_arg_type(variant)
1113806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz							!= DBUS_TYPE_ARRAY) {
1114806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz			error("Invalid signature");
1115806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz			return;
1116806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		}
1117806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
1118806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		dbus_message_iter_recurse(variant, &interfaces);
1119806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		parse_modem_interfaces(path, &interfaces);
1120806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	}
1121806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz}
1122806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
1123806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentzstatic gboolean handle_modem_property_changed(DBusConnection *conn,
1124806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz						DBusMessage *msg, void *data)
1125806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz{
1126806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	DBusMessageIter iter, variant;
1127806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	const char *property, *path;
1128806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
1129806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	path = dbus_message_get_path(msg);
1130806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
1131806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	/* Ignore if modem already exist and paths doesn't match */
1132806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	if (modem_obj_path != NULL &&
1133806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz				g_str_equal(path, modem_obj_path) == FALSE)
1134806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		return TRUE;
1135806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
1136806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	dbus_message_iter_init(msg, &iter);
1137806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
1138806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING) {
1139806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		error("Unexpected signature in %s.%s PropertyChanged signal",
1140806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz					dbus_message_get_interface(msg),
1141806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz					dbus_message_get_member(msg));
1142806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		return TRUE;
1143806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	}
1144806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
1145806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	dbus_message_iter_get_basic(&iter, &property);
1146806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
1147806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	dbus_message_iter_next(&iter);
1148806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	dbus_message_iter_recurse(&iter, &variant);
1149806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
1150806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	handle_modem_property(path, property, &variant);
1151806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
1152806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	return TRUE;
1153806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz}
1154806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
11559fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentzstatic gboolean handle_vcmanager_call_added(DBusConnection *conn,
11569fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz						DBusMessage *msg, void *data)
1157a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
11589fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	DBusMessageIter iter, properties;
11599fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	const char *path = dbus_message_get_path(msg);
1160a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
11619fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	/* Ignore call if modem path doesn't math */
11629fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	if (g_strcmp0(modem_obj_path, path) != 0)
11639fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		return TRUE;
1164a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
11659fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	dbus_message_iter_init(msg, &iter);
1166a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
11679fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	if (dbus_message_iter_get_arg_type(&iter)
11689fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz						!= DBUS_TYPE_OBJECT_PATH) {
11699fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		error("Unexpected signature in %s.%s signal",
11709fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz					dbus_message_get_interface(msg),
11719fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz					dbus_message_get_member(msg));
11729fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		return TRUE;
1173a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	}
1174a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
11759fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	dbus_message_iter_get_basic(&iter, &path);
11769fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	dbus_message_iter_next(&iter);
11779fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	dbus_message_iter_recurse(&iter, &properties);
1178a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
11799fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	call_added(path, &properties);
1180a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
11819fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	return TRUE;
1182a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
1183a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
11849fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentzstatic void call_removed(const char *path)
1185a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
11869fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	struct voice_call *vc;
1187a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
11889fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	DBG("%s", path);
1189a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
11909fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	vc = find_vc(path);
11919fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	if (vc == NULL)
11929fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		return;
11938309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz
11949fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	calls = g_slist_remove(calls, vc);
11959fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	call_free(vc);
11968309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz}
11978309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz
11989fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentzstatic gboolean handle_vcmanager_call_removed(DBusConnection *conn,
11998309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz						DBusMessage *msg, void *data)
12008309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz{
12019fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	const char *path = dbus_message_get_path(msg);
12028309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz
12039fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	/* Ignore call if modem path doesn't math */
12049fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	if (g_strcmp0(modem_obj_path, path) != 0)
12058309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz		return TRUE;
12068309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz
12079fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	if (!dbus_message_get_args(msg, NULL,
12089fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz				DBUS_TYPE_OBJECT_PATH, &path,
12099fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz				DBUS_TYPE_INVALID)) {
12109fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		error("Unexpected signature in %s.%s signal",
12119fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz					dbus_message_get_interface(msg),
12129fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz					dbus_message_get_member(msg));
12138309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz		return TRUE;
12148309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	}
12158309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz
12169fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	call_removed(path);
12178309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz
12188309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	return TRUE;
1219a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
1220a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1221e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentzstatic gboolean handle_manager_modem_added(DBusConnection *conn,
1222e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz						DBusMessage *msg, void *data)
1223e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz{
1224e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	DBusMessageIter iter, properties;
1225e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	const char *path;
1226e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz
1227e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	if (modem_obj_path != NULL)
1228e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz		return TRUE;
1229e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz
1230e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	dbus_message_iter_init(msg, &iter);
1231e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz
1232e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	if (dbus_message_iter_get_arg_type(&iter)
1233e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz						!= DBUS_TYPE_OBJECT_PATH) {
1234e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz		error("Unexpected signature in %s.%s signal",
1235e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz					dbus_message_get_interface(msg),
1236e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz					dbus_message_get_member(msg));
1237e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz		return TRUE;
1238e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	}
1239e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz
1240e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	dbus_message_iter_get_basic(&iter, &path);
1241806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	dbus_message_iter_next(&iter);
1242e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	dbus_message_iter_recurse(&iter, &properties);
1243e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz
1244806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	modem_added(path, &properties);
1245e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz
1246e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	return TRUE;
1247e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz}
1248e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz
1249e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentzstatic gboolean handle_manager_modem_removed(DBusConnection *conn,
1250e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz						DBusMessage *msg, void *data)
1251e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz{
1252e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	const char *path;
1253e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz
1254e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	if (!dbus_message_get_args(msg, NULL,
1255e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz				DBUS_TYPE_OBJECT_PATH, &path,
1256e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz				DBUS_TYPE_INVALID)) {
1257e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz		error("Unexpected signature in %s.%s signal",
1258e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz					dbus_message_get_interface(msg),
1259e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz					dbus_message_get_member(msg));
1260e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz		return TRUE;
1261e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	}
1262e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz
1263e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	modem_removed(path);
1264e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz
1265e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	return TRUE;
1266e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz}
1267e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz
1268a34c155f55270b917795d003be24488f53d9b711Forrest Zhaostatic void hal_battery_level_reply(DBusPendingCall *call, void *user_data)
1269a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
1270a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	DBusMessage *reply;
1271a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	DBusError err;
1272a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	dbus_int32_t level;
1273a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	int *value = user_data;
1274a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1275a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	reply = dbus_pending_call_steal_reply(call);
1276a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1277a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	dbus_error_init(&err);
1278a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	if (dbus_set_error_from_message(&err, reply)) {
1279a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		error("hald replied with an error: %s, %s",
1280a34c155f55270b917795d003be24488f53d9b711Forrest Zhao				err.name, err.message);
1281a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		dbus_error_free(&err);
1282a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		goto done;
1283a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	}
1284a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1285463763c080cd72ecd727a218dd68f7c0ba95bc9eLuiz Augusto von Dentz	dbus_error_init(&err);
1286463763c080cd72ecd727a218dd68f7c0ba95bc9eLuiz Augusto von Dentz	if (dbus_message_get_args(reply, &err,
1287a34c155f55270b917795d003be24488f53d9b711Forrest Zhao				DBUS_TYPE_INT32, &level,
1288463763c080cd72ecd727a218dd68f7c0ba95bc9eLuiz Augusto von Dentz				DBUS_TYPE_INVALID) == FALSE) {
1289463763c080cd72ecd727a218dd68f7c0ba95bc9eLuiz Augusto von Dentz		error("Unable to parse GetPropertyInteger reply: %s, %s",
1290463763c080cd72ecd727a218dd68f7c0ba95bc9eLuiz Augusto von Dentz							err.name, err.message);
1291463763c080cd72ecd727a218dd68f7c0ba95bc9eLuiz Augusto von Dentz		dbus_error_free(&err);
1292463763c080cd72ecd727a218dd68f7c0ba95bc9eLuiz Augusto von Dentz		goto done;
1293463763c080cd72ecd727a218dd68f7c0ba95bc9eLuiz Augusto von Dentz	}
1294a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1295a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	*value = (int) level;
1296a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1297a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	if (value == &battchg_last)
12988e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan		DBG("telephony-ofono: battery.charge_level.last_full"
1299a34c155f55270b917795d003be24488f53d9b711Forrest Zhao					" is %d", *value);
1300a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	else if (value == &battchg_design)
13018e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan		DBG("telephony-ofono: battery.charge_level.design"
1302a34c155f55270b917795d003be24488f53d9b711Forrest Zhao					" is %d", *value);
1303a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	else
13048e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan		DBG("telephony-ofono: battery.charge_level.current"
1305a34c155f55270b917795d003be24488f53d9b711Forrest Zhao					" is %d", *value);
1306a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1307a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	if ((battchg_design > 0 || battchg_last > 0) && battchg_cur >= 0) {
13089ff86aa7f2c11cb3198dfcde93f8db3c534ecdb6Johan Hedberg		int new, max;
1309a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1310a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		if (battchg_last > 0)
1311a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			max = battchg_last;
1312a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		else
1313a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			max = battchg_design;
1314a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1315a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		new = battchg_cur * 5 / max;
1316a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
13179ff86aa7f2c11cb3198dfcde93f8db3c534ecdb6Johan Hedberg		telephony_update_indicator(ofono_indicators, "battchg", new);
1318a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	}
1319a34c155f55270b917795d003be24488f53d9b711Forrest Zhaodone:
1320a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	dbus_message_unref(reply);
1321c49dc8c7c815191b5825896f827cac2e2ff395ffLuiz Augusto von Dentz	remove_pending(call);
1322a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
1323a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1324a34c155f55270b917795d003be24488f53d9b711Forrest Zhaostatic void hal_get_integer(const char *path, const char *key, void *user_data)
1325a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
1326a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	send_method_call("org.freedesktop.Hal", path,
1327a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			"org.freedesktop.Hal.Device",
1328a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			"GetPropertyInteger",
1329a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			hal_battery_level_reply, user_data,
1330a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			DBUS_TYPE_STRING, &key,
1331a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			DBUS_TYPE_INVALID);
1332a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
1333a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
13348309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentzstatic gboolean handle_hal_property_modified(DBusConnection *conn,
13358309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz						DBusMessage *msg, void *data)
1336a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
1337a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	const char *path;
1338a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	DBusMessageIter iter, array;
1339a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	dbus_int32_t num_changes;
1340a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1341a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	path = dbus_message_get_path(msg);
1342a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1343a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	dbus_message_iter_init(msg, &iter);
1344a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1345a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_INT32) {
1346a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		error("Unexpected signature in hal PropertyModified signal");
13478309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz		return TRUE;
1348a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	}
1349a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1350a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	dbus_message_iter_get_basic(&iter, &num_changes);
1351a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	dbus_message_iter_next(&iter);
1352a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1353a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY) {
1354a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		error("Unexpected signature in hal PropertyModified signal");
13558309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz		return TRUE;
1356a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	}
1357a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1358a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	dbus_message_iter_recurse(&iter, &array);
1359a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1360a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	while (dbus_message_iter_get_arg_type(&array) != DBUS_TYPE_INVALID) {
1361a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		DBusMessageIter prop;
1362a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		const char *name;
1363a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		dbus_bool_t added, removed;
1364a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1365a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		dbus_message_iter_recurse(&array, &prop);
1366a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1367a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		if (!iter_get_basic_args(&prop,
1368a34c155f55270b917795d003be24488f53d9b711Forrest Zhao					DBUS_TYPE_STRING, &name,
1369a34c155f55270b917795d003be24488f53d9b711Forrest Zhao					DBUS_TYPE_BOOLEAN, &added,
1370a34c155f55270b917795d003be24488f53d9b711Forrest Zhao					DBUS_TYPE_BOOLEAN, &removed,
1371a34c155f55270b917795d003be24488f53d9b711Forrest Zhao					DBUS_TYPE_INVALID)) {
1372a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			error("Invalid hal PropertyModified parameters");
1373a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			break;
1374a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		}
1375a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1376a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		if (g_str_equal(name, "battery.charge_level.last_full"))
1377a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			hal_get_integer(path, name, &battchg_last);
1378a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		else if (g_str_equal(name, "battery.charge_level.current"))
1379a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			hal_get_integer(path, name, &battchg_cur);
1380a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		else if (g_str_equal(name, "battery.charge_level.design"))
1381a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			hal_get_integer(path, name, &battchg_design);
1382a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1383a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		dbus_message_iter_next(&array);
1384a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	}
13858309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz
13868309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	return TRUE;
1387a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
1388a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
13899946e8636c3361dc769c5f8a463b74158018d3ddLuiz Augusto von Dentzstatic void add_watch(const char *sender, const char *path,
13909946e8636c3361dc769c5f8a463b74158018d3ddLuiz Augusto von Dentz				const char *interface, const char *member,
13919946e8636c3361dc769c5f8a463b74158018d3ddLuiz Augusto von Dentz				GDBusSignalFunction function)
13929946e8636c3361dc769c5f8a463b74158018d3ddLuiz Augusto von Dentz{
13939946e8636c3361dc769c5f8a463b74158018d3ddLuiz Augusto von Dentz	guint watch;
13949946e8636c3361dc769c5f8a463b74158018d3ddLuiz Augusto von Dentz
13959946e8636c3361dc769c5f8a463b74158018d3ddLuiz Augusto von Dentz	watch = g_dbus_add_signal_watch(connection, sender, path, interface,
13969946e8636c3361dc769c5f8a463b74158018d3ddLuiz Augusto von Dentz					member, function, NULL, NULL);
13979946e8636c3361dc769c5f8a463b74158018d3ddLuiz Augusto von Dentz
13989946e8636c3361dc769c5f8a463b74158018d3ddLuiz Augusto von Dentz	watches = g_slist_prepend(watches, GUINT_TO_POINTER(watch));
13999946e8636c3361dc769c5f8a463b74158018d3ddLuiz Augusto von Dentz}
14009946e8636c3361dc769c5f8a463b74158018d3ddLuiz Augusto von Dentz
14018309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentzstatic void hal_find_device_reply(DBusPendingCall *call, void *user_data)
1402a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
14038309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	DBusMessage *reply;
14048309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	DBusError err;
14058309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	DBusMessageIter iter, sub;
14068309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	int type;
14078309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	const char *path;
14088309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz
14098e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan	DBG("begin of hal_find_device_reply()");
14108309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	reply = dbus_pending_call_steal_reply(call);
14118309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz
14128309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	dbus_error_init(&err);
14138309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz
14148309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	if (dbus_set_error_from_message(&err, reply)) {
14158309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz		error("hald replied with an error: %s, %s",
14168309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz				err.name, err.message);
14178309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz		dbus_error_free(&err);
14188309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz		goto done;
14198309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	}
14208309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz
14218309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	dbus_message_iter_init(reply, &iter);
14228309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz
14238309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY) {
14248309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz		error("Unexpected signature in hal_find_device_reply()");
14258309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz		goto done;
14268309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	}
14278309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz
14288309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	dbus_message_iter_recurse(&iter, &sub);
14298309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz
14308309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	type = dbus_message_iter_get_arg_type(&sub);
14318309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz
14328309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	if (type != DBUS_TYPE_OBJECT_PATH && type != DBUS_TYPE_STRING) {
14338309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz		error("No hal device with battery capability found");
14348309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz		goto done;
14358309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	}
14368309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz
14378309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	dbus_message_iter_get_basic(&sub, &path);
14388309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz
14398e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan	DBG("telephony-ofono: found battery device at %s", path);
14408309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz
14419946e8636c3361dc769c5f8a463b74158018d3ddLuiz Augusto von Dentz	add_watch(NULL, path, "org.freedesktop.Hal.Device",
14429946e8636c3361dc769c5f8a463b74158018d3ddLuiz Augusto von Dentz			"PropertyModified", handle_hal_property_modified);
14438309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz
14448309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	hal_get_integer(path, "battery.charge_level.last_full", &battchg_last);
14458309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	hal_get_integer(path, "battery.charge_level.current", &battchg_cur);
14468309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	hal_get_integer(path, "battery.charge_level.design", &battchg_design);
14478309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentzdone:
14488309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	dbus_message_unref(reply);
1449c49dc8c7c815191b5825896f827cac2e2ff395ffLuiz Augusto von Dentz	remove_pending(call);
1450a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
1451a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1452c7b0c8e099b8fdfa1ad2a905d6f482beb3aaddaaLuiz Augusto von Dentzstatic void handle_service_connect(DBusConnection *conn, void *user_data)
1453c7b0c8e099b8fdfa1ad2a905d6f482beb3aaddaaLuiz Augusto von Dentz{
1454c7b0c8e099b8fdfa1ad2a905d6f482beb3aaddaaLuiz Augusto von Dentz	DBG("telephony-ofono: %s found", OFONO_BUS_NAME);
1455c7b0c8e099b8fdfa1ad2a905d6f482beb3aaddaaLuiz Augusto von Dentz
1456c7b0c8e099b8fdfa1ad2a905d6f482beb3aaddaaLuiz Augusto von Dentz	send_method_call(OFONO_BUS_NAME, OFONO_PATH,
1457c7b0c8e099b8fdfa1ad2a905d6f482beb3aaddaaLuiz Augusto von Dentz				OFONO_MANAGER_INTERFACE, "GetModems",
1458c7b0c8e099b8fdfa1ad2a905d6f482beb3aaddaaLuiz Augusto von Dentz				get_modems_reply, NULL, DBUS_TYPE_INVALID);
1459c7b0c8e099b8fdfa1ad2a905d6f482beb3aaddaaLuiz Augusto von Dentz}
1460c7b0c8e099b8fdfa1ad2a905d6f482beb3aaddaaLuiz Augusto von Dentz
1461c7b0c8e099b8fdfa1ad2a905d6f482beb3aaddaaLuiz Augusto von Dentzstatic void handle_service_disconnect(DBusConnection *conn, void *user_data)
1462c7b0c8e099b8fdfa1ad2a905d6f482beb3aaddaaLuiz Augusto von Dentz{
1463c7b0c8e099b8fdfa1ad2a905d6f482beb3aaddaaLuiz Augusto von Dentz	DBG("telephony-ofono: %s exitted", OFONO_BUS_NAME);
1464c7b0c8e099b8fdfa1ad2a905d6f482beb3aaddaaLuiz Augusto von Dentz
1465c7b0c8e099b8fdfa1ad2a905d6f482beb3aaddaaLuiz Augusto von Dentz	if (modem_obj_path)
1466c7b0c8e099b8fdfa1ad2a905d6f482beb3aaddaaLuiz Augusto von Dentz		modem_removed(modem_obj_path);
1467c7b0c8e099b8fdfa1ad2a905d6f482beb3aaddaaLuiz Augusto von Dentz}
1468c7b0c8e099b8fdfa1ad2a905d6f482beb3aaddaaLuiz Augusto von Dentz
1469a34c155f55270b917795d003be24488f53d9b711Forrest Zhaoint telephony_init(void)
1470a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
1471a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	const char *battery_cap = "battery";
1472a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	int ret;
1473c7b0c8e099b8fdfa1ad2a905d6f482beb3aaddaaLuiz Augusto von Dentz	guint watch;
1474a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1475a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	connection = dbus_bus_get(DBUS_BUS_SYSTEM, NULL);
1476a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1477806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	add_watch(OFONO_BUS_NAME, NULL, OFONO_MODEM_INTERFACE,
1478806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz			"PropertyChanged", handle_modem_property_changed);
14799946e8636c3361dc769c5f8a463b74158018d3ddLuiz Augusto von Dentz	add_watch(OFONO_BUS_NAME, NULL, OFONO_NETWORKREG_INTERFACE,
14809946e8636c3361dc769c5f8a463b74158018d3ddLuiz Augusto von Dentz			"PropertyChanged", handle_network_property_changed);
14819946e8636c3361dc769c5f8a463b74158018d3ddLuiz Augusto von Dentz	add_watch(OFONO_BUS_NAME, NULL, OFONO_MANAGER_INTERFACE,
14829946e8636c3361dc769c5f8a463b74158018d3ddLuiz Augusto von Dentz			"ModemAdded", handle_manager_modem_added);
14839946e8636c3361dc769c5f8a463b74158018d3ddLuiz Augusto von Dentz	add_watch(OFONO_BUS_NAME, NULL, OFONO_MANAGER_INTERFACE,
14849946e8636c3361dc769c5f8a463b74158018d3ddLuiz Augusto von Dentz			"ModemRemoved", handle_manager_modem_removed);
14859946e8636c3361dc769c5f8a463b74158018d3ddLuiz Augusto von Dentz	add_watch(OFONO_BUS_NAME, NULL, OFONO_VCMANAGER_INTERFACE,
14869946e8636c3361dc769c5f8a463b74158018d3ddLuiz Augusto von Dentz			"CallAdded", handle_vcmanager_call_added);
14879946e8636c3361dc769c5f8a463b74158018d3ddLuiz Augusto von Dentz	add_watch(OFONO_BUS_NAME, NULL, OFONO_VCMANAGER_INTERFACE,
14889946e8636c3361dc769c5f8a463b74158018d3ddLuiz Augusto von Dentz			"CallRemoved", handle_vcmanager_call_removed);
1489a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1490c7b0c8e099b8fdfa1ad2a905d6f482beb3aaddaaLuiz Augusto von Dentz	watch = g_dbus_add_service_watch(connection, OFONO_BUS_NAME,
1491c7b0c8e099b8fdfa1ad2a905d6f482beb3aaddaaLuiz Augusto von Dentz						handle_service_connect,
1492c7b0c8e099b8fdfa1ad2a905d6f482beb3aaddaaLuiz Augusto von Dentz						handle_service_disconnect,
1493c7b0c8e099b8fdfa1ad2a905d6f482beb3aaddaaLuiz Augusto von Dentz						NULL, NULL);
1494c7b0c8e099b8fdfa1ad2a905d6f482beb3aaddaaLuiz Augusto von Dentz	if (watch == 0)
1495c7b0c8e099b8fdfa1ad2a905d6f482beb3aaddaaLuiz Augusto von Dentz		return -ENOMEM;
1496c7b0c8e099b8fdfa1ad2a905d6f482beb3aaddaaLuiz Augusto von Dentz
1497c7b0c8e099b8fdfa1ad2a905d6f482beb3aaddaaLuiz Augusto von Dentz	watches = g_slist_prepend(watches, GUINT_TO_POINTER(watch));
1498a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1499a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	ret = send_method_call("org.freedesktop.Hal",
1500a34c155f55270b917795d003be24488f53d9b711Forrest Zhao				"/org/freedesktop/Hal/Manager",
1501a34c155f55270b917795d003be24488f53d9b711Forrest Zhao				"org.freedesktop.Hal.Manager",
1502a34c155f55270b917795d003be24488f53d9b711Forrest Zhao				"FindDeviceByCapability",
1503a34c155f55270b917795d003be24488f53d9b711Forrest Zhao				hal_find_device_reply, NULL,
1504a34c155f55270b917795d003be24488f53d9b711Forrest Zhao				DBUS_TYPE_STRING, &battery_cap,
1505a34c155f55270b917795d003be24488f53d9b711Forrest Zhao				DBUS_TYPE_INVALID);
1506a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	if (ret < 0)
1507a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		return ret;
1508a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
15098e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan	DBG("telephony_init() successfully");
1510a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1511a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	return ret;
1512a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
1513a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
15149946e8636c3361dc769c5f8a463b74158018d3ddLuiz Augusto von Dentzstatic void remove_watch(gpointer data)
15159946e8636c3361dc769c5f8a463b74158018d3ddLuiz Augusto von Dentz{
15169946e8636c3361dc769c5f8a463b74158018d3ddLuiz Augusto von Dentz	g_dbus_remove_watch(connection, GPOINTER_TO_UINT(data));
15179946e8636c3361dc769c5f8a463b74158018d3ddLuiz Augusto von Dentz}
15189946e8636c3361dc769c5f8a463b74158018d3ddLuiz Augusto von Dentz
1519a34c155f55270b917795d003be24488f53d9b711Forrest Zhaovoid telephony_exit(void)
1520a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
1521e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	DBG("");
1522a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1523a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	g_free(last_dialed_number);
1524e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	last_dialed_number = NULL;
1525a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1526e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	if (modem_obj_path)
1527e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz		modem_removed(modem_obj_path);
1528a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
15299946e8636c3361dc769c5f8a463b74158018d3ddLuiz Augusto von Dentz	g_slist_foreach(watches, (GFunc) remove_watch, NULL);
15309946e8636c3361dc769c5f8a463b74158018d3ddLuiz Augusto von Dentz	g_slist_free(watches);
15319946e8636c3361dc769c5f8a463b74158018d3ddLuiz Augusto von Dentz	watches = NULL;
1532a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1533c49dc8c7c815191b5825896f827cac2e2ff395ffLuiz Augusto von Dentz	g_slist_foreach(pending, (GFunc) dbus_pending_call_cancel, NULL);
1534c49dc8c7c815191b5825896f827cac2e2ff395ffLuiz Augusto von Dentz	g_slist_foreach(pending, (GFunc) dbus_pending_call_unref, NULL);
1535c49dc8c7c815191b5825896f827cac2e2ff395ffLuiz Augusto von Dentz	g_slist_free(pending);
1536c49dc8c7c815191b5825896f827cac2e2ff395ffLuiz Augusto von Dentz	pending = NULL;
1537c49dc8c7c815191b5825896f827cac2e2ff395ffLuiz Augusto von Dentz
1538a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	dbus_connection_unref(connection);
1539a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	connection = NULL;
1540401be3748717fae613041592778a3a7160fb763cJohan Hedberg
1541401be3748717fae613041592778a3a7160fb763cJohan Hedberg	telephony_deinit();
1542a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
1543