Skip to content

Commit

Permalink
[ril] Enable cell info updates only when requested. JB#50608
Browse files Browse the repository at this point in the history
  • Loading branch information
d-grigorev committed May 28, 2021
1 parent 6ef1174 commit 297926e
Show file tree
Hide file tree
Showing 6 changed files with 443 additions and 14 deletions.
4 changes: 3 additions & 1 deletion ofono/Makefile.am
Expand Up @@ -126,7 +126,8 @@ builtin_sources += plugins/sailfish_manager/sailfish_cell_info.c \
plugins/sailfish_manager/sailfish_manager.c \
plugins/sailfish_manager/sailfish_manager_dbus.c \
plugins/sailfish_manager/sailfish_sim_info.c \
plugins/sailfish_manager/sailfish_sim_info_dbus.c
plugins/sailfish_manager/sailfish_sim_info_dbus.c \
plugins/sailfish_manager/sailfish_dbus_clients.c
endif


Expand Down Expand Up @@ -979,6 +980,7 @@ unit_tests += unit/test-sailfish_cell_info
unit_test_sailfish_cell_info_dbus_SOURCES = unit/test-dbus.c \
unit/test-sailfish_cell_info_dbus.c \
unit/fake_sailfish_cell_info.c \
unit/fake_sailfish_dbus_clients.c \
plugins/sailfish_manager/sailfish_cell_info.c \
plugins/sailfish_manager/sailfish_cell_info_dbus.c \
gdbus/object.c \
Expand Down
4 changes: 2 additions & 2 deletions ofono/drivers/ril/ril_cell_info.c
Expand Up @@ -542,8 +542,8 @@ struct sailfish_cell_info *ril_cell_info_new(GRilIoChannel *io,
self->sim_card_ready = ril_sim_card_ready(sim_card);
ril_cell_info_refresh(self);

/* Enable updates by default */
self->enabled = TRUE;
/* Disable updates by default */
self->enabled = FALSE;
if (self->sim_card_ready) {
ril_cell_info_set_rate(self);
}
Expand Down
44 changes: 33 additions & 11 deletions ofono/plugins/sailfish_manager/sailfish_cell_info_dbus.c
Expand Up @@ -15,7 +15,9 @@

#include "sailfish_cell_info_dbus.h"
#include "sailfish_cell_info.h"
#include "sailfish_dbus_clients.h"

#include <ofono.h>
#include <ofono/modem.h>
#include <ofono/dbus.h>
#include <ofono/log.h>
Expand All @@ -35,6 +37,7 @@ struct sailfish_cell_info_dbus {
gulong handler_id;
guint next_cell_id;
GSList *entries;
struct sailfish_dbus_clients *clients;
};

#define CELL_INFO_DBUS_INTERFACE "org.nemomobile.ofono.CellInfo"
Expand Down Expand Up @@ -496,19 +499,27 @@ static DBusMessage *sailfish_cell_info_dbus_get_cells(DBusConnection *conn,
DBusMessage *msg, void *data)
{
struct sailfish_cell_info_dbus *dbus = data;
DBusMessage *reply = dbus_message_new_method_return(msg);
DBusMessageIter it, array;
GSList *l;
struct sailfish_dbus_client *client;

dbus_message_iter_init_append(reply, &it);
dbus_message_iter_open_container(&it, DBUS_TYPE_ARRAY, "o", &array);
for (l = dbus->entries; l; l = l->next) {
const struct sailfish_cell_entry *entry = l->data;
dbus_message_iter_append_basic(&array, DBUS_TYPE_OBJECT_PATH,
&entry->path);
client = sailfish_dbus_clients_new_client(dbus->clients, msg);
if (client) {
DBusMessage *reply = dbus_message_new_method_return(msg);
DBusMessageIter it, array;
GSList *l;

sailfish_cell_info_set_enabled(dbus->info, TRUE);
dbus_message_iter_init_append(reply, &it);
dbus_message_iter_open_container(&it, DBUS_TYPE_ARRAY,
"o", &array);
for (l = dbus->entries; l; l = l->next) {
const struct sailfish_cell_entry *entry = l->data;
dbus_message_iter_append_basic(&array,
DBUS_TYPE_OBJECT_PATH, &entry->path);
}
dbus_message_iter_close_container(&it, &array);
return reply;
}
dbus_message_iter_close_container(&it, &array);
return reply;
return __ofono_error_access_denied(msg);
}

static const GDBusMethodTable sailfish_cell_info_dbus_methods[] = {
Expand All @@ -526,6 +537,12 @@ static const GDBusSignalTable sailfish_cell_info_dbus_signals[] = {
{ }
};

static void sailfish_cell_info_dbus_disable_cb(void *user_data)
{
struct sailfish_cell_info_dbus *dbus = user_data;
sailfish_cell_info_set_enabled(dbus->info, FALSE);
}

struct sailfish_cell_info_dbus *sailfish_cell_info_dbus_new
(struct ofono_modem *modem, struct sailfish_cell_info *info)
{
Expand All @@ -550,6 +567,10 @@ struct sailfish_cell_info_dbus *sailfish_cell_info_dbus_new
ofono_modem_add_interface(modem,
CELL_INFO_DBUS_INTERFACE);
sailfish_cell_info_dbus_update_entries(dbus, FALSE);
dbus->clients =
sailfish_dbus_clients_new(dbus->conn,
sailfish_cell_info_dbus_disable_cb,
dbus);
return dbus;
} else {
ofono_error("CellInfo D-Bus register failed");
Expand All @@ -565,6 +586,7 @@ void sailfish_cell_info_dbus_free(struct sailfish_cell_info_dbus *dbus)
GSList *l;

DBG("%s", dbus->path);
sailfish_dbus_clients_free(dbus->clients);
g_dbus_unregister_interface(dbus->conn, dbus->path,
CELL_INFO_DBUS_INTERFACE);

Expand Down
241 changes: 241 additions & 0 deletions ofono/plugins/sailfish_manager/sailfish_dbus_clients.c
@@ -0,0 +1,241 @@
/*
* oFono - Open Source Telephony
*
* Copyright (C) 2017-2018 Jolla Ltd.
* Copyright (C) 2020 Open Mobile Platform LLC.
*
* 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.
*/

#include "sailfish_dbus_clients.h"

#include <ofono/gdbus.h>
#include <ofono/log.h>

#include "dbusaccess_peer.h"

struct sailfish_dbus_client {
struct sailfish_dbus_clients* clients;
DAPeer* peer;
guint watch_id;
};

struct sailfish_dbus_clients {
DBusConnection* conn;
GHashTable* table;
void (*disconnect_cb)(void *disconnect_cb_data);
void *disconnect_cb_data;
};

static void sailfish_dbus_client_free(struct sailfish_dbus_client* client)
{
/* Callers make sure that client parameter is not NULL */
if (client->watch_id) {
g_dbus_remove_watch(client->clients->conn, client->watch_id);
}
da_peer_unref(client->peer);
g_slice_free(struct sailfish_dbus_client, client);
}

static void sailfish_dbus_client_free1(void* data)
{
sailfish_dbus_client_free(data);
}

void sailfish_dbus_clients_remove_client(struct sailfish_dbus_client *client)
{
if (client && client->clients) {
struct sailfish_dbus_clients *clients = client->clients;

g_hash_table_remove(clients->table, client->peer->name);
if (clients->disconnect_cb &&
!sailfish_dbus_clients_count(clients)) {
clients->disconnect_cb(clients->disconnect_cb_data);
}
}
}

static void sailfish_dbus_client_disconnected(DBusConnection* connection,
void* user_data)
{
struct sailfish_dbus_client* client = user_data;

/* This deallocates struct sailfish_dbus_client: */
DBG("%s is gone", client->peer->name);
sailfish_dbus_clients_remove_client(client);
}

struct sailfish_dbus_clients* sailfish_dbus_clients_new(DBusConnection* conn,
void (*disconnect_cb)(void *disconnect_cb_data),
void *disconnect_cb_data)
{
struct sailfish_dbus_clients* self =
g_slice_new0(struct sailfish_dbus_clients);

self->conn = dbus_connection_ref(conn);
self->table = g_hash_table_new_full(g_str_hash, g_str_equal, NULL,
sailfish_dbus_client_free1);
self->disconnect_cb = disconnect_cb;
self->disconnect_cb_data = disconnect_cb_data;
return self;
}

void sailfish_dbus_clients_free(struct sailfish_dbus_clients* self)
{
if (self) {
g_hash_table_destroy(self->table);
dbus_connection_unref(self->conn);
g_slice_free(struct sailfish_dbus_clients, self);
}
}

guint sailfish_dbus_clients_count(struct sailfish_dbus_clients* self)
{
return self ? g_hash_table_size(self->table) : 0;
}

static void sailfish_dbus_clients_register(struct sailfish_dbus_clients* self,
DAPeer* peer)
{
if (self && peer && !g_hash_table_contains(self->table, peer->name)) {
struct sailfish_dbus_client* client =
g_slice_new0(struct sailfish_dbus_client);

client->clients = self;
client->peer = da_peer_ref(peer);
client->watch_id = g_dbus_add_disconnect_watch(
self->conn, peer->name,
sailfish_dbus_client_disconnected,
client, NULL);
if (client->watch_id) {
DBG("%s is registered", peer->name);
g_hash_table_replace(self->table,
(gpointer)peer->name, client);
} else {
DBG("failed to register %s", peer->name);
sailfish_dbus_client_free(client);
}
}
}

struct sailfish_dbus_client* sailfish_dbus_clients_lookup_client(
struct sailfish_dbus_clients* self,
DBusMessage *msg)
{
if (self && msg) {
DAPeer *peer = da_peer_get(DA_BUS_SYSTEM,
dbus_message_get_sender(msg));

if (peer)
return g_hash_table_lookup(self->table, peer->name);
}

return NULL;
}

struct sailfish_dbus_client* sailfish_dbus_clients_new_client(
struct sailfish_dbus_clients* self,
DBusMessage *msg)
{
if (self && msg) {
DAPeer *peer = da_peer_get(DA_BUS_SYSTEM,
dbus_message_get_sender(msg));

if (peer) {
sailfish_dbus_clients_register(self, peer);
return g_hash_table_lookup(self->table, peer->name);
}
}

return NULL;
}

void sailfish_dbus_clients_send(struct sailfish_dbus_clients* self,
DBusMessage* msg)
{
if (self && msg && g_hash_table_size(self->table)) {
GHashTableIter it;
gpointer key;
const char* last_name = NULL;

g_hash_table_iter_init(&it, self->table);
g_hash_table_iter_next(&it, &key, NULL);
last_name = key;

while (g_hash_table_iter_next(&it, &key, NULL)) {
DBusMessage* copy = dbus_message_copy(msg);

dbus_message_set_destination(copy, (const char*)key);
g_dbus_send_message(self->conn, copy);
}

/* The last one */
dbus_message_set_destination(msg, last_name);
g_dbus_send_message(self->conn, msg);
}
}

void sailfish_dbus_clients_send_to(struct sailfish_dbus_client *client,
DBusMessage* msg)
{
if (client && msg) {
dbus_message_set_destination(msg, client->peer->name);
g_dbus_send_message(client->clients->conn, msg);
}
}

static void append_variant(DBusMessageIter *iter, int type, const void *value)
{
char sig[2];
DBusMessageIter valueiter;

sig[0] = type;
sig[1] = 0;

dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT,
sig, &valueiter);
dbus_message_iter_append_basic(&valueiter, type, value);
dbus_message_iter_close_container(iter, &valueiter);
}

int sailfish_dbus_clients_signal_property_changed(
struct sailfish_dbus_clients* self,
const char *path,
const char *interface,
const char *name,
int type, const void *value)
{
if (self) {
DBusMessage *signal;
DBusMessageIter iter;

signal = dbus_message_new_signal(path, interface,
"PropertyChanged");
if (signal == NULL) {
ofono_error("Unable to allocate new signal for %s",
interface);
return -1;
}

dbus_message_iter_init_append(signal, &iter);
dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &name);
append_variant(&iter, type, value);
sailfish_dbus_clients_send(self, signal);
}
return 0;
}

/*
* Local Variables:
* mode: C
* c-basic-offset: 8
* indent-tabs-mode: t
* End:
*/

0 comments on commit 297926e

Please sign in to comment.