3
* BlueZ - Bluetooth protocol stack for Linux
5
* Copyright (C) 2006-2010 Nokia Corporation
6
* Copyright (C) 2004-2010 Marcel Holtmann <marcel@holtmann.org>
9
* This program is free software; you can redistribute it and/or modify
10
* it under the terms of the GNU General Public License as published by
11
* the Free Software Foundation; either version 2 of the License, or
12
* (at your option) any later version.
14
* This program is distributed in the hope that it will be useful,
15
* but WITHOUT ANY WARRANTY; without even the implied warranty of
16
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
* GNU General Public License for more details.
19
* You should have received a copy of the GNU General Public License
20
* along with this program; if not, write to the Free Software
21
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
33
#include <dbus/dbus.h>
37
#include "telephony.h"
40
#define TELEPHONY_DUMMY_IFACE "org.bluez.TelephonyTest"
41
#define TELEPHONY_DUMMY_PATH "/org/bluez/test"
43
static DBusConnection *connection = NULL;
45
static const char *chld_str = "0,1,1x,2,2x,3,4";
46
static char *subscriber_number = NULL;
47
static char *active_call_number = NULL;
48
static int active_call_status = 0;
49
static int active_call_dir = 0;
51
static gboolean events_enabled = FALSE;
53
static struct indicator dummy_indicators[] =
55
{ "battchg", "0-5", 5, TRUE },
56
{ "signal", "0-5", 5, TRUE },
57
{ "service", "0,1", 1, TRUE },
58
{ "call", "0,1", 0, TRUE },
59
{ "callsetup", "0-3", 0, TRUE },
60
{ "callheld", "0-2", 0, FALSE },
61
{ "roam", "0,1", 0, TRUE },
65
void telephony_device_connected(void *telephony_device)
67
DBG("telephony-dummy: device %p connected", telephony_device);
70
void telephony_device_disconnected(void *telephony_device)
72
DBG("telephony-dummy: device %p disconnected", telephony_device);
73
events_enabled = FALSE;
76
void telephony_event_reporting_req(void *telephony_device, int ind)
78
events_enabled = ind == 1 ? TRUE : FALSE;
80
telephony_event_reporting_rsp(telephony_device, CME_ERROR_NONE);
83
void telephony_response_and_hold_req(void *telephony_device, int rh)
85
telephony_response_and_hold_rsp(telephony_device,
86
CME_ERROR_NOT_SUPPORTED);
89
void telephony_last_dialed_number_req(void *telephony_device)
91
telephony_last_dialed_number_rsp(telephony_device, CME_ERROR_NONE);
93
/* Notify outgoing call set-up successfully initiated */
94
telephony_update_indicator(dummy_indicators, "callsetup",
95
EV_CALLSETUP_OUTGOING);
96
telephony_update_indicator(dummy_indicators, "callsetup",
97
EV_CALLSETUP_ALERTING);
99
active_call_status = CALL_STATUS_ALERTING;
100
active_call_dir = CALL_DIR_OUTGOING;
103
void telephony_terminate_call_req(void *telephony_device)
105
g_free(active_call_number);
106
active_call_number = NULL;
108
telephony_terminate_call_rsp(telephony_device, CME_ERROR_NONE);
110
if (telephony_get_indicator(dummy_indicators, "callsetup") > 0)
111
telephony_update_indicator(dummy_indicators, "callsetup",
112
EV_CALLSETUP_INACTIVE);
114
telephony_update_indicator(dummy_indicators, "call",
118
void telephony_answer_call_req(void *telephony_device)
120
telephony_answer_call_rsp(telephony_device, CME_ERROR_NONE);
122
telephony_update_indicator(dummy_indicators, "call", EV_CALL_ACTIVE);
123
telephony_update_indicator(dummy_indicators, "callsetup",
124
EV_CALLSETUP_INACTIVE);
126
active_call_status = CALL_STATUS_ACTIVE;
129
void telephony_dial_number_req(void *telephony_device, const char *number)
131
g_free(active_call_number);
132
active_call_number = g_strdup(number);
134
DBG("telephony-dummy: dial request to %s", active_call_number);
136
telephony_dial_number_rsp(telephony_device, CME_ERROR_NONE);
138
/* Notify outgoing call set-up successfully initiated */
139
telephony_update_indicator(dummy_indicators, "callsetup",
140
EV_CALLSETUP_OUTGOING);
141
telephony_update_indicator(dummy_indicators, "callsetup",
142
EV_CALLSETUP_ALERTING);
144
active_call_status = CALL_STATUS_ALERTING;
145
active_call_dir = CALL_DIR_OUTGOING;
148
void telephony_transmit_dtmf_req(void *telephony_device, char tone)
150
DBG("telephony-dummy: transmit dtmf: %c", tone);
151
telephony_transmit_dtmf_rsp(telephony_device, CME_ERROR_NONE);
154
void telephony_subscriber_number_req(void *telephony_device)
156
DBG("telephony-dummy: subscriber number request");
157
if (subscriber_number)
158
telephony_subscriber_number_ind(subscriber_number,
159
NUMBER_TYPE_TELEPHONY,
160
SUBSCRIBER_SERVICE_VOICE);
161
telephony_subscriber_number_rsp(telephony_device, CME_ERROR_NONE);
164
void telephony_list_current_calls_req(void *telephony_device)
166
DBG("telephony-dummy: list current calls request");
167
if (active_call_number)
168
telephony_list_current_call_ind(1, active_call_dir,
173
NUMBER_TYPE_TELEPHONY);
174
telephony_list_current_calls_rsp(telephony_device, CME_ERROR_NONE);
177
void telephony_operator_selection_req(void *telephony_device)
179
telephony_operator_selection_ind(OPERATOR_MODE_AUTO, "DummyOperator");
180
telephony_operator_selection_rsp(telephony_device, CME_ERROR_NONE);
183
void telephony_call_hold_req(void *telephony_device, const char *cmd)
185
DBG("telephony-dymmy: got call hold request %s", cmd);
186
telephony_call_hold_rsp(telephony_device, CME_ERROR_NONE);
189
void telephony_nr_and_ec_req(void *telephony_device, gboolean enable)
191
DBG("telephony-dummy: got %s NR and EC request",
192
enable ? "enable" : "disable");
194
telephony_nr_and_ec_rsp(telephony_device, CME_ERROR_NONE);
197
void telephony_voice_dial_req(void *telephony_device, gboolean enable)
199
DBG("telephony-dummy: got %s voice dial request",
200
enable ? "enable" : "disable");
202
g_dbus_emit_signal(connection, TELEPHONY_DUMMY_PATH,
203
TELEPHONY_DUMMY_IFACE, "VoiceDial",
206
telephony_voice_dial_rsp(telephony_device, CME_ERROR_NONE);
209
void telephony_key_press_req(void *telephony_device, const char *keys)
211
DBG("telephony-dummy: got key press request for %s", keys);
212
telephony_key_press_rsp(telephony_device, CME_ERROR_NONE);
215
/* D-Bus method handlers */
216
static DBusMessage *outgoing_call(DBusConnection *conn, DBusMessage *msg,
221
if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &number,
223
return btd_error_invalid_args(msg);
225
DBG("telephony-dummy: outgoing call to %s", number);
227
g_free(active_call_number);
228
active_call_number = g_strdup(number);
230
telephony_update_indicator(dummy_indicators, "callsetup",
231
EV_CALLSETUP_OUTGOING);
232
telephony_update_indicator(dummy_indicators, "callsetup",
233
EV_CALLSETUP_ALERTING);
235
active_call_status = CALL_STATUS_ALERTING;
236
active_call_dir = CALL_DIR_OUTGOING;
238
return dbus_message_new_method_return(msg);
241
static DBusMessage *incoming_call(DBusConnection *conn, DBusMessage *msg,
246
if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &number,
248
return btd_error_invalid_args(msg);
250
DBG("telephony-dummy: incoming call to %s", number);
252
g_free(active_call_number);
253
active_call_number = g_strdup(number);
255
telephony_update_indicator(dummy_indicators, "callsetup",
256
EV_CALLSETUP_INCOMING);
258
active_call_status = CALL_STATUS_INCOMING;
259
active_call_dir = CALL_DIR_INCOMING;
261
telephony_incoming_call_ind(number, NUMBER_TYPE_TELEPHONY);
263
return dbus_message_new_method_return(msg);
266
static DBusMessage *cancel_call(DBusConnection *conn, DBusMessage *msg,
269
DBG("telephony-dummy: cancel call");
271
g_free(active_call_number);
272
active_call_number = NULL;
274
if (telephony_get_indicator(dummy_indicators, "callsetup") > 0) {
275
telephony_update_indicator(dummy_indicators, "callsetup",
276
EV_CALLSETUP_INACTIVE);
277
telephony_calling_stopped_ind();
280
if (telephony_get_indicator(dummy_indicators, "call") > 0)
281
telephony_update_indicator(dummy_indicators, "call",
284
return dbus_message_new_method_return(msg);
287
static DBusMessage *signal_strength(DBusConnection *conn, DBusMessage *msg,
290
dbus_uint32_t strength;
292
if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_UINT32, &strength,
294
return btd_error_invalid_args(msg);
297
return btd_error_invalid_args(msg);
299
telephony_update_indicator(dummy_indicators, "signal", strength);
301
DBG("telephony-dummy: signal strength set to %u", strength);
303
return dbus_message_new_method_return(msg);
306
static DBusMessage *battery_level(DBusConnection *conn, DBusMessage *msg,
311
if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_UINT32, &level,
313
return btd_error_invalid_args(msg);
316
return btd_error_invalid_args(msg);
318
telephony_update_indicator(dummy_indicators, "battchg", level);
320
DBG("telephony-dummy: battery level set to %u", level);
322
return dbus_message_new_method_return(msg);
325
static DBusMessage *roaming_status(DBusConnection *conn, DBusMessage *msg,
331
if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_BOOLEAN, &roaming,
333
return btd_error_invalid_args(msg);
335
val = roaming ? EV_ROAM_ACTIVE : EV_ROAM_INACTIVE;
337
telephony_update_indicator(dummy_indicators, "roam", val);
339
DBG("telephony-dummy: roaming status set to %d", val);
341
return dbus_message_new_method_return(msg);
344
static DBusMessage *registration_status(DBusConnection *conn, DBusMessage *msg,
347
dbus_bool_t registration;
350
if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_BOOLEAN, ®istration,
352
return btd_error_invalid_args(msg);
354
val = registration ? EV_SERVICE_PRESENT : EV_SERVICE_NONE;
356
telephony_update_indicator(dummy_indicators, "service", val);
358
DBG("telephony-dummy: registration status set to %d", val);
360
return dbus_message_new_method_return(msg);
363
static DBusMessage *set_subscriber_number(DBusConnection *conn,
369
if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &number,
371
return btd_error_invalid_args(msg);
373
g_free(subscriber_number);
374
subscriber_number = g_strdup(number);
376
DBG("telephony-dummy: subscriber number set to %s", number);
378
return dbus_message_new_method_return(msg);
381
static const GDBusMethodTable dummy_methods[] = {
382
{ GDBUS_METHOD("OutgoingCall",
383
GDBUS_ARGS({ "number", "s" }), NULL,
385
{ GDBUS_METHOD("IncomingCall",
386
GDBUS_ARGS({ "number", "s" }), NULL,
388
{ GDBUS_METHOD("CancelCall", NULL, NULL, cancel_call) },
389
{ GDBUS_METHOD("SignalStrength",
390
GDBUS_ARGS({ "strength", "u" }), NULL,
392
{ GDBUS_METHOD("BatteryLevel",
393
GDBUS_ARGS({ "level", "u" }), NULL,
395
{ GDBUS_METHOD("RoamingStatus",
396
GDBUS_ARGS({ "roaming", "b" }), NULL,
398
{ GDBUS_METHOD("RegistrationStatus",
399
GDBUS_ARGS({ "registration", "b" }), NULL,
400
registration_status) },
401
{ GDBUS_METHOD("SetSubscriberNumber",
402
GDBUS_ARGS({ "number", "s" }), NULL,
403
set_subscriber_number) },
407
static const GDBusSignalTable dummy_signals[] = {
408
{ GDBUS_SIGNAL("VoiceDial", NULL) },
412
int telephony_init(void)
414
uint32_t features = AG_FEATURE_REJECT_A_CALL |
415
AG_FEATURE_ENHANCED_CALL_STATUS |
416
AG_FEATURE_EXTENDED_ERROR_RESULT_CODES;
420
connection = dbus_bus_get(DBUS_BUS_SYSTEM, NULL);
422
if (g_dbus_register_interface(connection, TELEPHONY_DUMMY_PATH,
423
TELEPHONY_DUMMY_IFACE,
424
dummy_methods, dummy_signals,
425
NULL, NULL, NULL) == FALSE) {
426
error("telephony-dummy interface %s init failed on path %s",
427
TELEPHONY_DUMMY_IFACE, TELEPHONY_DUMMY_PATH);
431
telephony_ready_ind(features, dummy_indicators, BTRH_NOT_SUPPORTED,
437
void telephony_exit(void)
441
g_dbus_unregister_interface(connection, TELEPHONY_DUMMY_PATH,
442
TELEPHONY_DUMMY_IFACE);
443
dbus_connection_unref(connection);