summaryrefslogtreecommitdiffstats
path: root/src/call-waiting.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/call-waiting.c')
-rw-r--r--src/call-waiting.c528
1 files changed, 0 insertions, 528 deletions
diff --git a/src/call-waiting.c b/src/call-waiting.c
deleted file mode 100644
index 29773b8b..00000000
--- a/src/call-waiting.c
+++ /dev/null
@@ -1,528 +0,0 @@
-/*
- *
- * oFono - Open Source Telephony
- *
- * Copyright (C) 2008-2009 Intel Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <string.h>
-#include <stdlib.h>
-#include <stdio.h>
-
-#include <dbus/dbus.h>
-#include <glib.h>
-#include <gdbus.h>
-
-#include "ofono.h"
-
-#include "driver.h"
-#include "common.h"
-#include "dbus-gsm.h"
-#include "modem.h"
-#include "ussd.h"
-
-#define CALL_WAITING_INTERFACE "org.ofono.CallWaiting"
-
-#define CALL_WAITING_FLAG_CACHED 0x1
-
-struct call_waiting_data {
- struct ofono_call_waiting_ops *ops;
- int flags;
- DBusMessage *pending;
- int conditions;
- int ss_req_type;
- int ss_req_cls;
-};
-
-static void cw_register_ss_controls(struct ofono_modem *modem);
-static void cw_unregister_ss_controls(struct ofono_modem *modem);
-
-static struct call_waiting_data *call_waiting_create()
-{
- struct call_waiting_data *r;
-
- r = g_new0(struct call_waiting_data, 1);
-
- return r;
-}
-
-static void call_waiting_destroy(gpointer data)
-{
- struct ofono_modem *modem = data;
- struct call_waiting_data *cw = modem->call_waiting;
-
- cw_unregister_ss_controls(modem);
-
- g_free(cw);
-}
-
-static void update_conditions(struct ofono_modem *modem, int new_conditions,
- int mask)
-{
- struct call_waiting_data *cw = modem->call_waiting;
- DBusConnection *conn = dbus_gsm_connection();
- char buf[64];
- int j;
- const char *value;
-
- for (j = 1; j <= BEARER_CLASS_PAD; j = j << 1) {
- if ((j & mask) == 0)
- continue;
-
- if ((cw->conditions & j) == (new_conditions & j))
- continue;
-
- if (new_conditions & j)
- value = "enabled";
- else
- value = "disabled";
-
- sprintf(buf, "%s", bearer_class_to_string(j));
- dbus_gsm_signal_property_changed(conn, modem->path,
- CALL_WAITING_INTERFACE,
- buf, DBUS_TYPE_STRING,
- &value);
- }
-
- cw->conditions = new_conditions;
-}
-
-static void property_append_cw_conditions(DBusMessageIter *dict,
- int conditions, int mask)
-{
- int i;
- const char *prop;
- const char *value;
-
- for (i = 1; i <= BEARER_CLASS_PAD; i = i << 1) {
- if (!(mask & i))
- continue;
-
- prop = bearer_class_to_string(i);
-
- if (conditions & i)
- value = "enabled";
- else
- value = "disabled";
-
- dbus_gsm_dict_append(dict, prop, DBUS_TYPE_STRING, &value);
- }
-}
-
-static void generate_ss_query_reply(struct ofono_modem *modem)
-{
- struct call_waiting_data *cw = modem->call_waiting;
- const char *sig = "(sa{sv})";
- const char *ss_type = ss_control_type_to_string(cw->ss_req_type);
- const char *context = "CallWaiting";
- DBusMessageIter iter;
- DBusMessageIter var;
- DBusMessageIter vstruct;
- DBusMessageIter dict;
- DBusMessage *reply;
-
- reply = dbus_message_new_method_return(cw->pending);
-
- dbus_message_iter_init_append(reply, &iter);
-
- dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &context);
-
- dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT, sig, &var);
-
- dbus_message_iter_open_container(&var, DBUS_TYPE_STRUCT, NULL,
- &vstruct);
-
- dbus_message_iter_append_basic(&vstruct, DBUS_TYPE_STRING,
- &ss_type);
-
- dbus_message_iter_open_container(&vstruct, DBUS_TYPE_ARRAY,
- PROPERTIES_ARRAY_SIGNATURE, &dict);
-
- property_append_cw_conditions(&dict, cw->conditions, cw->ss_req_cls);
-
- dbus_message_iter_close_container(&vstruct, &dict);
-
- dbus_message_iter_close_container(&var, &vstruct);
-
- dbus_message_iter_close_container(&iter, &var);
-
- dbus_gsm_pending_reply(&cw->pending, reply);
-}
-
-static void cw_ss_query_callback(const struct ofono_error *error, int status,
- void *data)
-{
- struct ofono_modem *modem = data;
- struct call_waiting_data *cw = modem->call_waiting;
-
- if (error->type != OFONO_ERROR_TYPE_NO_ERROR) {
- ofono_debug("setting CW via SS failed");
-
- cw->flags &= ~CALL_WAITING_FLAG_CACHED;
- dbus_gsm_pending_reply(&cw->pending,
- dbus_gsm_failed(cw->pending));
-
- return;
- }
-
- update_conditions(modem, status, BEARER_CLASS_VOICE);
- cw->flags |= CALL_WAITING_FLAG_CACHED;
-
- generate_ss_query_reply(modem);
-}
-
-static void cw_ss_set_callback(const struct ofono_error *error, void *data)
-{
- struct ofono_modem *modem = data;
- struct call_waiting_data *cw = modem->call_waiting;
- int cls;
-
- if (error->type != OFONO_ERROR_TYPE_NO_ERROR) {
- ofono_debug("setting CW via SS failed");
- dbus_gsm_pending_reply(&cw->pending,
- dbus_gsm_failed(cw->pending));
-
- return;
- }
-
- cls = cw->ss_req_cls | BEARER_CLASS_DEFAULT;
-
- cw->ops->query(modem, cw->ss_req_cls, cw_ss_query_callback, modem);
-}
-
-static gboolean cw_ss_control(struct ofono_modem *modem, int type,
- const char *sc, const char *sia,
- const char *sib, const char *sic,
- const char *dn, DBusMessage *msg)
-{
- struct call_waiting_data *cw = modem->call_waiting;
- DBusConnection *conn = dbus_gsm_connection();
- int cls = BEARER_CLASS_SS_DEFAULT;
- DBusMessage *reply;
-
- if (!cw)
- return FALSE;
-
- if (strcmp(sc, "43"))
- return FALSE;
-
- if (cw->pending) {
- reply = dbus_gsm_busy(msg);
- goto error;
- }
-
- if (strlen(sib) || strlen(sib) || strlen(dn))
- goto bad_format;
-
- if ((type == SS_CONTROL_TYPE_QUERY && !cw->ops->query) ||
- (type != SS_CONTROL_TYPE_QUERY && !cw->ops->set)) {
- reply = dbus_gsm_not_implemented(msg);
- goto error;
- }
-
- if (strlen(sia) > 0) {
- long service_code;
- char *end;
-
- service_code = strtoul(sia, &end, 10);
-
- if (end == sia || *end != '\0')
- goto bad_format;
-
- cls = mmi_service_code_to_bearer_class(service_code);
- if (cls == 0)
- goto bad_format;
- }
-
- cw->ss_req_cls = cls;
- cw->pending = dbus_message_ref(msg);
-
- cls = BEARER_CLASS_DEFAULT;
-
- switch (type) {
- case SS_CONTROL_TYPE_REGISTRATION:
- case SS_CONTROL_TYPE_ACTIVATION:
- cw->ss_req_type = SS_CONTROL_TYPE_ACTIVATION;
- cw->ops->set(modem, 1, cls, cw_ss_set_callback, modem);
- break;
-
- case SS_CONTROL_TYPE_QUERY:
- cw->ss_req_type = SS_CONTROL_TYPE_QUERY;
- cw->ops->query(modem, cls, cw_ss_query_callback, modem);
- break;
-
- case SS_CONTROL_TYPE_DEACTIVATION:
- case SS_CONTROL_TYPE_ERASURE:
- cw->ss_req_type = SS_CONTROL_TYPE_DEACTIVATION;
- cw->ops->set(modem, 0, cls, cw_ss_set_callback, modem);
- break;
- }
-
- return TRUE;
-
-bad_format:
- reply = dbus_gsm_invalid_format(msg);
-error:
- g_dbus_send_message(conn, reply);
- return TRUE;
-}
-
-static void cw_register_ss_controls(struct ofono_modem *modem)
-{
- ss_control_register(modem, "43", cw_ss_control);
-}
-
-static void cw_unregister_ss_controls(struct ofono_modem *modem)
-{
- ss_control_unregister(modem, "43", cw_ss_control);
-}
-
-static DBusMessage *generate_get_properties_reply(struct ofono_modem *modem,
- DBusMessage *msg)
-{
- struct call_waiting_data *cw = modem->call_waiting;
- DBusMessage *reply;
- DBusMessageIter iter;
- DBusMessageIter dict;
-
- reply = dbus_message_new_method_return(msg);
-
- if (!reply)
- return NULL;
-
- dbus_message_iter_init_append(reply, &iter);
-
- dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
- PROPERTIES_ARRAY_SIGNATURE,
- &dict);
-
- property_append_cw_conditions(&dict, cw->conditions,
- BEARER_CLASS_VOICE);
-
- dbus_message_iter_close_container(&iter, &dict);
-
- return reply;
-}
-
-static void cw_query_callback(const struct ofono_error *error, int status,
- void *data)
-{
- struct ofono_modem *modem = data;
- struct call_waiting_data *cw = modem->call_waiting;
-
- if (error->type != OFONO_ERROR_TYPE_NO_ERROR) {
- ofono_debug("Error during cw query");
- goto out;
- }
-
- update_conditions(modem, status, BEARER_CLASS_VOICE);
- cw->flags |= CALL_WAITING_FLAG_CACHED;
-
-out:
- if (cw->pending) {
- DBusMessage *reply;
-
- reply = generate_get_properties_reply(modem, cw->pending);
- dbus_gsm_pending_reply(&cw->pending, reply);
- }
-}
-
-static DBusMessage *cw_get_properties(DBusConnection *conn, DBusMessage *msg,
- void *data)
-{
- struct ofono_modem *modem = data;
- struct call_waiting_data *cw = modem->call_waiting;
-
- if (cw->pending)
- return dbus_gsm_busy(msg);
-
- if (!cw->ops->query)
- return dbus_gsm_not_implemented(msg);
-
- if (cw->flags & CALL_WAITING_FLAG_CACHED)
- return generate_get_properties_reply(modem, msg);
-
- cw->pending = dbus_message_ref(msg);
-
- cw->ops->query(modem, BEARER_CLASS_DEFAULT, cw_query_callback, modem);
-
- return NULL;
-}
-
-static void set_query_callback(const struct ofono_error *error, int status,
- void *data)
-{
- struct ofono_modem *modem = data;
- struct call_waiting_data *cw = modem->call_waiting;
-
- if (error->type != OFONO_ERROR_TYPE_NO_ERROR) {
- ofono_error("CW set succeeded, but query failed!");
- cw->flags &= ~CALL_WAITING_FLAG_CACHED;
-
- dbus_gsm_pending_reply(&cw->pending,
- dbus_gsm_failed(cw->pending));
- return;
- }
-
- dbus_gsm_pending_reply(&cw->pending,
- dbus_message_new_method_return(cw->pending));
-
- update_conditions(modem, status, BEARER_CLASS_VOICE);
-}
-
-static void set_callback(const struct ofono_error *error, void *data)
-{
- struct ofono_modem *modem = data;
- struct call_waiting_data *cw = modem->call_waiting;
-
- if (error->type != OFONO_ERROR_TYPE_NO_ERROR) {
- ofono_debug("Error occurred during CW set");
-
- dbus_gsm_pending_reply(&cw->pending,
- dbus_gsm_failed(cw->pending));
-
- return;
- }
-
- cw->ops->query(modem, BEARER_CLASS_DEFAULT, set_query_callback, modem);
-}
-
-static DBusMessage *cw_set_property(DBusConnection *conn, DBusMessage *msg,
- void *data)
-{
- struct ofono_modem *modem = data;
- struct call_waiting_data *cw = modem->call_waiting;
- DBusMessageIter iter;
- DBusMessageIter var;
- const char *property;
- int i;
-
- if (cw->pending)
- return dbus_gsm_busy(msg);
-
- if (!cw->ops->set)
- return dbus_gsm_not_implemented(msg);
-
- if (!dbus_message_iter_init(msg, &iter))
- return dbus_gsm_invalid_args(msg);
-
- if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
- return dbus_gsm_invalid_args(msg);
-
- dbus_message_iter_get_basic(&iter, &property);
- dbus_message_iter_next(&iter);
-
- if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT)
- return dbus_gsm_invalid_args(msg);
-
- dbus_message_iter_recurse(&iter, &var);
-
- for (i = 1; i < BEARER_CLASS_SMS; i = i << 1)
- if (!strcmp(property, bearer_class_to_string(i)))
- break;
-
- if (i < BEARER_CLASS_SMS) {
- const char *value;
- int status;
-
- if (dbus_message_iter_get_arg_type(&var) != DBUS_TYPE_STRING)
- return dbus_gsm_invalid_format(msg);
-
- dbus_message_iter_get_basic(&var, &value);
-
- if (!strcmp(value, "enabled"))
- status = 1;
- else if (!strcmp(value, "disabled"))
- status = 0;
- else
- return dbus_gsm_invalid_format(msg);
-
- cw->pending = dbus_message_ref(msg);
-
- cw->ops->set(modem, status, i, set_callback, modem);
- }
-
- return dbus_gsm_invalid_args(msg);
-}
-
-static GDBusMethodTable cw_methods[] = {
- { "GetProperties", "", "a{sv}", cw_get_properties,
- G_DBUS_METHOD_FLAG_ASYNC },
- { "SetProperty", "sv", "", cw_set_property,
- G_DBUS_METHOD_FLAG_ASYNC },
- { }
-};
-
-static GDBusSignalTable cw_signals[] = {
- { "PropertyChanged", "sv" },
- { }
-};
-
-int ofono_call_waiting_register(struct ofono_modem *modem,
- struct ofono_call_waiting_ops *ops)
-{
- DBusConnection *conn = dbus_gsm_connection();
-
- if (modem == NULL)
- return -1;
-
- if (ops == NULL)
- return -1;
-
- modem->call_waiting = call_waiting_create();
-
- if (!modem->call_waiting)
- return -1;
-
- modem->call_waiting->ops = ops;
-
- if (!g_dbus_register_interface(conn, modem->path,
- CALL_WAITING_INTERFACE,
- cw_methods, cw_signals, NULL,
- modem, call_waiting_destroy)) {
- ofono_error("Could not register CallWaiting %s", modem->path);
- call_waiting_destroy(modem);
-
- return -1;
- }
-
- ofono_debug("Registered call waiting interface");
-
- cw_register_ss_controls(modem);
-
- modem_add_interface(modem, CALL_WAITING_INTERFACE);
- return 0;
-}
-
-void ofono_call_waiting_unregister(struct ofono_modem *modem)
-{
- struct call_waiting_data *cw = modem->call_waiting;
- DBusConnection *conn = dbus_gsm_connection();
-
- if (!cw)
- return;
-
- modem_remove_interface(modem, CALL_WAITING_INTERFACE);
- g_dbus_unregister_interface(conn, modem->path,
- CALL_WAITING_INTERFACE);
-
- modem->call_waiting = NULL;
-}