From: =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis <frederic.danis@linux.intel.com>
To: ofono@ofono.org
Subject: [PATCH 4/4] emulator: add +COPS support
Date: Thu, 17 Mar 2011 17:50:56 +0100 [thread overview]
Message-ID: <1300380656-8757-5-git-send-email-frederic.danis@linux.intel.com> (raw)
In-Reply-To: <1300380656-8757-1-git-send-email-frederic.danis@linux.intel.com>
[-- Attachment #1: Type: text/plain, Size: 10954 bytes --]
This needs to be in emulator as HFP plugin should answer AT+COPS requests
even when oFono is not registered on network.
---
src/emulator.c | 72 ++++++++++++++++++++++++++++++++++++++++++++
src/network.c | 90 +++++++++++++++++++++++++++++++++++++++++++++++++++----
2 files changed, 155 insertions(+), 7 deletions(-)
diff --git a/src/emulator.c b/src/emulator.c
index 864e50b..eb4f49e 100644
--- a/src/emulator.c
+++ b/src/emulator.c
@@ -49,6 +49,8 @@ struct ofono_emulator {
int events_mode;
gboolean events_ind;
GSList *indicators;
+ char op_name[17];
+ int net_mode;
};
struct indicator {
@@ -387,6 +389,59 @@ fail:
}
}
+static void cops_cb(GAtServer *server, GAtServerRequestType type,
+ GAtResult *result, gpointer user_data)
+{
+ struct ofono_emulator *em = user_data;
+ char buf[32];
+
+ if (em->type == OFONO_EMULATOR_TYPE_HFP && em->slc == FALSE) {
+ g_at_server_send_final(em->server, G_AT_SERVER_RESULT_ERROR);
+ return;
+ }
+
+ switch (type) {
+ case G_AT_SERVER_REQUEST_TYPE_QUERY:
+ sprintf(buf, "+COPS: %d,0,\"%s\"", em->net_mode, em->op_name);
+ g_at_server_send_info(em->server, buf, TRUE);
+ g_at_server_send_final(server, G_AT_SERVER_RESULT_OK);
+ break;
+
+ case G_AT_SERVER_REQUEST_TYPE_SET:
+ {
+ GAtResultIter iter;
+ int val;
+
+ g_at_result_iter_init(&iter, result);
+ g_at_result_iter_next(&iter, "");
+
+ if (!g_at_result_iter_next_number(&iter, &val))
+ goto fail;
+
+ if (val != 3)
+ goto fail;
+
+ if (!g_at_result_iter_next_number(&iter, &val))
+ goto fail;
+
+ if (val != 0)
+ goto fail;
+
+ /* check there is no more parameter */
+ if (g_at_result_iter_skip_next(&iter))
+ goto fail;
+
+ g_at_server_send_final(server, G_AT_SERVER_RESULT_OK);
+ break;
+ }
+
+ default:
+fail:
+ g_at_server_send_final(server, G_AT_SERVER_RESULT_ERROR);
+ break;
+ }
+}
+
static void emulator_add_indicator(struct ofono_emulator *em, const char* name,
int min, int max, int dflt)
{
@@ -465,6 +520,7 @@ void ofono_emulator_register(struct ofono_emulator *em, int fd)
g_at_server_register(em->server, "+BRSF", brsf_cb, em, NULL);
g_at_server_register(em->server, "+CIND", cind_cb, em, NULL);
g_at_server_register(em->server, "+CMER", cmer_cb, em, NULL);
+ g_at_server_register(em->server, "+COPS", cops_cb, em, NULL);
}
__ofono_atom_register(em->atom, emulator_unregister);
@@ -508,6 +564,7 @@ struct ofono_emulator *ofono_emulator_create(struct ofono_modem *modem,
/* TODO: Check real local features */
em->l_features = 32;
em->events_mode = 3; /* default mode is forwarding events */
+ em->op_name[0] = '\0';
em->atom = __ofono_modem_add_atom_offline(modem, atom_t,
emulator_remove, em);
@@ -703,3 +760,18 @@ void ofono_emulator_set_indicator(struct ofono_emulator *em,
return;
}
}
+
+void ofono_emulator_set_network_name(struct ofono_emulator *em,
+ const char *name)
+{
+ if (name == NULL)
+ return;
+
+ strncpy(em->op_name, name, 16);
+ em->op_name[16] = '\0';
+}
+
+void ofono_emulator_set_network_mode(struct ofono_emulator *em, int mode)
+{
+ em->net_mode = mode;
+}
diff --git a/src/network.c b/src/network.c
index 2d0a9f8..d529431 100644
--- a/src/network.c
+++ b/src/network.c
@@ -145,11 +145,19 @@ static char **network_operator_technologies(struct network_operator_data *opd)
return techs;
}
+static void notify_emulator_mode(struct ofono_atom *atom, void *data)
+{
+ struct ofono_emulator *em = __ofono_atom_get_data(atom);
+
+ ofono_emulator_set_network_mode(em, GPOINTER_TO_INT(data));
+}
+
static void set_registration_mode(struct ofono_netreg *netreg, int mode)
{
DBusConnection *conn;
const char *strmode;
const char *path;
+ struct ofono_modem *modem;
if (netreg->mode == mode)
return;
@@ -170,6 +178,10 @@ static void set_registration_mode(struct ofono_netreg *netreg, int mode)
ofono_dbus_signal_property_changed(conn, path,
OFONO_NETWORK_REGISTRATION_INTERFACE,
"Mode", DBUS_TYPE_STRING, &strmode);
+
+ modem = __ofono_atom_get_modem(netreg->atom);
+ __ofono_modem_foreach_atom(modem, OFONO_ATOM_TYPE_EMULATOR_HFP,
+ notify_emulator_mode, GINT_TO_POINTER(mode));
}
static void registration_status_callback(const struct ofono_error *error,
@@ -400,13 +412,20 @@ static char *get_operator_display_name(struct ofono_netreg *netreg)
return name;
}
+static void notify_emulator_operator_name(struct ofono_atom *atom, void *data)
+{
+ struct ofono_emulator *em = __ofono_atom_get_data(atom);
+
+ ofono_emulator_set_network_name(em, data);
+}
+
static void set_network_operator_name(struct network_operator_data *opd,
const char *name)
{
DBusConnection *conn = ofono_dbus_get_connection();
struct ofono_netreg *netreg = opd->netreg;
const char *path;
- const char *operator;
+ char *operator;
if (name[0] == '\0')
return;
@@ -426,6 +445,7 @@ static void set_network_operator_name(struct network_operator_data *opd,
if (opd == netreg->current_operator) {
const char *path = __ofono_atom_get_path(netreg->atom);
+ struct ofono_modem *modem;
operator = get_operator_display_name(netreg);
@@ -433,6 +453,11 @@ static void set_network_operator_name(struct network_operator_data *opd,
OFONO_NETWORK_REGISTRATION_INTERFACE,
"Name", DBUS_TYPE_STRING,
&operator);
+
+ modem = __ofono_atom_get_modem(netreg->atom);
+ __ofono_modem_foreach_atom(modem, OFONO_ATOM_TYPE_EMULATOR_HFP,
+ notify_emulator_operator_name,
+ operator);
}
/* Don't emit when only operator name is reported */
@@ -481,13 +506,19 @@ static void set_network_operator_eons_info(struct network_operator_data *opd,
if (opd == netreg->current_operator) {
const char *npath = __ofono_atom_get_path(netreg->atom);
- const char *operator =
- get_operator_display_name(netreg);
+ char *operator = get_operator_display_name(netreg);
+ struct ofono_modem *modem;
ofono_dbus_signal_property_changed(conn, npath,
OFONO_NETWORK_REGISTRATION_INTERFACE,
"Name", DBUS_TYPE_STRING,
&operator);
+
+ modem = __ofono_atom_get_modem(netreg->atom);
+ __ofono_modem_foreach_atom(modem,
+ OFONO_ATOM_TYPE_EMULATOR_HFP,
+ notify_emulator_operator_name,
+ operator);
}
}
@@ -1178,7 +1209,8 @@ static void current_operator_callback(const struct ofono_error *error,
struct ofono_netreg *netreg = data;
const char *path = __ofono_atom_get_path(netreg->atom);
GSList *op = NULL;
- const char *operator;
+ char *operator;
+ struct ofono_modem *modem;
DBG("%p, %p", netreg, netreg->current_operator);
@@ -1254,6 +1286,11 @@ emit:
"Name", DBUS_TYPE_STRING,
&operator);
+ modem = __ofono_atom_get_modem(netreg->atom);
+ __ofono_modem_foreach_atom(modem, OFONO_ATOM_TYPE_EMULATOR_HFP,
+ notify_emulator_operator_name,
+ operator);
+
if (netreg->current_operator) {
if (netreg->current_operator->mcc[0] != '\0') {
const char *mcc = netreg->current_operator->mcc;
@@ -1540,7 +1577,8 @@ static void sim_spdi_read_cb(int ok, int length, int record,
if (netreg->status == NETWORK_REGISTRATION_STATUS_ROAMING) {
DBusConnection *conn = ofono_dbus_get_connection();
const char *path = __ofono_atom_get_path(netreg->atom);
- const char *operator;
+ char *operator;
+ struct ofono_modem *modem;
if (!sim_spdi_lookup(netreg->spdi,
current->mcc, current->mnc))
@@ -1552,6 +1590,11 @@ static void sim_spdi_read_cb(int ok, int length, int record,
OFONO_NETWORK_REGISTRATION_INTERFACE,
"Name", DBUS_TYPE_STRING,
&operator);
+
+ modem = __ofono_atom_get_modem(netreg->atom);
+ __ofono_modem_foreach_atom(modem, OFONO_ATOM_TYPE_EMULATOR_HFP,
+ notify_emulator_operator_name,
+ operator);
}
}
@@ -1609,7 +1652,8 @@ static void sim_spn_read_cb(int ok, int length, int record,
if (netreg->current_operator) {
DBusConnection *conn = ofono_dbus_get_connection();
const char *path = __ofono_atom_get_path(netreg->atom);
- const char *operator;
+ char *operator;
+ struct ofono_modem *modem;
operator = get_operator_display_name(netreg);
@@ -1617,6 +1661,11 @@ static void sim_spn_read_cb(int ok, int length, int record,
OFONO_NETWORK_REGISTRATION_INTERFACE,
"Name", DBUS_TYPE_STRING,
&operator);
+
+ modem = __ofono_atom_get_modem(netreg->atom);
+ __ofono_modem_foreach_atom(modem, OFONO_ATOM_TYPE_EMULATOR_HFP,
+ notify_emulator_operator_name,
+ operator);
}
}
@@ -1704,9 +1753,16 @@ static void netreg_unregister(struct ofono_atom *atom)
__ofono_modem_foreach_atom(modem, OFONO_ATOM_TYPE_EMULATOR_HFP,
notify_emulator_status,
GINT_TO_POINTER(0));
+
__ofono_modem_foreach_atom(modem, OFONO_ATOM_TYPE_EMULATOR_HFP,
notify_emulator_strength, GINT_TO_POINTER(0));
+ __ofono_modem_foreach_atom(modem, OFONO_ATOM_TYPE_EMULATOR_HFP,
+ notify_emulator_mode, GINT_TO_POINTER(0));
+
+ __ofono_modem_foreach_atom(modem, OFONO_ATOM_TYPE_EMULATOR_HFP,
+ notify_emulator_operator_name, "");
+
__ofono_modem_remove_atom_watch(modem, netreg->hfp_watch);
__ofono_watchlist_free(netreg->status_watches);
@@ -1875,7 +1931,8 @@ static void sim_spn_spdi_changed(int id, void *userdata)
if (netreg->current_operator) {
DBusConnection *conn = ofono_dbus_get_connection();
const char *path = __ofono_atom_get_path(netreg->atom);
- const char *operator;
+ char *operator;
+ struct ofono_modem *modem;
operator = get_operator_display_name(netreg);
@@ -1883,6 +1940,11 @@ static void sim_spn_spdi_changed(int id, void *userdata)
OFONO_NETWORK_REGISTRATION_INTERFACE,
"Name", DBUS_TYPE_STRING,
&operator);
+
+ modem = __ofono_atom_get_modem(netreg->atom);
+ __ofono_modem_foreach_atom(modem, OFONO_ATOM_TYPE_EMULATOR_HFP,
+ notify_emulator_operator_name,
+ operator);
}
ofono_sim_read(netreg->sim_context, SIM_EFSPN_FILEID,
@@ -1901,9 +1963,23 @@ static void emulator_hfp_watch(struct ofono_atom *atom,
__ofono_modem_foreach_atom(modem, OFONO_ATOM_TYPE_EMULATOR_HFP,
notify_emulator_status,
GINT_TO_POINTER(netreg->status));
+
__ofono_modem_foreach_atom(modem, OFONO_ATOM_TYPE_EMULATOR_HFP,
notify_emulator_strength,
GINT_TO_POINTER(netreg->signal_strength));
+
+ __ofono_modem_foreach_atom(modem, OFONO_ATOM_TYPE_EMULATOR_HFP,
+ notify_emulator_mode,
+ GINT_TO_POINTER(netreg->mode));
+
+ if (netreg->current_operator) {
+ char *operator = get_operator_display_name(netreg);
+
+ __ofono_modem_foreach_atom(modem,
+ OFONO_ATOM_TYPE_EMULATOR_HFP,
+ notify_emulator_operator_name,
+ operator);
+ }
}
}
--
1.7.1
next prev parent reply other threads:[~2011-03-17 16:50 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-03-17 16:50 [PATCH 0/4] HFP: add call, callsetup indicators and +COPS support =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
2011-03-17 16:50 ` [PATCH 1/4] emulator: add defines for call and callsetup indicators =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
2011-03-17 16:50 ` [PATCH 2/4] emulator: add " =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
2011-03-17 21:14 ` Denis Kenzior
2011-03-17 16:50 ` [PATCH 3/4] emulator: add API to set network mode and name =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
2011-03-17 21:15 ` Denis Kenzior
2011-03-17 16:50 ` =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis [this message]
2011-03-17 21:18 ` [PATCH 4/4] emulator: add +COPS support Denis Kenzior
2011-03-18 9:13 ` Frederic Danis
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1300380656-8757-5-git-send-email-frederic.danis@linux.intel.com \
--to=frederic.danis@linux.intel.com \
--cc=ofono@ofono.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.