telephony-ofono.c revision de8eb4773a1ac878b1b9b8e7306a3c1f4cfe43eb
1a34c155f55270b917795d003be24488f53d9b711Forrest Zhao/*
2a34c155f55270b917795d003be24488f53d9b711Forrest Zhao *
3a34c155f55270b917795d003be24488f53d9b711Forrest Zhao *  BlueZ - Bluetooth protocol stack for Linux
4a34c155f55270b917795d003be24488f53d9b711Forrest Zhao *
5d3b613c392352f59fd6b18becf80e6504ad2423cMarcel Holtmann *  Copyright (C) 2009-2010  Intel Corporation
65592142cb9383df0556b27ac59e96547b380310bJohan Hedberg *  Copyright (C) 2006-2009  Nokia Corporation
79184e2eeb7b97371c6b83b747c8984e2340d2b47Marcel Holtmann *  Copyright (C) 2004-2010  Marcel Holtmann <marcel@holtmann.org>
8a34c155f55270b917795d003be24488f53d9b711Forrest Zhao *
9a34c155f55270b917795d003be24488f53d9b711Forrest Zhao *
10a34c155f55270b917795d003be24488f53d9b711Forrest Zhao *  This program is free software; you can redistribute it and/or modify
11a34c155f55270b917795d003be24488f53d9b711Forrest Zhao *  it under the terms of the GNU General Public License as published by
12a34c155f55270b917795d003be24488f53d9b711Forrest Zhao *  the Free Software Foundation; either version 2 of the License, or
13a34c155f55270b917795d003be24488f53d9b711Forrest Zhao *  (at your option) any later version.
14a34c155f55270b917795d003be24488f53d9b711Forrest Zhao *
15a34c155f55270b917795d003be24488f53d9b711Forrest Zhao *  This program is distributed in the hope that it will be useful,
16a34c155f55270b917795d003be24488f53d9b711Forrest Zhao *  but WITHOUT ANY WARRANTY; without even the implied warranty of
17a34c155f55270b917795d003be24488f53d9b711Forrest Zhao *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18a34c155f55270b917795d003be24488f53d9b711Forrest Zhao *  GNU General Public License for more details.
19a34c155f55270b917795d003be24488f53d9b711Forrest Zhao *
20a34c155f55270b917795d003be24488f53d9b711Forrest Zhao *  You should have received a copy of the GNU General Public License
21a34c155f55270b917795d003be24488f53d9b711Forrest Zhao *  along with this program; if not, write to the Free Software
22a34c155f55270b917795d003be24488f53d9b711Forrest Zhao *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
23a34c155f55270b917795d003be24488f53d9b711Forrest Zhao *
24a34c155f55270b917795d003be24488f53d9b711Forrest Zhao */
25a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
26a34c155f55270b917795d003be24488f53d9b711Forrest Zhao#ifdef HAVE_CONFIG_H
27a34c155f55270b917795d003be24488f53d9b711Forrest Zhao#include <config.h>
28a34c155f55270b917795d003be24488f53d9b711Forrest Zhao#endif
29a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
30a34c155f55270b917795d003be24488f53d9b711Forrest Zhao#include <stdlib.h>
31a34c155f55270b917795d003be24488f53d9b711Forrest Zhao#include <stdio.h>
32a34c155f55270b917795d003be24488f53d9b711Forrest Zhao#include <string.h>
33a34c155f55270b917795d003be24488f53d9b711Forrest Zhao#include <stdint.h>
34a34c155f55270b917795d003be24488f53d9b711Forrest Zhao#include <glib.h>
35a34c155f55270b917795d003be24488f53d9b711Forrest Zhao#include <dbus/dbus.h>
36a34c155f55270b917795d003be24488f53d9b711Forrest Zhao#include <gdbus.h>
37a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
38e891f7df6225c758da0d95f7554c6cc67f72f31eGustavo F. Padovan#include "log.h"
39a34c155f55270b917795d003be24488f53d9b711Forrest Zhao#include "telephony.h"
40a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
41a34c155f55270b917795d003be24488f53d9b711Forrest Zhaoenum net_registration_status {
42a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	NETWORK_REG_STATUS_HOME = 0x00,
43a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	NETWORK_REG_STATUS_ROAM,
44a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	NETWORK_REG_STATUS_NOSERV
45a34c155f55270b917795d003be24488f53d9b711Forrest Zhao};
46a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
47a34c155f55270b917795d003be24488f53d9b711Forrest Zhaostruct voice_call {
48a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	char *obj_path;
49a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	int status;
50a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	gboolean originating;
519d7109c994bec237bdf1fff158d9400cbfb1b5c9Luiz Augusto von Dentz	gboolean conference;
52a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	char *number;
538309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	guint watch;
54a34c155f55270b917795d003be24488f53d9b711Forrest Zhao};
55a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
56a34c155f55270b917795d003be24488f53d9b711Forrest Zhaostatic DBusConnection *connection = NULL;
57a34c155f55270b917795d003be24488f53d9b711Forrest Zhaostatic char *modem_obj_path = NULL;
58a34c155f55270b917795d003be24488f53d9b711Forrest Zhaostatic char *last_dialed_number = NULL;
59a34c155f55270b917795d003be24488f53d9b711Forrest Zhaostatic GSList *calls = NULL;
609946e8636c3361dc769c5f8a463b74158018d3ddLuiz Augusto von Dentzstatic GSList *watches = NULL;
61c49dc8c7c815191b5825896f827cac2e2ff395ffLuiz Augusto von Dentzstatic GSList *pending = NULL;
62a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
63a34c155f55270b917795d003be24488f53d9b711Forrest Zhao#define OFONO_BUS_NAME "org.ofono"
64a34c155f55270b917795d003be24488f53d9b711Forrest Zhao#define OFONO_PATH "/"
65806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz#define OFONO_MODEM_INTERFACE "org.ofono.Modem"
66d89690657f2634ceb9d4b13257ccc7d60bc0cb5dForrest Zhao#define OFONO_MANAGER_INTERFACE "org.ofono.Manager"
67a34c155f55270b917795d003be24488f53d9b711Forrest Zhao#define OFONO_NETWORKREG_INTERFACE "org.ofono.NetworkRegistration"
68a34c155f55270b917795d003be24488f53d9b711Forrest Zhao#define OFONO_VCMANAGER_INTERFACE "org.ofono.VoiceCallManager"
69a34c155f55270b917795d003be24488f53d9b711Forrest Zhao#define OFONO_VC_INTERFACE "org.ofono.VoiceCall"
70a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
71a34c155f55270b917795d003be24488f53d9b711Forrest Zhao/* HAL battery namespace key values */
72a34c155f55270b917795d003be24488f53d9b711Forrest Zhaostatic int battchg_cur = -1;    /* "battery.charge_level.current" */
73a34c155f55270b917795d003be24488f53d9b711Forrest Zhaostatic int battchg_last = -1;   /* "battery.charge_level.last_full" */
74a34c155f55270b917795d003be24488f53d9b711Forrest Zhaostatic int battchg_design = -1; /* "battery.charge_level.design" */
75a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
76a34c155f55270b917795d003be24488f53d9b711Forrest Zhaostatic struct {
77a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	uint8_t status;
78a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	uint32_t signals_bar;
79a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	char *operator_name;
80a34c155f55270b917795d003be24488f53d9b711Forrest Zhao} net = {
81a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	.status = NETWORK_REG_STATUS_NOSERV,
82a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	.signals_bar = 0,
83a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	.operator_name = NULL,
84a34c155f55270b917795d003be24488f53d9b711Forrest Zhao};
85a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
86a34c155f55270b917795d003be24488f53d9b711Forrest Zhaostatic const char *chld_str = "0,1,1x,2,2x,3,4";
87a34c155f55270b917795d003be24488f53d9b711Forrest Zhaostatic char *subscriber_number = NULL;
88a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
89a34c155f55270b917795d003be24488f53d9b711Forrest Zhaostatic gboolean events_enabled = FALSE;
90a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
91a34c155f55270b917795d003be24488f53d9b711Forrest Zhaostatic struct indicator ofono_indicators[] =
92a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
93884debf8418651b63b1a5a8918092ba4d230783eJohan Hedberg	{ "battchg",	"0-5",	5,	TRUE },
94884debf8418651b63b1a5a8918092ba4d230783eJohan Hedberg	{ "signal",	"0-5",	5,	TRUE },
95884debf8418651b63b1a5a8918092ba4d230783eJohan Hedberg	{ "service",	"0,1",	1,	TRUE },
96884debf8418651b63b1a5a8918092ba4d230783eJohan Hedberg	{ "call",	"0,1",	0,	TRUE },
97884debf8418651b63b1a5a8918092ba4d230783eJohan Hedberg	{ "callsetup",	"0-3",	0,	TRUE },
98884debf8418651b63b1a5a8918092ba4d230783eJohan Hedberg	{ "callheld",	"0-2",	0,	FALSE },
99884debf8418651b63b1a5a8918092ba4d230783eJohan Hedberg	{ "roam",	"0,1",	0,	TRUE },
100a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	{ NULL }
101a34c155f55270b917795d003be24488f53d9b711Forrest Zhao};
102a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
103a34c155f55270b917795d003be24488f53d9b711Forrest Zhaostatic struct voice_call *find_vc(const char *path)
104a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
105a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	GSList *l;
106a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
107a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	for (l = calls; l != NULL; l = l->next) {
108a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		struct voice_call *vc = l->data;
109a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
110a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		if (g_str_equal(vc->obj_path, path))
111a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			return vc;
112a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	}
113a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
114a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	return NULL;
115a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
116a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
117a34c155f55270b917795d003be24488f53d9b711Forrest Zhaostatic struct voice_call *find_vc_with_status(int status)
118a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
119a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	GSList *l;
120a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
121a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	for (l = calls; l != NULL; l = l->next) {
122a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		struct voice_call *vc = l->data;
123a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
124a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		if (vc->status == status)
125a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			return vc;
126a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	}
127a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
128a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	return NULL;
129a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
130a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
131d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentzstatic struct voice_call *find_vc_without_status(int status)
132d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz{
133d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	GSList *l;
134d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz
135d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	for (l = calls; l != NULL; l = l->next) {
136d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz		struct voice_call *call = l->data;
137d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz
138d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz		if (call->status != status)
139d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz			return call;
140d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	}
141d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz
142d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	return NULL;
143d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz}
144d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz
1451097cfd46e906ddfd8a827ce683c1eddf2d98499Luiz Augusto von Dentzstatic int number_type(const char *number)
1461097cfd46e906ddfd8a827ce683c1eddf2d98499Luiz Augusto von Dentz{
1471097cfd46e906ddfd8a827ce683c1eddf2d98499Luiz Augusto von Dentz	if (number == NULL)
1481097cfd46e906ddfd8a827ce683c1eddf2d98499Luiz Augusto von Dentz		return NUMBER_TYPE_TELEPHONY;
1491097cfd46e906ddfd8a827ce683c1eddf2d98499Luiz Augusto von Dentz
1501097cfd46e906ddfd8a827ce683c1eddf2d98499Luiz Augusto von Dentz	if (number[0] == '+' || strncmp(number, "00", 2) == 0)
1511097cfd46e906ddfd8a827ce683c1eddf2d98499Luiz Augusto von Dentz		return NUMBER_TYPE_INTERNATIONAL;
1521097cfd46e906ddfd8a827ce683c1eddf2d98499Luiz Augusto von Dentz
1531097cfd46e906ddfd8a827ce683c1eddf2d98499Luiz Augusto von Dentz	return NUMBER_TYPE_TELEPHONY;
1541097cfd46e906ddfd8a827ce683c1eddf2d98499Luiz Augusto von Dentz}
1551097cfd46e906ddfd8a827ce683c1eddf2d98499Luiz Augusto von Dentz
156a34c155f55270b917795d003be24488f53d9b711Forrest Zhaovoid telephony_device_connected(void *telephony_device)
157a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
1581097cfd46e906ddfd8a827ce683c1eddf2d98499Luiz Augusto von Dentz	struct voice_call *coming;
1591097cfd46e906ddfd8a827ce683c1eddf2d98499Luiz Augusto von Dentz
1608e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan	DBG("telephony-ofono: device %p connected", telephony_device);
1611097cfd46e906ddfd8a827ce683c1eddf2d98499Luiz Augusto von Dentz
1621097cfd46e906ddfd8a827ce683c1eddf2d98499Luiz Augusto von Dentz	coming = find_vc_with_status(CALL_STATUS_ALERTING);
1631097cfd46e906ddfd8a827ce683c1eddf2d98499Luiz Augusto von Dentz	if (coming) {
1641097cfd46e906ddfd8a827ce683c1eddf2d98499Luiz Augusto von Dentz		if (find_vc_with_status(CALL_STATUS_ACTIVE))
1651097cfd46e906ddfd8a827ce683c1eddf2d98499Luiz Augusto von Dentz			telephony_call_waiting_ind(coming->number,
1661097cfd46e906ddfd8a827ce683c1eddf2d98499Luiz Augusto von Dentz						number_type(coming->number));
1671097cfd46e906ddfd8a827ce683c1eddf2d98499Luiz Augusto von Dentz		else
1681097cfd46e906ddfd8a827ce683c1eddf2d98499Luiz Augusto von Dentz			telephony_incoming_call_ind(coming->number,
1691097cfd46e906ddfd8a827ce683c1eddf2d98499Luiz Augusto von Dentz						number_type(coming->number));
1701097cfd46e906ddfd8a827ce683c1eddf2d98499Luiz Augusto von Dentz	}
171a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
172a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
173a34c155f55270b917795d003be24488f53d9b711Forrest Zhaovoid telephony_device_disconnected(void *telephony_device)
174a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
1758e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan	DBG("telephony-ofono: device %p disconnected", telephony_device);
176a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	events_enabled = FALSE;
177a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
178a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
179a34c155f55270b917795d003be24488f53d9b711Forrest Zhaovoid telephony_event_reporting_req(void *telephony_device, int ind)
180a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
181a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	events_enabled = ind == 1 ? TRUE : FALSE;
182a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
183a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	telephony_event_reporting_rsp(telephony_device, CME_ERROR_NONE);
184a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
185a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
186a34c155f55270b917795d003be24488f53d9b711Forrest Zhaovoid telephony_response_and_hold_req(void *telephony_device, int rh)
187a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
188b0d302d48976920cec7548ec5cc603f3896bbb8cJohan Hedberg	telephony_response_and_hold_rsp(telephony_device,
189b0d302d48976920cec7548ec5cc603f3896bbb8cJohan Hedberg						CME_ERROR_NOT_SUPPORTED);
190a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
191a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
192a34c155f55270b917795d003be24488f53d9b711Forrest Zhaovoid telephony_last_dialed_number_req(void *telephony_device)
193a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
1948e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan	DBG("telephony-ofono: last dialed number request");
195a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
196a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	if (last_dialed_number)
197a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		telephony_dial_number_req(telephony_device, last_dialed_number);
198a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	else
199a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		telephony_last_dialed_number_rsp(telephony_device,
200a34c155f55270b917795d003be24488f53d9b711Forrest Zhao				CME_ERROR_NOT_ALLOWED);
201a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
202a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
203a34c155f55270b917795d003be24488f53d9b711Forrest Zhaostatic int send_method_call(const char *dest, const char *path,
204a34c155f55270b917795d003be24488f53d9b711Forrest Zhao                                const char *interface, const char *method,
205a34c155f55270b917795d003be24488f53d9b711Forrest Zhao                                DBusPendingCallNotifyFunction cb,
206a34c155f55270b917795d003be24488f53d9b711Forrest Zhao                                void *user_data, int type, ...)
207a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
208a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	DBusMessage *msg;
209a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	DBusPendingCall *call;
210a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	va_list args;
211a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
212a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	msg = dbus_message_new_method_call(dest, path, interface, method);
213a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	if (!msg) {
214a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		error("Unable to allocate new D-Bus %s message", method);
215a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		return -ENOMEM;
216a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	}
217a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
218a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	va_start(args, type);
219a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
220a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	if (!dbus_message_append_args_valist(msg, type, args)) {
221a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		dbus_message_unref(msg);
222a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		va_end(args);
223a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		return -EIO;
224a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	}
225a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
226a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	va_end(args);
227a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
228a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	if (!cb) {
229a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		g_dbus_send_message(connection, msg);
230a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		return 0;
231a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	}
232a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
233a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	if (!dbus_connection_send_with_reply(connection, msg, &call, -1)) {
234a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		error("Sending %s failed", method);
235a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		dbus_message_unref(msg);
236a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		return -EIO;
237a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	}
238a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
239a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	dbus_pending_call_set_notify(call, cb, user_data, NULL);
240c49dc8c7c815191b5825896f827cac2e2ff395ffLuiz Augusto von Dentz	pending = g_slist_prepend(pending, call);
241a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	dbus_message_unref(msg);
242a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
243a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	return 0;
244a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
245a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
246d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentzstatic int answer_call(struct voice_call *vc)
247d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz{
248d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	DBG("%s", vc->number);
249d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	return send_method_call(OFONO_BUS_NAME, vc->obj_path,
250d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz						OFONO_VC_INTERFACE, "Answer",
251d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz						NULL, NULL, DBUS_TYPE_INVALID);
252d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz}
253d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz
254d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentzstatic int release_call(struct voice_call *vc)
255d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz{
256d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	DBG("%s", vc->number);
257d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	return send_method_call(OFONO_BUS_NAME, vc->obj_path,
258d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz						OFONO_VC_INTERFACE, "Hangup",
259d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz						NULL, NULL, DBUS_TYPE_INVALID);
260d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz}
261d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz
262d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentzstatic int release_answer_calls()
263d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz{
264d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	DBG("");
265d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	return send_method_call(OFONO_BUS_NAME, modem_obj_path,
266d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz						OFONO_VCMANAGER_INTERFACE,
267d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz						"ReleaseAndAnswer",
268d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz						NULL, NULL, DBUS_TYPE_INVALID);
269d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz}
270d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz
271a6099d662b4304e9255c53ab28f23358bb893cbaLuiz Augusto von Dentzstatic int split_call(struct voice_call *call)
272d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz{
273a6099d662b4304e9255c53ab28f23358bb893cbaLuiz Augusto von Dentz	DBG("%s", call->number);
274d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	return send_method_call(OFONO_BUS_NAME, modem_obj_path,
275d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz						OFONO_VCMANAGER_INTERFACE,
276a6099d662b4304e9255c53ab28f23358bb893cbaLuiz Augusto von Dentz						"PrivateChat",
277a6099d662b4304e9255c53ab28f23358bb893cbaLuiz Augusto von Dentz						NULL, NULL,
278a6099d662b4304e9255c53ab28f23358bb893cbaLuiz Augusto von Dentz						DBUS_TYPE_OBJECT_PATH,
279a6099d662b4304e9255c53ab28f23358bb893cbaLuiz Augusto von Dentz						call->obj_path,
280a6099d662b4304e9255c53ab28f23358bb893cbaLuiz Augusto von Dentz						DBUS_TYPE_INVALID);
281a6099d662b4304e9255c53ab28f23358bb893cbaLuiz Augusto von Dentz	return -1;
282d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz}
283d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz
284a6099d662b4304e9255c53ab28f23358bb893cbaLuiz Augusto von Dentzstatic int swap_calls(void)
285d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz{
286d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	DBG("");
287d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	return send_method_call(OFONO_BUS_NAME, modem_obj_path,
288d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz						OFONO_VCMANAGER_INTERFACE,
289a6099d662b4304e9255c53ab28f23358bb893cbaLuiz Augusto von Dentz						"SwapCalls",
290d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz						NULL, NULL, DBUS_TYPE_INVALID);
291d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz}
292d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz
2939d7109c994bec237bdf1fff158d9400cbfb1b5c9Luiz Augusto von Dentzstatic int create_conference(void)
2949d7109c994bec237bdf1fff158d9400cbfb1b5c9Luiz Augusto von Dentz{
2959d7109c994bec237bdf1fff158d9400cbfb1b5c9Luiz Augusto von Dentz	DBG("");
2969d7109c994bec237bdf1fff158d9400cbfb1b5c9Luiz Augusto von Dentz	return send_method_call(OFONO_BUS_NAME, modem_obj_path,
2979d7109c994bec237bdf1fff158d9400cbfb1b5c9Luiz Augusto von Dentz						OFONO_VCMANAGER_INTERFACE,
2989d7109c994bec237bdf1fff158d9400cbfb1b5c9Luiz Augusto von Dentz						"CreateMultiparty",
2999d7109c994bec237bdf1fff158d9400cbfb1b5c9Luiz Augusto von Dentz						NULL, NULL, DBUS_TYPE_INVALID);
3009d7109c994bec237bdf1fff158d9400cbfb1b5c9Luiz Augusto von Dentz}
3019d7109c994bec237bdf1fff158d9400cbfb1b5c9Luiz Augusto von Dentz
3029d7109c994bec237bdf1fff158d9400cbfb1b5c9Luiz Augusto von Dentzstatic int release_conference(void)
3039d7109c994bec237bdf1fff158d9400cbfb1b5c9Luiz Augusto von Dentz{
3049d7109c994bec237bdf1fff158d9400cbfb1b5c9Luiz Augusto von Dentz	DBG("");
3059d7109c994bec237bdf1fff158d9400cbfb1b5c9Luiz Augusto von Dentz	return send_method_call(OFONO_BUS_NAME, modem_obj_path,
3069d7109c994bec237bdf1fff158d9400cbfb1b5c9Luiz Augusto von Dentz						OFONO_VCMANAGER_INTERFACE,
3079d7109c994bec237bdf1fff158d9400cbfb1b5c9Luiz Augusto von Dentz						"HangupMultiparty",
3089d7109c994bec237bdf1fff158d9400cbfb1b5c9Luiz Augusto von Dentz						NULL, NULL, DBUS_TYPE_INVALID);
3099d7109c994bec237bdf1fff158d9400cbfb1b5c9Luiz Augusto von Dentz}
3109d7109c994bec237bdf1fff158d9400cbfb1b5c9Luiz Augusto von Dentz
3119d7109c994bec237bdf1fff158d9400cbfb1b5c9Luiz Augusto von Dentzstatic int call_transfer(void)
3129d7109c994bec237bdf1fff158d9400cbfb1b5c9Luiz Augusto von Dentz{
3139d7109c994bec237bdf1fff158d9400cbfb1b5c9Luiz Augusto von Dentz	DBG("");
3149d7109c994bec237bdf1fff158d9400cbfb1b5c9Luiz Augusto von Dentz	return send_method_call(OFONO_BUS_NAME, modem_obj_path,
3159d7109c994bec237bdf1fff158d9400cbfb1b5c9Luiz Augusto von Dentz						OFONO_VCMANAGER_INTERFACE,
3169d7109c994bec237bdf1fff158d9400cbfb1b5c9Luiz Augusto von Dentz						"Transfer",
3179d7109c994bec237bdf1fff158d9400cbfb1b5c9Luiz Augusto von Dentz						NULL, NULL, DBUS_TYPE_INVALID);
3189d7109c994bec237bdf1fff158d9400cbfb1b5c9Luiz Augusto von Dentz}
3199d7109c994bec237bdf1fff158d9400cbfb1b5c9Luiz Augusto von Dentz
320a34c155f55270b917795d003be24488f53d9b711Forrest Zhaovoid telephony_terminate_call_req(void *telephony_device)
321a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
322d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	struct voice_call *call;
323d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	struct voice_call *alerting;
324d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	int err;
325a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
326d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	call = find_vc_with_status(CALL_STATUS_ACTIVE);
327d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	if (!call)
328d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz		call = calls->data;
329a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
330d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	if (!call) {
331d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz		error("No active call");
332a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		telephony_terminate_call_rsp(telephony_device,
333d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz						CME_ERROR_NOT_ALLOWED);
334a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		return;
335a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	}
336a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
337d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	alerting = find_vc_with_status(CALL_STATUS_ALERTING);
338d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	if (call->status == CALL_STATUS_HELD && alerting)
339d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz		err = release_call(alerting);
3409d7109c994bec237bdf1fff158d9400cbfb1b5c9Luiz Augusto von Dentz	else if (call->conference)
3419d7109c994bec237bdf1fff158d9400cbfb1b5c9Luiz Augusto von Dentz		err = release_conference();
342d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	else
343d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz		err = release_call(call);
344a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
345d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	if (err < 0)
346d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz		telephony_terminate_call_rsp(telephony_device,
347d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz						CME_ERROR_AG_FAILURE);
348d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	else
349d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz		telephony_terminate_call_rsp(telephony_device, CME_ERROR_NONE);
350a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
351a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
352a34c155f55270b917795d003be24488f53d9b711Forrest Zhaovoid telephony_answer_call_req(void *telephony_device)
353a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
35416ec168ac7fdd18cb2cbc7b3be7df349fd84c41cLuiz Augusto von Dentz	struct voice_call *vc;
355a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	int ret;
356a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
35716ec168ac7fdd18cb2cbc7b3be7df349fd84c41cLuiz Augusto von Dentz	vc = find_vc_with_status(CALL_STATUS_INCOMING);
35816ec168ac7fdd18cb2cbc7b3be7df349fd84c41cLuiz Augusto von Dentz	if (!vc)
35916ec168ac7fdd18cb2cbc7b3be7df349fd84c41cLuiz Augusto von Dentz		vc = find_vc_with_status(CALL_STATUS_ALERTING);
36016ec168ac7fdd18cb2cbc7b3be7df349fd84c41cLuiz Augusto von Dentz
36116ec168ac7fdd18cb2cbc7b3be7df349fd84c41cLuiz Augusto von Dentz	if (!vc)
36216ec168ac7fdd18cb2cbc7b3be7df349fd84c41cLuiz Augusto von Dentz		vc = find_vc_with_status(CALL_STATUS_WAITING);
36316ec168ac7fdd18cb2cbc7b3be7df349fd84c41cLuiz Augusto von Dentz
364a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	if (!vc) {
365a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		telephony_answer_call_rsp(telephony_device,
366a34c155f55270b917795d003be24488f53d9b711Forrest Zhao					CME_ERROR_NOT_ALLOWED);
367a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		return;
368a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	}
369a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
370d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	ret = answer_call(vc);
371a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	if (ret < 0) {
372a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		telephony_answer_call_rsp(telephony_device,
373a34c155f55270b917795d003be24488f53d9b711Forrest Zhao					CME_ERROR_AG_FAILURE);
374a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		return;
375a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	}
376a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
377a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	telephony_answer_call_rsp(telephony_device, CME_ERROR_NONE);
378a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
379a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
380a34c155f55270b917795d003be24488f53d9b711Forrest Zhaovoid telephony_dial_number_req(void *telephony_device, const char *number)
381a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
38283003660808c30390f21c569a5ba7dbdd8344a41Claudio Takahasi	const char *clir;
383a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	int ret;
384a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
3858e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan	DBG("telephony-ofono: dial request to %s", number);
386a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
387c5321032b046c39477ab99a05e933b13d0b67a04Forrest Zhao	if (!modem_obj_path) {
388c5321032b046c39477ab99a05e933b13d0b67a04Forrest Zhao		telephony_dial_number_rsp(telephony_device,
389c5321032b046c39477ab99a05e933b13d0b67a04Forrest Zhao					CME_ERROR_AG_FAILURE);
390c5321032b046c39477ab99a05e933b13d0b67a04Forrest Zhao		return;
391c5321032b046c39477ab99a05e933b13d0b67a04Forrest Zhao	}
392c5321032b046c39477ab99a05e933b13d0b67a04Forrest Zhao
393a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	if (!strncmp(number, "*31#", 4)) {
394a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		number += 4;
39583003660808c30390f21c569a5ba7dbdd8344a41Claudio Takahasi		clir = "enabled";
396a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	} else if (!strncmp(number, "#31#", 4)) {
397a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		number += 4;
39883003660808c30390f21c569a5ba7dbdd8344a41Claudio Takahasi		clir =  "disabled";
39983003660808c30390f21c569a5ba7dbdd8344a41Claudio Takahasi	} else
40083003660808c30390f21c569a5ba7dbdd8344a41Claudio Takahasi		clir = "default";
401a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
402a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	ret = send_method_call(OFONO_BUS_NAME, modem_obj_path,
403a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			OFONO_VCMANAGER_INTERFACE,
404a34c155f55270b917795d003be24488f53d9b711Forrest Zhao                        "Dial", NULL, NULL,
405a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			DBUS_TYPE_STRING, &number,
406a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			DBUS_TYPE_STRING, &clir,
407a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			DBUS_TYPE_INVALID);
408a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
409a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	if (ret < 0)
410a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		telephony_dial_number_rsp(telephony_device,
411a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			CME_ERROR_AG_FAILURE);
412a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	else
413a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		telephony_dial_number_rsp(telephony_device, CME_ERROR_NONE);
414a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
415a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
416a34c155f55270b917795d003be24488f53d9b711Forrest Zhaovoid telephony_transmit_dtmf_req(void *telephony_device, char tone)
417a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
418a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	char *tone_string;
419a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	int ret;
420a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
4218e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan	DBG("telephony-ofono: transmit dtmf: %c", tone);
422a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
423c5321032b046c39477ab99a05e933b13d0b67a04Forrest Zhao	if (!modem_obj_path) {
424c5321032b046c39477ab99a05e933b13d0b67a04Forrest Zhao		telephony_transmit_dtmf_rsp(telephony_device,
425c5321032b046c39477ab99a05e933b13d0b67a04Forrest Zhao					CME_ERROR_AG_FAILURE);
426c5321032b046c39477ab99a05e933b13d0b67a04Forrest Zhao		return;
427c5321032b046c39477ab99a05e933b13d0b67a04Forrest Zhao	}
428c5321032b046c39477ab99a05e933b13d0b67a04Forrest Zhao
429a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	tone_string = g_strdup_printf("%c", tone);
430a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	ret = send_method_call(OFONO_BUS_NAME, modem_obj_path,
431a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			OFONO_VCMANAGER_INTERFACE,
432a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			"SendTones", NULL, NULL,
433a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			DBUS_TYPE_STRING, &tone_string,
434a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			DBUS_TYPE_INVALID);
435a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	g_free(tone_string);
436a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
437a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	if (ret < 0)
438a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		telephony_transmit_dtmf_rsp(telephony_device,
439a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			CME_ERROR_AG_FAILURE);
440a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	else
441a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		telephony_transmit_dtmf_rsp(telephony_device, CME_ERROR_NONE);
442a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
443a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
444a34c155f55270b917795d003be24488f53d9b711Forrest Zhaovoid telephony_subscriber_number_req(void *telephony_device)
445a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
4468e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan	DBG("telephony-ofono: subscriber number request");
447a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
448a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	if (subscriber_number)
449a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		telephony_subscriber_number_ind(subscriber_number,
450a34c155f55270b917795d003be24488f53d9b711Forrest Zhao						NUMBER_TYPE_TELEPHONY,
451a34c155f55270b917795d003be24488f53d9b711Forrest Zhao						SUBSCRIBER_SERVICE_VOICE);
452a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	telephony_subscriber_number_rsp(telephony_device, CME_ERROR_NONE);
453a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
454a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
455a34c155f55270b917795d003be24488f53d9b711Forrest Zhaovoid telephony_list_current_calls_req(void *telephony_device)
456a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
457a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	GSList *l;
458a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	int i;
459a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
4608e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan	DBG("telephony-ofono: list current calls request");
461a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
462a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	for (l = calls, i = 1; l != NULL; l = l->next, i++) {
463a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		struct voice_call *vc = l->data;
4649d7109c994bec237bdf1fff158d9400cbfb1b5c9Luiz Augusto von Dentz		int direction, multiparty;
465a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
466a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		direction = vc->originating ?
467a34c155f55270b917795d003be24488f53d9b711Forrest Zhao				CALL_DIR_OUTGOING : CALL_DIR_INCOMING;
468a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
4699d7109c994bec237bdf1fff158d9400cbfb1b5c9Luiz Augusto von Dentz		multiparty = vc->conference ?
4709d7109c994bec237bdf1fff158d9400cbfb1b5c9Luiz Augusto von Dentz				CALL_MULTIPARTY_YES : CALL_MULTIPARTY_NO;
4719d7109c994bec237bdf1fff158d9400cbfb1b5c9Luiz Augusto von Dentz
4729d7109c994bec237bdf1fff158d9400cbfb1b5c9Luiz Augusto von Dentz		DBG("call %s direction %d multiparty %d", vc->number,
4739d7109c994bec237bdf1fff158d9400cbfb1b5c9Luiz Augusto von Dentz							direction, multiparty);
474d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz
475a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		telephony_list_current_call_ind(i, direction, vc->status,
4769d7109c994bec237bdf1fff158d9400cbfb1b5c9Luiz Augusto von Dentz					CALL_MODE_VOICE, multiparty,
477d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz					vc->number, number_type(vc->number));
478a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	}
479d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz
480a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	telephony_list_current_calls_rsp(telephony_device, CME_ERROR_NONE);
481a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
482a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
483a34c155f55270b917795d003be24488f53d9b711Forrest Zhaovoid telephony_operator_selection_req(void *telephony_device)
484a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
4858e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan	DBG("telephony-ofono: operator selection request");
486a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
487a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	telephony_operator_selection_ind(OPERATOR_MODE_AUTO,
488a34c155f55270b917795d003be24488f53d9b711Forrest Zhao				net.operator_name ? net.operator_name : "");
489a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	telephony_operator_selection_rsp(telephony_device, CME_ERROR_NONE);
490a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
491a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
492d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentzstatic void foreach_vc_with_status(int status,
493d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz					int (*func)(struct voice_call *vc))
494d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz{
495d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	GSList *l;
496d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz
497d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	for (l = calls; l != NULL; l = l->next) {
498d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz		struct voice_call *call = l->data;
499d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz
500d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz		if (call->status == status)
501d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz			func(call);
502d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	}
503d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz}
504d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz
505a34c155f55270b917795d003be24488f53d9b711Forrest Zhaovoid telephony_call_hold_req(void *telephony_device, const char *cmd)
506a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
507a6099d662b4304e9255c53ab28f23358bb893cbaLuiz Augusto von Dentz	const char *idx;
508d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	struct voice_call *call;
509d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	int err = 0;
510d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz
5118e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan	DBG("telephony-ofono: got call hold request %s", cmd);
512d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz
513a6099d662b4304e9255c53ab28f23358bb893cbaLuiz Augusto von Dentz	if (strlen(cmd) > 1)
514a6099d662b4304e9255c53ab28f23358bb893cbaLuiz Augusto von Dentz		idx = &cmd[1];
515a6099d662b4304e9255c53ab28f23358bb893cbaLuiz Augusto von Dentz	else
516a6099d662b4304e9255c53ab28f23358bb893cbaLuiz Augusto von Dentz		idx = NULL;
517a6099d662b4304e9255c53ab28f23358bb893cbaLuiz Augusto von Dentz
518a6099d662b4304e9255c53ab28f23358bb893cbaLuiz Augusto von Dentz	if (idx)
519a6099d662b4304e9255c53ab28f23358bb893cbaLuiz Augusto von Dentz		call = g_slist_nth_data(calls, strtol(idx, NULL, 0) - 1);
520a6099d662b4304e9255c53ab28f23358bb893cbaLuiz Augusto von Dentz	else
521a6099d662b4304e9255c53ab28f23358bb893cbaLuiz Augusto von Dentz		call = NULL;
522a6099d662b4304e9255c53ab28f23358bb893cbaLuiz Augusto von Dentz
523d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	switch (cmd[0]) {
524d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	case '0':
525d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz		if (find_vc_with_status(CALL_STATUS_WAITING))
526d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz			foreach_vc_with_status(CALL_STATUS_WAITING,
527d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz								release_call);
528d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz		else
529d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz			foreach_vc_with_status(CALL_STATUS_HELD, release_call);
530d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz		break;
531d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	case '1':
532a6099d662b4304e9255c53ab28f23358bb893cbaLuiz Augusto von Dentz		if (idx) {
533a6099d662b4304e9255c53ab28f23358bb893cbaLuiz Augusto von Dentz			if (call)
534a6099d662b4304e9255c53ab28f23358bb893cbaLuiz Augusto von Dentz				err = release_call(call);
535a6099d662b4304e9255c53ab28f23358bb893cbaLuiz Augusto von Dentz			break;
536a6099d662b4304e9255c53ab28f23358bb893cbaLuiz Augusto von Dentz		}
537d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz		err = release_answer_calls();
538d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz		break;
539d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	case '2':
540a6099d662b4304e9255c53ab28f23358bb893cbaLuiz Augusto von Dentz		if (idx) {
541a6099d662b4304e9255c53ab28f23358bb893cbaLuiz Augusto von Dentz			if (call)
542a6099d662b4304e9255c53ab28f23358bb893cbaLuiz Augusto von Dentz				err = split_call(call);
543a6099d662b4304e9255c53ab28f23358bb893cbaLuiz Augusto von Dentz		} else {
544a6099d662b4304e9255c53ab28f23358bb893cbaLuiz Augusto von Dentz			call = find_vc_with_status(CALL_STATUS_WAITING);
545a6099d662b4304e9255c53ab28f23358bb893cbaLuiz Augusto von Dentz
546a6099d662b4304e9255c53ab28f23358bb893cbaLuiz Augusto von Dentz			if (call)
547a6099d662b4304e9255c53ab28f23358bb893cbaLuiz Augusto von Dentz				err = answer_call(call);
548a6099d662b4304e9255c53ab28f23358bb893cbaLuiz Augusto von Dentz			else
549a6099d662b4304e9255c53ab28f23358bb893cbaLuiz Augusto von Dentz				err = swap_calls();
550a6099d662b4304e9255c53ab28f23358bb893cbaLuiz Augusto von Dentz		}
551d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz		break;
5529d7109c994bec237bdf1fff158d9400cbfb1b5c9Luiz Augusto von Dentz	case '3':
5539d7109c994bec237bdf1fff158d9400cbfb1b5c9Luiz Augusto von Dentz		if (find_vc_with_status(CALL_STATUS_HELD) ||
5549d7109c994bec237bdf1fff158d9400cbfb1b5c9Luiz Augusto von Dentz				find_vc_with_status(CALL_STATUS_WAITING))
5559d7109c994bec237bdf1fff158d9400cbfb1b5c9Luiz Augusto von Dentz			err = create_conference();
5569d7109c994bec237bdf1fff158d9400cbfb1b5c9Luiz Augusto von Dentz		break;
5579d7109c994bec237bdf1fff158d9400cbfb1b5c9Luiz Augusto von Dentz	case '4':
5589d7109c994bec237bdf1fff158d9400cbfb1b5c9Luiz Augusto von Dentz		err = call_transfer();
5599d7109c994bec237bdf1fff158d9400cbfb1b5c9Luiz Augusto von Dentz		break;
560d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	default:
561d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz		DBG("Unknown call hold request");
562d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz		break;
563d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	}
564d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz
565d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	if (err)
566d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz		telephony_call_hold_rsp(telephony_device,
567d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz					CME_ERROR_AG_FAILURE);
568d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	else
569d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz		telephony_call_hold_rsp(telephony_device, CME_ERROR_NONE);
570a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
571a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
572a34c155f55270b917795d003be24488f53d9b711Forrest Zhaovoid telephony_nr_and_ec_req(void *telephony_device, gboolean enable)
573a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
5748e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan	DBG("telephony-ofono: got %s NR and EC request",
575a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			enable ? "enable" : "disable");
576a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
577a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	telephony_nr_and_ec_rsp(telephony_device, CME_ERROR_NONE);
578a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
579a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
580a34c155f55270b917795d003be24488f53d9b711Forrest Zhaovoid telephony_key_press_req(void *telephony_device, const char *keys)
581a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
582d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	struct voice_call *active, *waiting;
583d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	int err;
584d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz
5858e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan	DBG("telephony-ofono: got key press request for %s", keys);
586d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz
587d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	waiting = find_vc_with_status(CALL_STATUS_INCOMING);
588d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	if (!waiting)
589d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz		waiting = find_vc_with_status(CALL_STATUS_DIALING);
590d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz
591d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	active = find_vc_with_status(CALL_STATUS_ACTIVE);
592d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz
593d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	if (waiting)
594d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz		err = answer_call(waiting);
595d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	else if (active)
596d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz		err = release_call(active);
597d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	else
598d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz		err = 0;
599d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz
600d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	if (err < 0)
601d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz		telephony_key_press_rsp(telephony_device,
602d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz							CME_ERROR_AG_FAILURE);
603d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz	else
604d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz		telephony_key_press_rsp(telephony_device, CME_ERROR_NONE);
605a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
606a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
6070218ab79ea881c593111b7165cd57337c711d2ecPeter Zotovvoid telephony_voice_dial_req(void *telephony_device, gboolean enable)
6080218ab79ea881c593111b7165cd57337c711d2ecPeter Zotov{
6098e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan	DBG("telephony-ofono: got %s voice dial request",
6100218ab79ea881c593111b7165cd57337c711d2ecPeter Zotov			enable ? "enable" : "disable");
6110218ab79ea881c593111b7165cd57337c711d2ecPeter Zotov
6120218ab79ea881c593111b7165cd57337c711d2ecPeter Zotov	telephony_voice_dial_rsp(telephony_device, CME_ERROR_NOT_SUPPORTED);
6130218ab79ea881c593111b7165cd57337c711d2ecPeter Zotov}
6140218ab79ea881c593111b7165cd57337c711d2ecPeter Zotov
615a34c155f55270b917795d003be24488f53d9b711Forrest Zhaostatic gboolean iter_get_basic_args(DBusMessageIter *iter,
616a34c155f55270b917795d003be24488f53d9b711Forrest Zhao					int first_arg_type, ...)
617a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
618a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	int type;
619a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	va_list ap;
620a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
621a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	va_start(ap, first_arg_type);
622a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
623a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	for (type = first_arg_type; type != DBUS_TYPE_INVALID;
624a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		type = va_arg(ap, int)) {
625a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		void *value = va_arg(ap, void *);
626a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		int real_type = dbus_message_iter_get_arg_type(iter);
627a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
628a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		if (real_type != type) {
629a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			error("iter_get_basic_args: expected %c but got %c",
630a34c155f55270b917795d003be24488f53d9b711Forrest Zhao				(char) type, (char) real_type);
631a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			break;
632a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		}
633a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
634a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		dbus_message_iter_get_basic(iter, value);
635a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		dbus_message_iter_next(iter);
636a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	}
637a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
638a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	va_end(ap);
639a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
640a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	return type == DBUS_TYPE_INVALID ? TRUE : FALSE;
641a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
642a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
6439fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentzstatic void call_free(struct voice_call *vc)
6449fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz{
6459fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	DBG("%s", vc->obj_path);
6469fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
64703085e6ba3e636e35e0395b694077635a9b0f563Luiz Augusto von Dentz	if (vc->status == CALL_STATUS_ACTIVE)
64803085e6ba3e636e35e0395b694077635a9b0f563Luiz Augusto von Dentz		telephony_update_indicator(ofono_indicators, "call",
64903085e6ba3e636e35e0395b694077635a9b0f563Luiz Augusto von Dentz							EV_CALL_INACTIVE);
65003085e6ba3e636e35e0395b694077635a9b0f563Luiz Augusto von Dentz	else
65103085e6ba3e636e35e0395b694077635a9b0f563Luiz Augusto von Dentz		telephony_update_indicator(ofono_indicators, "callsetup",
65203085e6ba3e636e35e0395b694077635a9b0f563Luiz Augusto von Dentz							EV_CALLSETUP_INACTIVE);
65303085e6ba3e636e35e0395b694077635a9b0f563Luiz Augusto von Dentz
65403085e6ba3e636e35e0395b694077635a9b0f563Luiz Augusto von Dentz	if (vc->status == CALL_STATUS_INCOMING)
65503085e6ba3e636e35e0395b694077635a9b0f563Luiz Augusto von Dentz		telephony_calling_stopped_ind();
65603085e6ba3e636e35e0395b694077635a9b0f563Luiz Augusto von Dentz
6579fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	g_dbus_remove_watch(connection, vc->watch);
6589fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	g_free(vc->obj_path);
6599fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	g_free(vc->number);
6609fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	g_free(vc);
6619fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz}
6629fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
6639fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentzstatic gboolean handle_vc_property_changed(DBusConnection *conn,
6649fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz					DBusMessage *msg, void *data)
6659fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz{
6669fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	struct voice_call *vc = data;
6679fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	const char *obj_path = dbus_message_get_path(msg);
6689fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	DBusMessageIter iter, sub;
6699fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	const char *property, *state;
6709fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
6719fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	DBG("path %s", obj_path);
6729fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
6739fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	dbus_message_iter_init(msg, &iter);
6749fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
6759fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING) {
6769fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		error("Unexpected signature in vc PropertyChanged signal");
6779fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		return TRUE;
6789fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	}
6799fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
6809fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	dbus_message_iter_get_basic(&iter, &property);
6819fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	DBG("property %s", property);
6829fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
6839fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	dbus_message_iter_next(&iter);
6849fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	dbus_message_iter_recurse(&iter, &sub);
6859fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	if (g_str_equal(property, "State")) {
6869fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		dbus_message_iter_get_basic(&sub, &state);
6879fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		DBG("State %s", state);
6889fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		if (g_str_equal(state, "disconnected")) {
6899fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz			calls = g_slist_remove(calls, vc);
6909fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz			call_free(vc);
6919fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		} else if (g_str_equal(state, "active")) {
6929fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz			telephony_update_indicator(ofono_indicators,
6939fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz							"call", EV_CALL_ACTIVE);
6949fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz			telephony_update_indicator(ofono_indicators,
6959fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz							"callsetup",
6969fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz							EV_CALLSETUP_INACTIVE);
6979fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz			if (vc->status == CALL_STATUS_INCOMING)
6989fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz				telephony_calling_stopped_ind();
6999fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz			vc->status = CALL_STATUS_ACTIVE;
7009fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		} else if (g_str_equal(state, "alerting")) {
7019fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz			telephony_update_indicator(ofono_indicators,
7029fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz					"callsetup", EV_CALLSETUP_ALERTING);
7039fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz			vc->status = CALL_STATUS_ALERTING;
7049fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz			vc->originating = TRUE;
7059fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		} else if (g_str_equal(state, "incoming")) {
7069fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz			/* state change from waiting to incoming */
7079fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz			telephony_update_indicator(ofono_indicators,
7089fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz					"callsetup", EV_CALLSETUP_INCOMING);
7099fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz			telephony_incoming_call_ind(vc->number,
7109fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz						NUMBER_TYPE_TELEPHONY);
7119fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz			vc->status = CALL_STATUS_INCOMING;
7129fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz			vc->originating = FALSE;
713d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz		} else if (g_str_equal(state, "held")) {
714d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz			vc->status = CALL_STATUS_HELD;
715d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz			if (find_vc_without_status(CALL_STATUS_HELD))
716d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz				telephony_update_indicator(ofono_indicators,
717d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz							"callheld",
718d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz							EV_CALLHELD_MULTIPLE);
719d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz			else
720d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz				telephony_update_indicator(ofono_indicators,
721d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz							"callheld",
722d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz							EV_CALLHELD_ON_HOLD);
7239fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		}
7249d7109c994bec237bdf1fff158d9400cbfb1b5c9Luiz Augusto von Dentz	} else if (g_str_equal(property, "Multiparty")) {
7259d7109c994bec237bdf1fff158d9400cbfb1b5c9Luiz Augusto von Dentz		dbus_bool_t multiparty;
7269d7109c994bec237bdf1fff158d9400cbfb1b5c9Luiz Augusto von Dentz
7279d7109c994bec237bdf1fff158d9400cbfb1b5c9Luiz Augusto von Dentz		dbus_message_iter_get_basic(&sub, &multiparty);
7289d7109c994bec237bdf1fff158d9400cbfb1b5c9Luiz Augusto von Dentz		DBG("Multiparty %s", multiparty ? "True" : "False");
7299d7109c994bec237bdf1fff158d9400cbfb1b5c9Luiz Augusto von Dentz		vc->conference = multiparty;
7309fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	}
7319fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
7329fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	return TRUE;
7339fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz}
7349fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
7359fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentzstatic struct voice_call *call_new(const char *path, DBusMessageIter *properties)
7369fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz{
7379fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	struct voice_call *vc;
7389fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
7399fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	DBG("%s", path);
7409fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
7419fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	vc = g_new0(struct voice_call, 1);
7429fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	vc->obj_path = g_strdup(path);
7439fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	vc->watch = g_dbus_add_signal_watch(connection, NULL, path,
7449fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz					OFONO_VC_INTERFACE, "PropertyChanged",
7459fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz					handle_vc_property_changed, vc, NULL);
7469fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
7479fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	while (dbus_message_iter_get_arg_type(properties)
7489fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz						== DBUS_TYPE_DICT_ENTRY) {
7499fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		DBusMessageIter entry, value;
7509fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		const char *property, *cli, *state;
7519d7109c994bec237bdf1fff158d9400cbfb1b5c9Luiz Augusto von Dentz		dbus_bool_t multiparty;
7529fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
7539fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		dbus_message_iter_recurse(properties, &entry);
7549fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		dbus_message_iter_get_basic(&entry, &property);
7559fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
7569fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		dbus_message_iter_next(&entry);
7579fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		dbus_message_iter_recurse(&entry, &value);
7589fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
7599fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		if (g_str_equal(property, "LineIdentification")) {
7609fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz			dbus_message_iter_get_basic(&value, &cli);
7619fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz			DBG("cli %s", cli);
7629fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz			vc->number = g_strdup(cli);
7639fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		} else if (g_str_equal(property, "State")) {
7649fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz			dbus_message_iter_get_basic(&value, &state);
7659fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz			DBG("state %s", state);
7669fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz			if (g_str_equal(state, "incoming"))
7679fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz				vc->status = CALL_STATUS_INCOMING;
7689fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz			else if (g_str_equal(state, "dialing"))
7699fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz				vc->status = CALL_STATUS_DIALING;
7709fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz			else if (g_str_equal(state, "alerting"))
7719fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz				vc->status = CALL_STATUS_ALERTING;
7729fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz			else if (g_str_equal(state, "waiting"))
7739fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz				vc->status = CALL_STATUS_WAITING;
774d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz			else if (g_str_equal(state, "held"))
775d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz				vc->status = CALL_STATUS_HELD;
7769d7109c994bec237bdf1fff158d9400cbfb1b5c9Luiz Augusto von Dentz		} else if (g_str_equal(property, "Multiparty")) {
7779d7109c994bec237bdf1fff158d9400cbfb1b5c9Luiz Augusto von Dentz			dbus_message_iter_get_basic(&value, &multiparty);
7789d7109c994bec237bdf1fff158d9400cbfb1b5c9Luiz Augusto von Dentz			DBG("Multipary %s", multiparty ? "True" : "False");
7799d7109c994bec237bdf1fff158d9400cbfb1b5c9Luiz Augusto von Dentz			vc->conference = multiparty;
7809fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		}
7819fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
7829fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		dbus_message_iter_next(properties);
7839fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	}
7849fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
7859fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	switch (vc->status) {
7869fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	case CALL_STATUS_INCOMING:
7879fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		DBG("CALL_STATUS_INCOMING");
7889fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		vc->originating = FALSE;
7899fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		telephony_update_indicator(ofono_indicators, "callsetup",
7909fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz					EV_CALLSETUP_INCOMING);
7919fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		telephony_incoming_call_ind(vc->number, NUMBER_TYPE_TELEPHONY);
7929fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		break;
7939fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	case CALL_STATUS_DIALING:
7949fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		DBG("CALL_STATUS_DIALING");
7959fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		vc->originating = TRUE;
7969fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		g_free(last_dialed_number);
7979fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		last_dialed_number = g_strdup(vc->number);
7989fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		telephony_update_indicator(ofono_indicators, "callsetup",
7999fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz					EV_CALLSETUP_OUTGOING);
8009fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		break;
8019fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	case CALL_STATUS_ALERTING:
8029fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		DBG("CALL_STATUS_ALERTING");
8039fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		vc->originating = TRUE;
8049fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		g_free(last_dialed_number);
8059fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		last_dialed_number = g_strdup(vc->number);
8069fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		telephony_update_indicator(ofono_indicators, "callsetup",
8079fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz					EV_CALLSETUP_ALERTING);
8089fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		break;
8099fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	case CALL_STATUS_WAITING:
8109fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		DBG("CALL_STATUS_WAITING");
8119fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		vc->originating = FALSE;
8129fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		telephony_update_indicator(ofono_indicators, "callsetup",
8139fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz					EV_CALLSETUP_INCOMING);
8149fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		telephony_call_waiting_ind(vc->number, NUMBER_TYPE_TELEPHONY);
8159fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		break;
8169fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	}
8179fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
8189fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	return vc;
8199fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz}
8209fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
821c49dc8c7c815191b5825896f827cac2e2ff395ffLuiz Augusto von Dentzstatic void remove_pending(DBusPendingCall *call)
822c49dc8c7c815191b5825896f827cac2e2ff395ffLuiz Augusto von Dentz{
823c49dc8c7c815191b5825896f827cac2e2ff395ffLuiz Augusto von Dentz	pending = g_slist_remove(pending, call);
824c49dc8c7c815191b5825896f827cac2e2ff395ffLuiz Augusto von Dentz	dbus_pending_call_unref(call);
825c49dc8c7c815191b5825896f827cac2e2ff395ffLuiz Augusto von Dentz}
826c49dc8c7c815191b5825896f827cac2e2ff395ffLuiz Augusto von Dentz
8279fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentzstatic void call_added(const char *path, DBusMessageIter *properties)
8289fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz{
8299fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	struct voice_call *vc;
8309fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
8319fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	DBG("%s", path);
8329fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
8339fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	vc = find_vc(path);
8349fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	if (vc)
8359fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		return;
8369fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
8379fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	vc = call_new(path, properties);
8389fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	calls = g_slist_prepend(calls, vc);
8399fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz}
8409fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
8419fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentzstatic void get_calls_reply(DBusPendingCall *call, void *user_data)
8429fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz{
8439fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	DBusError err;
8449fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	DBusMessage *reply;
8459fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	DBusMessageIter iter, entry;
8469fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
8479fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	DBG("");
8489fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	reply = dbus_pending_call_steal_reply(call);
8499fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
8509fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	dbus_error_init(&err);
8519fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	if (dbus_set_error_from_message(&err, reply)) {
8529fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		error("ofono replied with an error: %s, %s",
8539fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz				err.name, err.message);
8549fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		dbus_error_free(&err);
8559fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		goto done;
8569fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	}
8579fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
8589fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	dbus_message_iter_init(reply, &iter);
8599fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
8609fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY) {
8619fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		error("Unexpected signature");
8629fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		goto done;
8639fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	}
8649fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
8659fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	dbus_message_iter_recurse(&iter, &entry);
8669fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
8679fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	while (dbus_message_iter_get_arg_type(&entry)
8689fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz						== DBUS_TYPE_STRUCT) {
8699fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		const char *path;
8709fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		DBusMessageIter value, properties;
8719fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
8729fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		dbus_message_iter_recurse(&entry, &value);
8739fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		dbus_message_iter_get_basic(&value, &path);
8749fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
8759fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		dbus_message_iter_next(&value);
8769fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		dbus_message_iter_recurse(&value, &properties);
8779fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
8789fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		call_added(path, &properties);
8799fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
8809fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		dbus_message_iter_next(&entry);
8819fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	}
8829fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
8839fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentzdone:
8849fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	dbus_message_unref(reply);
885c49dc8c7c815191b5825896f827cac2e2ff395ffLuiz Augusto von Dentz	remove_pending(call);
8869fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz}
8879fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
888e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentzstatic void handle_network_property(const char *property, DBusMessageIter *variant)
889a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
89083003660808c30390f21c569a5ba7dbdd8344a41Claudio Takahasi	const char *status, *operator;
891a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	unsigned int signals_bar;
892a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
893a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	if (g_str_equal(property, "Status")) {
894e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz		dbus_message_iter_get_basic(variant, &status);
8958e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan		DBG("Status is %s", status);
896a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		if (g_str_equal(status, "registered")) {
897a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			net.status = NETWORK_REG_STATUS_HOME;
898a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			telephony_update_indicator(ofono_indicators,
899a34c155f55270b917795d003be24488f53d9b711Forrest Zhao						"roam", EV_ROAM_INACTIVE);
900a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			telephony_update_indicator(ofono_indicators,
901a34c155f55270b917795d003be24488f53d9b711Forrest Zhao						"service", EV_SERVICE_PRESENT);
902a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		} else if (g_str_equal(status, "roaming")) {
903a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			net.status = NETWORK_REG_STATUS_ROAM;
904a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			telephony_update_indicator(ofono_indicators,
905a34c155f55270b917795d003be24488f53d9b711Forrest Zhao						"roam", EV_ROAM_ACTIVE);
906a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			telephony_update_indicator(ofono_indicators,
907a34c155f55270b917795d003be24488f53d9b711Forrest Zhao						"service", EV_SERVICE_PRESENT);
908a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		} else {
909a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			net.status = NETWORK_REG_STATUS_NOSERV;
910a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			telephony_update_indicator(ofono_indicators,
911a34c155f55270b917795d003be24488f53d9b711Forrest Zhao						"roam", EV_ROAM_INACTIVE);
912a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			telephony_update_indicator(ofono_indicators,
913a34c155f55270b917795d003be24488f53d9b711Forrest Zhao						"service", EV_SERVICE_NONE);
914a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		}
915e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	} else if (g_str_equal(property, "Name")) {
916e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz		dbus_message_iter_get_basic(variant, &operator);
9178e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan		DBG("Operator is %s", operator);
918a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		g_free(net.operator_name);
919a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		net.operator_name = g_strdup(operator);
920a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	} else if (g_str_equal(property, "SignalStrength")) {
921e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz		dbus_message_iter_get_basic(variant, &signals_bar);
9228e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan		DBG("SignalStrength is %d", signals_bar);
923a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		net.signals_bar = signals_bar;
924a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		telephony_update_indicator(ofono_indicators, "signal",
925a34c155f55270b917795d003be24488f53d9b711Forrest Zhao						(signals_bar + 20) / 21);
926a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	}
927a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
928a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
929e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentzstatic int parse_network_properties(DBusMessageIter *properties)
930a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
931a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	uint32_t features = AG_FEATURE_EC_ANDOR_NR |
9325e072a21aa4d68fdcfa605ef31427411c643e8bdLuiz Augusto von Dentz				AG_FEATURE_INBAND_RINGTONE |
933a34c155f55270b917795d003be24488f53d9b711Forrest Zhao				AG_FEATURE_REJECT_A_CALL |
934a34c155f55270b917795d003be24488f53d9b711Forrest Zhao				AG_FEATURE_ENHANCED_CALL_STATUS |
935d8ee95eb6d31fa715398a785b4b79846ca0a1f70Luiz Augusto von Dentz				AG_FEATURE_ENHANCED_CALL_CONTROL |
9369d7109c994bec237bdf1fff158d9400cbfb1b5c9Luiz Augusto von Dentz				AG_FEATURE_EXTENDED_ERROR_RESULT_CODES |
9379d7109c994bec237bdf1fff158d9400cbfb1b5c9Luiz Augusto von Dentz				AG_FEATURE_THREE_WAY_CALLING;
938d8fbf5b42f6a7fff8326b1a69d267640db45b367Luiz Augusto von Dentz	int i;
939d8fbf5b42f6a7fff8326b1a69d267640db45b367Luiz Augusto von Dentz
940d8fbf5b42f6a7fff8326b1a69d267640db45b367Luiz Augusto von Dentz	/* Reset indicators */
941d8fbf5b42f6a7fff8326b1a69d267640db45b367Luiz Augusto von Dentz	for (i = 0; ofono_indicators[i].desc != NULL; i++) {
942d8fbf5b42f6a7fff8326b1a69d267640db45b367Luiz Augusto von Dentz		if (g_str_equal(ofono_indicators[i].desc, "battchg"))
943d8fbf5b42f6a7fff8326b1a69d267640db45b367Luiz Augusto von Dentz			ofono_indicators[i].val = 5;
944d8fbf5b42f6a7fff8326b1a69d267640db45b367Luiz Augusto von Dentz		else
945d8fbf5b42f6a7fff8326b1a69d267640db45b367Luiz Augusto von Dentz			ofono_indicators[i].val = 0;
946d8fbf5b42f6a7fff8326b1a69d267640db45b367Luiz Augusto von Dentz	}
947a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
948e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	while (dbus_message_iter_get_arg_type(properties)
949e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz						== DBUS_TYPE_DICT_ENTRY) {
950e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz		const char *key;
951e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz		DBusMessageIter value, entry;
952e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz
953e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz		dbus_message_iter_recurse(properties, &entry);
954e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz		dbus_message_iter_get_basic(&entry, &key);
955e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz
956e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz		dbus_message_iter_next(&entry);
957e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz		dbus_message_iter_recurse(&entry, &value);
958e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz
959e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz		handle_network_property(key, &value);
960e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz
961e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz		dbus_message_iter_next(properties);
962e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	}
963e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz
964e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	telephony_ready_ind(features, ofono_indicators, BTRH_NOT_SUPPORTED,
965e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz								chld_str);
966e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz
967e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	return 0;
968e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz}
969e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz
970e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentzstatic void get_properties_reply(DBusPendingCall *call, void *user_data)
971e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz{
972e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	DBusError err;
973e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	DBusMessage *reply;
974e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	DBusMessageIter iter, properties;
975e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	int ret = 0;
976e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz
977e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	DBG("");
978a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	reply = dbus_pending_call_steal_reply(call);
979a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
980a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	dbus_error_init(&err);
981a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	if (dbus_set_error_from_message(&err, reply)) {
982a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		error("ofono replied with an error: %s, %s",
983a34c155f55270b917795d003be24488f53d9b711Forrest Zhao				err.name, err.message);
984a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		dbus_error_free(&err);
985a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		goto done;
986a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	}
987a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
988a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	dbus_message_iter_init(reply, &iter);
989a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
990a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY) {
991e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz		error("Unexpected signature");
992a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		goto done;
993a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	}
994a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
995e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	dbus_message_iter_recurse(&iter, &properties);
996a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
997e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	ret = parse_network_properties(&properties);
9989fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	if (ret < 0) {
999e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz		error("Unable to parse %s.GetProperty reply",
1000e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz						OFONO_NETWORKREG_INTERFACE);
10019fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		goto done;
10029fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	}
10039fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz
10049fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	ret = send_method_call(OFONO_BUS_NAME, modem_obj_path,
10059fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz				OFONO_VCMANAGER_INTERFACE, "GetCalls",
10069fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz				get_calls_reply, NULL, DBUS_TYPE_INVALID);
10079fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	if (ret < 0)
10089fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		error("Unable to send %s.GetCalls",
10099fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz						OFONO_VCMANAGER_INTERFACE);
1010a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1011a34c155f55270b917795d003be24488f53d9b711Forrest Zhaodone:
1012a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	dbus_message_unref(reply);
1013c49dc8c7c815191b5825896f827cac2e2ff395ffLuiz Augusto von Dentz	remove_pending(call);
1014a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
1015a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1016806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentzstatic void network_found(const char *path)
1017a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
1018e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	int ret;
1019c5321032b046c39477ab99a05e933b13d0b67a04Forrest Zhao
1020e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	DBG("%s", path);
1021e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz
1022e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	modem_obj_path = g_strdup(path);
1023e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz
1024e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	ret = send_method_call(OFONO_BUS_NAME, path,
1025e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz				OFONO_NETWORKREG_INTERFACE, "GetProperties",
1026e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz				get_properties_reply, NULL, DBUS_TYPE_INVALID);
1027e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	if (ret < 0)
1028e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz		error("Unable to send %s.GetProperties",
1029e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz						OFONO_NETWORKREG_INTERFACE);
1030a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
1031a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1032806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentzstatic void modem_removed(const char *path)
1033806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz{
1034806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	if (g_strcmp0(modem_obj_path, path) != 0)
1035806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		return;
1036806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
1037806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	DBG("%s", path);
1038806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
1039806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	g_slist_foreach(calls, (GFunc) call_free, NULL);
1040806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	g_slist_free(calls);
1041806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	calls = NULL;
1042806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
1043806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	g_free(net.operator_name);
1044806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	net.operator_name = NULL;
1045de8eb4773a1ac878b1b9b8e7306a3c1f4cfe43ebLuiz Augusto von Dentz	net.status = NETWORK_REG_STATUS_NOSERV;
1046de8eb4773a1ac878b1b9b8e7306a3c1f4cfe43ebLuiz Augusto von Dentz	net.signals_bar = 0;
1047806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
1048806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	g_free(modem_obj_path);
1049806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	modem_obj_path = NULL;
1050806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz}
1051806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
1052806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentzstatic void parse_modem_interfaces(const char *path, DBusMessageIter *ifaces)
1053806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz{
1054806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	DBG("%s", path);
1055806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
1056806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	while (dbus_message_iter_get_arg_type(ifaces) == DBUS_TYPE_STRING) {
1057806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		const char *iface;
1058806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
1059806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		dbus_message_iter_get_basic(ifaces, &iface);
1060806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
1061806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		if (g_str_equal(iface, OFONO_NETWORKREG_INTERFACE)) {
1062806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz			network_found(path);
1063806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz			return;
1064806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		}
1065806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
1066806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		dbus_message_iter_next(ifaces);
1067806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	}
1068806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
1069806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	modem_removed(path);
1070806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz}
1071806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
1072806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentzstatic void modem_added(const char *path, DBusMessageIter *properties)
1073806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz{
1074806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	if (modem_obj_path != NULL) {
1075806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		DBG("Ignoring, modem already exist");
1076806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		return;
1077806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	}
1078806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
1079806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	DBG("%s", path);
1080806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
1081806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	while (dbus_message_iter_get_arg_type(properties)
1082806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz						== DBUS_TYPE_DICT_ENTRY) {
1083806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		const char *key;
1084806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		DBusMessageIter interfaces, value, entry;
1085806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
1086806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		dbus_message_iter_recurse(properties, &entry);
1087806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		dbus_message_iter_get_basic(&entry, &key);
1088806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
1089806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		dbus_message_iter_next(&entry);
1090806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		dbus_message_iter_recurse(&entry, &value);
1091806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
1092806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		if (strcasecmp(key, "Interfaces") != 0)
1093806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz			goto next;
1094806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
1095806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		if (dbus_message_iter_get_arg_type(&value)
1096806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz							!= DBUS_TYPE_ARRAY) {
1097806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz			error("Invalid Signature");
1098806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz			return;
1099806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		}
1100806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
1101806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		dbus_message_iter_recurse(&value, &interfaces);
1102806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
1103806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		parse_modem_interfaces(path, &interfaces);
1104806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
1105806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		if (modem_obj_path != NULL)
1106806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz			return;
1107806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
1108806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	next:
1109806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		dbus_message_iter_next(properties);
1110806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	}
1111806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz}
1112806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
1113e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentzstatic void get_modems_reply(DBusPendingCall *call, void *user_data)
1114a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
1115a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	DBusError err;
1116a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	DBusMessage *reply;
1117e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	DBusMessageIter iter, entry;
1118a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
11198e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan	DBG("list_modem_reply is called\n");
1120a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	reply = dbus_pending_call_steal_reply(call);
1121a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1122a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	dbus_error_init(&err);
1123a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	if (dbus_set_error_from_message(&err, reply)) {
1124a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		error("ofono replied with an error: %s, %s",
1125a34c155f55270b917795d003be24488f53d9b711Forrest Zhao				err.name, err.message);
1126a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		dbus_error_free(&err);
1127a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		goto done;
1128a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	}
1129a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1130806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	/* Skip modem selection if a modem already exist */
1131806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	if (modem_obj_path != NULL)
1132806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		goto done;
1133806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
1134a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	dbus_message_iter_init(reply, &iter);
1135a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1136a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY) {
1137e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz		error("Unexpected signature");
1138a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		goto done;
1139a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	}
1140a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1141e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	dbus_message_iter_recurse(&iter, &entry);
1142a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1143806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	while (dbus_message_iter_get_arg_type(&entry)
1144806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz						== DBUS_TYPE_STRUCT) {
1145806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		const char *path;
1146806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		DBusMessageIter item, properties;
1147806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
1148806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		dbus_message_iter_recurse(&entry, &item);
1149806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		dbus_message_iter_get_basic(&item, &path);
1150806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
1151806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		dbus_message_iter_next(&item);
1152806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		dbus_message_iter_recurse(&item, &properties);
1153a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1154806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		modem_added(path, &properties);
1155806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		if (modem_obj_path != NULL)
1156806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz			break;
1157a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1158806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		dbus_message_iter_next(&entry);
1159806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	}
1160a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1161a34c155f55270b917795d003be24488f53d9b711Forrest Zhaodone:
1162a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	dbus_message_unref(reply);
1163c49dc8c7c815191b5825896f827cac2e2ff395ffLuiz Augusto von Dentz	remove_pending(call);
1164a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
1165a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1166e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentzstatic gboolean handle_network_property_changed(DBusConnection *conn,
11678309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz						DBusMessage *msg, void *data)
1168a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
1169e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	DBusMessageIter iter, variant;
1170a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	const char *property;
1171a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1172a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	dbus_message_iter_init(msg, &iter);
1173a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1174a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING) {
1175a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		error("Unexpected signature in networkregistration"
1176a34c155f55270b917795d003be24488f53d9b711Forrest Zhao					" PropertyChanged signal");
11778309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz		return TRUE;
1178a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	}
1179a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	dbus_message_iter_get_basic(&iter, &property);
11808e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan	DBG("in handle_registration_property_changed(),"
1181a34c155f55270b917795d003be24488f53d9b711Forrest Zhao					" the property is %s", property);
1182a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1183a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	dbus_message_iter_next(&iter);
1184e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	dbus_message_iter_recurse(&iter, &variant);
1185a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1186e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	handle_network_property(property, &variant);
11878309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz
11888309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	return TRUE;
1189a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
1190a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1191806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentzstatic void handle_modem_property(const char *path, const char *property,
1192806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz						DBusMessageIter *variant)
1193806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz{
1194806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	DBG("%s", property);
1195806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
1196806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	if (g_str_equal(property, "Interfaces")) {
1197806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		DBusMessageIter interfaces;
1198806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
1199806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		if (dbus_message_iter_get_arg_type(variant)
1200806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz							!= DBUS_TYPE_ARRAY) {
1201806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz			error("Invalid signature");
1202806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz			return;
1203806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		}
1204806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
1205806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		dbus_message_iter_recurse(variant, &interfaces);
1206806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		parse_modem_interfaces(path, &interfaces);
1207806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	}
1208806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz}
1209806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
1210806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentzstatic gboolean handle_modem_property_changed(DBusConnection *conn,
1211806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz						DBusMessage *msg, void *data)
1212806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz{
1213806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	DBusMessageIter iter, variant;
1214806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	const char *property, *path;
1215806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
1216806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	path = dbus_message_get_path(msg);
1217806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
1218806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	/* Ignore if modem already exist and paths doesn't match */
1219806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	if (modem_obj_path != NULL &&
1220806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz				g_str_equal(path, modem_obj_path) == FALSE)
1221806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		return TRUE;
1222806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
1223806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	dbus_message_iter_init(msg, &iter);
1224806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
1225806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING) {
1226806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		error("Unexpected signature in %s.%s PropertyChanged signal",
1227806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz					dbus_message_get_interface(msg),
1228806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz					dbus_message_get_member(msg));
1229806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz		return TRUE;
1230806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	}
1231806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
1232806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	dbus_message_iter_get_basic(&iter, &property);
1233806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
1234806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	dbus_message_iter_next(&iter);
1235806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	dbus_message_iter_recurse(&iter, &variant);
1236806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
1237806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	handle_modem_property(path, property, &variant);
1238806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
1239806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	return TRUE;
1240806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz}
1241806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz
12429fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentzstatic gboolean handle_vcmanager_call_added(DBusConnection *conn,
12439fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz						DBusMessage *msg, void *data)
1244a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
12459fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	DBusMessageIter iter, properties;
12469fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	const char *path = dbus_message_get_path(msg);
1247a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
12489fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	/* Ignore call if modem path doesn't math */
12499fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	if (g_strcmp0(modem_obj_path, path) != 0)
12509fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		return TRUE;
1251a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
12529fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	dbus_message_iter_init(msg, &iter);
1253a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
12549fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	if (dbus_message_iter_get_arg_type(&iter)
12559fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz						!= DBUS_TYPE_OBJECT_PATH) {
12569fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		error("Unexpected signature in %s.%s signal",
12579fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz					dbus_message_get_interface(msg),
12589fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz					dbus_message_get_member(msg));
12599fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		return TRUE;
1260a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	}
1261a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
12629fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	dbus_message_iter_get_basic(&iter, &path);
12639fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	dbus_message_iter_next(&iter);
12649fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	dbus_message_iter_recurse(&iter, &properties);
1265a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
12669fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	call_added(path, &properties);
1267a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
12689fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	return TRUE;
1269a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
1270a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
12719fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentzstatic void call_removed(const char *path)
1272a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
12739fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	struct voice_call *vc;
1274a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
12759fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	DBG("%s", path);
1276a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
12779fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	vc = find_vc(path);
12789fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	if (vc == NULL)
12799fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		return;
12808309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz
12819fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	calls = g_slist_remove(calls, vc);
12829fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	call_free(vc);
12838309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz}
12848309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz
12859fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentzstatic gboolean handle_vcmanager_call_removed(DBusConnection *conn,
12868309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz						DBusMessage *msg, void *data)
12878309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz{
12889fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	const char *path = dbus_message_get_path(msg);
12898309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz
12909fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	/* Ignore call if modem path doesn't math */
12919fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	if (g_strcmp0(modem_obj_path, path) != 0)
12928309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz		return TRUE;
12938309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz
12949fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	if (!dbus_message_get_args(msg, NULL,
12959fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz				DBUS_TYPE_OBJECT_PATH, &path,
12969fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz				DBUS_TYPE_INVALID)) {
12979fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz		error("Unexpected signature in %s.%s signal",
12989fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz					dbus_message_get_interface(msg),
12999fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz					dbus_message_get_member(msg));
13008309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz		return TRUE;
13018309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	}
13028309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz
13039fa0976e28224d25c62d4a68fd02a6e5134447e6Luiz Augusto von Dentz	call_removed(path);
13048309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz
13058309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	return TRUE;
1306a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
1307a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1308e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentzstatic gboolean handle_manager_modem_added(DBusConnection *conn,
1309e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz						DBusMessage *msg, void *data)
1310e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz{
1311e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	DBusMessageIter iter, properties;
1312e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	const char *path;
1313e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz
1314e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	if (modem_obj_path != NULL)
1315e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz		return TRUE;
1316e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz
1317e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	dbus_message_iter_init(msg, &iter);
1318e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz
1319e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	if (dbus_message_iter_get_arg_type(&iter)
1320e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz						!= DBUS_TYPE_OBJECT_PATH) {
1321e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz		error("Unexpected signature in %s.%s signal",
1322e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz					dbus_message_get_interface(msg),
1323e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz					dbus_message_get_member(msg));
1324e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz		return TRUE;
1325e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	}
1326e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz
1327e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	dbus_message_iter_get_basic(&iter, &path);
1328806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	dbus_message_iter_next(&iter);
1329e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	dbus_message_iter_recurse(&iter, &properties);
1330e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz
1331806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	modem_added(path, &properties);
1332e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz
1333e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	return TRUE;
1334e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz}
1335e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz
1336e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentzstatic gboolean handle_manager_modem_removed(DBusConnection *conn,
1337e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz						DBusMessage *msg, void *data)
1338e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz{
1339e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	const char *path;
1340e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz
1341e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	if (!dbus_message_get_args(msg, NULL,
1342e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz				DBUS_TYPE_OBJECT_PATH, &path,
1343e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz				DBUS_TYPE_INVALID)) {
1344e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz		error("Unexpected signature in %s.%s signal",
1345e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz					dbus_message_get_interface(msg),
1346e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz					dbus_message_get_member(msg));
1347e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz		return TRUE;
1348e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	}
1349e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz
1350e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	modem_removed(path);
1351e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz
1352e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	return TRUE;
1353e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz}
1354e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz
1355a34c155f55270b917795d003be24488f53d9b711Forrest Zhaostatic void hal_battery_level_reply(DBusPendingCall *call, void *user_data)
1356a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
1357a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	DBusMessage *reply;
1358a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	DBusError err;
1359a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	dbus_int32_t level;
1360a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	int *value = user_data;
1361a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1362a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	reply = dbus_pending_call_steal_reply(call);
1363a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1364a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	dbus_error_init(&err);
1365a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	if (dbus_set_error_from_message(&err, reply)) {
1366a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		error("hald replied with an error: %s, %s",
1367a34c155f55270b917795d003be24488f53d9b711Forrest Zhao				err.name, err.message);
1368a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		dbus_error_free(&err);
1369a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		goto done;
1370a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	}
1371a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1372463763c080cd72ecd727a218dd68f7c0ba95bc9eLuiz Augusto von Dentz	dbus_error_init(&err);
1373463763c080cd72ecd727a218dd68f7c0ba95bc9eLuiz Augusto von Dentz	if (dbus_message_get_args(reply, &err,
1374a34c155f55270b917795d003be24488f53d9b711Forrest Zhao				DBUS_TYPE_INT32, &level,
1375463763c080cd72ecd727a218dd68f7c0ba95bc9eLuiz Augusto von Dentz				DBUS_TYPE_INVALID) == FALSE) {
1376463763c080cd72ecd727a218dd68f7c0ba95bc9eLuiz Augusto von Dentz		error("Unable to parse GetPropertyInteger reply: %s, %s",
1377463763c080cd72ecd727a218dd68f7c0ba95bc9eLuiz Augusto von Dentz							err.name, err.message);
1378463763c080cd72ecd727a218dd68f7c0ba95bc9eLuiz Augusto von Dentz		dbus_error_free(&err);
1379463763c080cd72ecd727a218dd68f7c0ba95bc9eLuiz Augusto von Dentz		goto done;
1380463763c080cd72ecd727a218dd68f7c0ba95bc9eLuiz Augusto von Dentz	}
1381a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1382a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	*value = (int) level;
1383a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1384a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	if (value == &battchg_last)
13858e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan		DBG("telephony-ofono: battery.charge_level.last_full"
1386a34c155f55270b917795d003be24488f53d9b711Forrest Zhao					" is %d", *value);
1387a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	else if (value == &battchg_design)
13888e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan		DBG("telephony-ofono: battery.charge_level.design"
1389a34c155f55270b917795d003be24488f53d9b711Forrest Zhao					" is %d", *value);
1390a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	else
13918e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan		DBG("telephony-ofono: battery.charge_level.current"
1392a34c155f55270b917795d003be24488f53d9b711Forrest Zhao					" is %d", *value);
1393a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1394a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	if ((battchg_design > 0 || battchg_last > 0) && battchg_cur >= 0) {
13959ff86aa7f2c11cb3198dfcde93f8db3c534ecdb6Johan Hedberg		int new, max;
1396a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1397a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		if (battchg_last > 0)
1398a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			max = battchg_last;
1399a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		else
1400a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			max = battchg_design;
1401a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1402a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		new = battchg_cur * 5 / max;
1403a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
14049ff86aa7f2c11cb3198dfcde93f8db3c534ecdb6Johan Hedberg		telephony_update_indicator(ofono_indicators, "battchg", new);
1405a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	}
1406a34c155f55270b917795d003be24488f53d9b711Forrest Zhaodone:
1407a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	dbus_message_unref(reply);
1408c49dc8c7c815191b5825896f827cac2e2ff395ffLuiz Augusto von Dentz	remove_pending(call);
1409a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
1410a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1411a34c155f55270b917795d003be24488f53d9b711Forrest Zhaostatic void hal_get_integer(const char *path, const char *key, void *user_data)
1412a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
1413a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	send_method_call("org.freedesktop.Hal", path,
1414a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			"org.freedesktop.Hal.Device",
1415a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			"GetPropertyInteger",
1416a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			hal_battery_level_reply, user_data,
1417a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			DBUS_TYPE_STRING, &key,
1418a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			DBUS_TYPE_INVALID);
1419a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
1420a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
14218309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentzstatic gboolean handle_hal_property_modified(DBusConnection *conn,
14228309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz						DBusMessage *msg, void *data)
1423a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
1424a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	const char *path;
1425a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	DBusMessageIter iter, array;
1426a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	dbus_int32_t num_changes;
1427a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1428a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	path = dbus_message_get_path(msg);
1429a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1430a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	dbus_message_iter_init(msg, &iter);
1431a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1432a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_INT32) {
1433a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		error("Unexpected signature in hal PropertyModified signal");
14348309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz		return TRUE;
1435a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	}
1436a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1437a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	dbus_message_iter_get_basic(&iter, &num_changes);
1438a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	dbus_message_iter_next(&iter);
1439a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1440a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY) {
1441a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		error("Unexpected signature in hal PropertyModified signal");
14428309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz		return TRUE;
1443a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	}
1444a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1445a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	dbus_message_iter_recurse(&iter, &array);
1446a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1447a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	while (dbus_message_iter_get_arg_type(&array) != DBUS_TYPE_INVALID) {
1448a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		DBusMessageIter prop;
1449a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		const char *name;
1450a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		dbus_bool_t added, removed;
1451a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1452a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		dbus_message_iter_recurse(&array, &prop);
1453a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1454a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		if (!iter_get_basic_args(&prop,
1455a34c155f55270b917795d003be24488f53d9b711Forrest Zhao					DBUS_TYPE_STRING, &name,
1456a34c155f55270b917795d003be24488f53d9b711Forrest Zhao					DBUS_TYPE_BOOLEAN, &added,
1457a34c155f55270b917795d003be24488f53d9b711Forrest Zhao					DBUS_TYPE_BOOLEAN, &removed,
1458a34c155f55270b917795d003be24488f53d9b711Forrest Zhao					DBUS_TYPE_INVALID)) {
1459a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			error("Invalid hal PropertyModified parameters");
1460a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			break;
1461a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		}
1462a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1463a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		if (g_str_equal(name, "battery.charge_level.last_full"))
1464a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			hal_get_integer(path, name, &battchg_last);
1465a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		else if (g_str_equal(name, "battery.charge_level.current"))
1466a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			hal_get_integer(path, name, &battchg_cur);
1467a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		else if (g_str_equal(name, "battery.charge_level.design"))
1468a34c155f55270b917795d003be24488f53d9b711Forrest Zhao			hal_get_integer(path, name, &battchg_design);
1469a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1470a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		dbus_message_iter_next(&array);
1471a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	}
14728309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz
14738309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	return TRUE;
1474a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
1475a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
14769946e8636c3361dc769c5f8a463b74158018d3ddLuiz Augusto von Dentzstatic void add_watch(const char *sender, const char *path,
14779946e8636c3361dc769c5f8a463b74158018d3ddLuiz Augusto von Dentz				const char *interface, const char *member,
14789946e8636c3361dc769c5f8a463b74158018d3ddLuiz Augusto von Dentz				GDBusSignalFunction function)
14799946e8636c3361dc769c5f8a463b74158018d3ddLuiz Augusto von Dentz{
14809946e8636c3361dc769c5f8a463b74158018d3ddLuiz Augusto von Dentz	guint watch;
14819946e8636c3361dc769c5f8a463b74158018d3ddLuiz Augusto von Dentz
14829946e8636c3361dc769c5f8a463b74158018d3ddLuiz Augusto von Dentz	watch = g_dbus_add_signal_watch(connection, sender, path, interface,
14839946e8636c3361dc769c5f8a463b74158018d3ddLuiz Augusto von Dentz					member, function, NULL, NULL);
14849946e8636c3361dc769c5f8a463b74158018d3ddLuiz Augusto von Dentz
14859946e8636c3361dc769c5f8a463b74158018d3ddLuiz Augusto von Dentz	watches = g_slist_prepend(watches, GUINT_TO_POINTER(watch));
14869946e8636c3361dc769c5f8a463b74158018d3ddLuiz Augusto von Dentz}
14879946e8636c3361dc769c5f8a463b74158018d3ddLuiz Augusto von Dentz
14888309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentzstatic void hal_find_device_reply(DBusPendingCall *call, void *user_data)
1489a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
14908309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	DBusMessage *reply;
14918309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	DBusError err;
14928309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	DBusMessageIter iter, sub;
14938309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	int type;
14948309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	const char *path;
14958309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz
14968e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan	DBG("begin of hal_find_device_reply()");
14978309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	reply = dbus_pending_call_steal_reply(call);
14988309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz
14998309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	dbus_error_init(&err);
15008309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz
15018309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	if (dbus_set_error_from_message(&err, reply)) {
15028309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz		error("hald replied with an error: %s, %s",
15038309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz				err.name, err.message);
15048309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz		dbus_error_free(&err);
15058309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz		goto done;
15068309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	}
15078309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz
15088309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	dbus_message_iter_init(reply, &iter);
15098309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz
15108309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY) {
15118309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz		error("Unexpected signature in hal_find_device_reply()");
15128309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz		goto done;
15138309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	}
15148309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz
15158309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	dbus_message_iter_recurse(&iter, &sub);
15168309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz
15178309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	type = dbus_message_iter_get_arg_type(&sub);
15188309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz
15198309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	if (type != DBUS_TYPE_OBJECT_PATH && type != DBUS_TYPE_STRING) {
15208309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz		error("No hal device with battery capability found");
15218309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz		goto done;
15228309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	}
15238309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz
15248309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	dbus_message_iter_get_basic(&sub, &path);
15258309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz
15268e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan	DBG("telephony-ofono: found battery device at %s", path);
15278309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz
15289946e8636c3361dc769c5f8a463b74158018d3ddLuiz Augusto von Dentz	add_watch(NULL, path, "org.freedesktop.Hal.Device",
15299946e8636c3361dc769c5f8a463b74158018d3ddLuiz Augusto von Dentz			"PropertyModified", handle_hal_property_modified);
15308309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz
15318309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	hal_get_integer(path, "battery.charge_level.last_full", &battchg_last);
15328309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	hal_get_integer(path, "battery.charge_level.current", &battchg_cur);
15338309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	hal_get_integer(path, "battery.charge_level.design", &battchg_design);
15348309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentzdone:
15358309018a3f1e381c95a019071b6e870e6363bd9bLuiz Augusto von Dentz	dbus_message_unref(reply);
1536c49dc8c7c815191b5825896f827cac2e2ff395ffLuiz Augusto von Dentz	remove_pending(call);
1537a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
1538a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1539c7b0c8e099b8fdfa1ad2a905d6f482beb3aaddaaLuiz Augusto von Dentzstatic void handle_service_connect(DBusConnection *conn, void *user_data)
1540c7b0c8e099b8fdfa1ad2a905d6f482beb3aaddaaLuiz Augusto von Dentz{
1541c7b0c8e099b8fdfa1ad2a905d6f482beb3aaddaaLuiz Augusto von Dentz	DBG("telephony-ofono: %s found", OFONO_BUS_NAME);
1542c7b0c8e099b8fdfa1ad2a905d6f482beb3aaddaaLuiz Augusto von Dentz
1543c7b0c8e099b8fdfa1ad2a905d6f482beb3aaddaaLuiz Augusto von Dentz	send_method_call(OFONO_BUS_NAME, OFONO_PATH,
1544c7b0c8e099b8fdfa1ad2a905d6f482beb3aaddaaLuiz Augusto von Dentz				OFONO_MANAGER_INTERFACE, "GetModems",
1545c7b0c8e099b8fdfa1ad2a905d6f482beb3aaddaaLuiz Augusto von Dentz				get_modems_reply, NULL, DBUS_TYPE_INVALID);
1546c7b0c8e099b8fdfa1ad2a905d6f482beb3aaddaaLuiz Augusto von Dentz}
1547c7b0c8e099b8fdfa1ad2a905d6f482beb3aaddaaLuiz Augusto von Dentz
1548c7b0c8e099b8fdfa1ad2a905d6f482beb3aaddaaLuiz Augusto von Dentzstatic void handle_service_disconnect(DBusConnection *conn, void *user_data)
1549c7b0c8e099b8fdfa1ad2a905d6f482beb3aaddaaLuiz Augusto von Dentz{
1550c7b0c8e099b8fdfa1ad2a905d6f482beb3aaddaaLuiz Augusto von Dentz	DBG("telephony-ofono: %s exitted", OFONO_BUS_NAME);
1551c7b0c8e099b8fdfa1ad2a905d6f482beb3aaddaaLuiz Augusto von Dentz
1552c7b0c8e099b8fdfa1ad2a905d6f482beb3aaddaaLuiz Augusto von Dentz	if (modem_obj_path)
1553c7b0c8e099b8fdfa1ad2a905d6f482beb3aaddaaLuiz Augusto von Dentz		modem_removed(modem_obj_path);
1554c7b0c8e099b8fdfa1ad2a905d6f482beb3aaddaaLuiz Augusto von Dentz}
1555c7b0c8e099b8fdfa1ad2a905d6f482beb3aaddaaLuiz Augusto von Dentz
1556a34c155f55270b917795d003be24488f53d9b711Forrest Zhaoint telephony_init(void)
1557a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
1558a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	const char *battery_cap = "battery";
1559a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	int ret;
1560c7b0c8e099b8fdfa1ad2a905d6f482beb3aaddaaLuiz Augusto von Dentz	guint watch;
1561a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1562a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	connection = dbus_bus_get(DBUS_BUS_SYSTEM, NULL);
1563a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1564806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz	add_watch(OFONO_BUS_NAME, NULL, OFONO_MODEM_INTERFACE,
1565806c74dbebe7402d0485f80854b95aca8e68fceaLuiz Augusto von Dentz			"PropertyChanged", handle_modem_property_changed);
15669946e8636c3361dc769c5f8a463b74158018d3ddLuiz Augusto von Dentz	add_watch(OFONO_BUS_NAME, NULL, OFONO_NETWORKREG_INTERFACE,
15679946e8636c3361dc769c5f8a463b74158018d3ddLuiz Augusto von Dentz			"PropertyChanged", handle_network_property_changed);
15689946e8636c3361dc769c5f8a463b74158018d3ddLuiz Augusto von Dentz	add_watch(OFONO_BUS_NAME, NULL, OFONO_MANAGER_INTERFACE,
15699946e8636c3361dc769c5f8a463b74158018d3ddLuiz Augusto von Dentz			"ModemAdded", handle_manager_modem_added);
15709946e8636c3361dc769c5f8a463b74158018d3ddLuiz Augusto von Dentz	add_watch(OFONO_BUS_NAME, NULL, OFONO_MANAGER_INTERFACE,
15719946e8636c3361dc769c5f8a463b74158018d3ddLuiz Augusto von Dentz			"ModemRemoved", handle_manager_modem_removed);
15729946e8636c3361dc769c5f8a463b74158018d3ddLuiz Augusto von Dentz	add_watch(OFONO_BUS_NAME, NULL, OFONO_VCMANAGER_INTERFACE,
15739946e8636c3361dc769c5f8a463b74158018d3ddLuiz Augusto von Dentz			"CallAdded", handle_vcmanager_call_added);
15749946e8636c3361dc769c5f8a463b74158018d3ddLuiz Augusto von Dentz	add_watch(OFONO_BUS_NAME, NULL, OFONO_VCMANAGER_INTERFACE,
15759946e8636c3361dc769c5f8a463b74158018d3ddLuiz Augusto von Dentz			"CallRemoved", handle_vcmanager_call_removed);
1576a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1577c7b0c8e099b8fdfa1ad2a905d6f482beb3aaddaaLuiz Augusto von Dentz	watch = g_dbus_add_service_watch(connection, OFONO_BUS_NAME,
1578c7b0c8e099b8fdfa1ad2a905d6f482beb3aaddaaLuiz Augusto von Dentz						handle_service_connect,
1579c7b0c8e099b8fdfa1ad2a905d6f482beb3aaddaaLuiz Augusto von Dentz						handle_service_disconnect,
1580c7b0c8e099b8fdfa1ad2a905d6f482beb3aaddaaLuiz Augusto von Dentz						NULL, NULL);
1581c7b0c8e099b8fdfa1ad2a905d6f482beb3aaddaaLuiz Augusto von Dentz	if (watch == 0)
1582c7b0c8e099b8fdfa1ad2a905d6f482beb3aaddaaLuiz Augusto von Dentz		return -ENOMEM;
1583c7b0c8e099b8fdfa1ad2a905d6f482beb3aaddaaLuiz Augusto von Dentz
1584c7b0c8e099b8fdfa1ad2a905d6f482beb3aaddaaLuiz Augusto von Dentz	watches = g_slist_prepend(watches, GUINT_TO_POINTER(watch));
1585a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1586a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	ret = send_method_call("org.freedesktop.Hal",
1587a34c155f55270b917795d003be24488f53d9b711Forrest Zhao				"/org/freedesktop/Hal/Manager",
1588a34c155f55270b917795d003be24488f53d9b711Forrest Zhao				"org.freedesktop.Hal.Manager",
1589a34c155f55270b917795d003be24488f53d9b711Forrest Zhao				"FindDeviceByCapability",
1590a34c155f55270b917795d003be24488f53d9b711Forrest Zhao				hal_find_device_reply, NULL,
1591a34c155f55270b917795d003be24488f53d9b711Forrest Zhao				DBUS_TYPE_STRING, &battery_cap,
1592a34c155f55270b917795d003be24488f53d9b711Forrest Zhao				DBUS_TYPE_INVALID);
1593a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	if (ret < 0)
1594a34c155f55270b917795d003be24488f53d9b711Forrest Zhao		return ret;
1595a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
15968e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan	DBG("telephony_init() successfully");
1597a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1598a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	return ret;
1599a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
1600a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
16019946e8636c3361dc769c5f8a463b74158018d3ddLuiz Augusto von Dentzstatic void remove_watch(gpointer data)
16029946e8636c3361dc769c5f8a463b74158018d3ddLuiz Augusto von Dentz{
16039946e8636c3361dc769c5f8a463b74158018d3ddLuiz Augusto von Dentz	g_dbus_remove_watch(connection, GPOINTER_TO_UINT(data));
16049946e8636c3361dc769c5f8a463b74158018d3ddLuiz Augusto von Dentz}
16059946e8636c3361dc769c5f8a463b74158018d3ddLuiz Augusto von Dentz
1606a34c155f55270b917795d003be24488f53d9b711Forrest Zhaovoid telephony_exit(void)
1607a34c155f55270b917795d003be24488f53d9b711Forrest Zhao{
1608e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	DBG("");
1609a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1610a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	g_free(last_dialed_number);
1611e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	last_dialed_number = NULL;
1612a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1613e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz	if (modem_obj_path)
1614e2f9bfa4b8ce406d93f38f248ffd2e503bb4a7a6Luiz Augusto von Dentz		modem_removed(modem_obj_path);
1615a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
16169946e8636c3361dc769c5f8a463b74158018d3ddLuiz Augusto von Dentz	g_slist_foreach(watches, (GFunc) remove_watch, NULL);
16179946e8636c3361dc769c5f8a463b74158018d3ddLuiz Augusto von Dentz	g_slist_free(watches);
16189946e8636c3361dc769c5f8a463b74158018d3ddLuiz Augusto von Dentz	watches = NULL;
1619a34c155f55270b917795d003be24488f53d9b711Forrest Zhao
1620c49dc8c7c815191b5825896f827cac2e2ff395ffLuiz Augusto von Dentz	g_slist_foreach(pending, (GFunc) dbus_pending_call_cancel, NULL);
1621c49dc8c7c815191b5825896f827cac2e2ff395ffLuiz Augusto von Dentz	g_slist_foreach(pending, (GFunc) dbus_pending_call_unref, NULL);
1622c49dc8c7c815191b5825896f827cac2e2ff395ffLuiz Augusto von Dentz	g_slist_free(pending);
1623c49dc8c7c815191b5825896f827cac2e2ff395ffLuiz Augusto von Dentz	pending = NULL;
1624c49dc8c7c815191b5825896f827cac2e2ff395ffLuiz Augusto von Dentz
1625a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	dbus_connection_unref(connection);
1626a34c155f55270b917795d003be24488f53d9b711Forrest Zhao	connection = NULL;
1627401be3748717fae613041592778a3a7160fb763cJohan Hedberg
1628401be3748717fae613041592778a3a7160fb763cJohan Hedberg	telephony_deinit();
1629a34c155f55270b917795d003be24488f53d9b711Forrest Zhao}
1630