mirror of git://git.sysmocom.de/ofono
netreg: Update to the new Scan/GetOperators API
This commit is contained in:
parent
f6a4fcde1e
commit
b67a324ff4
565
src/network.c
565
src/network.c
|
@ -85,10 +85,6 @@ struct ofono_netreg {
|
|||
struct ofono_atom *atom;
|
||||
};
|
||||
|
||||
static void operator_list_callback(const struct ofono_error *error, int total,
|
||||
const struct ofono_network_operator *list,
|
||||
void *data);
|
||||
|
||||
static void current_operator_callback(const struct ofono_error *error,
|
||||
const struct ofono_network_operator *current,
|
||||
void *data);
|
||||
|
@ -223,69 +219,6 @@ static void init_register(const struct ofono_error *error, void *data)
|
|||
registration_status_callback, netreg);
|
||||
}
|
||||
|
||||
/* Must use g_strfreev on network_operators */
|
||||
static void network_operator_populate_registered(struct ofono_netreg *netreg,
|
||||
char ***network_operators)
|
||||
{
|
||||
DBusConnection *conn = ofono_dbus_get_connection();
|
||||
char **children;
|
||||
int i;
|
||||
int prefix_len;
|
||||
int num_children;
|
||||
GSList *l;
|
||||
char path[256];
|
||||
char mnc[OFONO_MAX_MNC_LENGTH + 1];
|
||||
char mcc[OFONO_MAX_MCC_LENGTH + 1];
|
||||
int op_path_len;
|
||||
|
||||
prefix_len = snprintf(path, sizeof(path), "%s/operator",
|
||||
__ofono_atom_get_path(netreg->atom));
|
||||
|
||||
if (!dbus_connection_list_registered(conn, path, &children)) {
|
||||
DBG("Unable to obtain registered NetworkOperator(s)");
|
||||
*network_operators = g_try_new0(char *, 1);
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; children[i]; i++)
|
||||
;
|
||||
|
||||
num_children = i;
|
||||
|
||||
*network_operators = g_try_new0(char *, num_children + 1);
|
||||
|
||||
/* Enough to store '/' + MCC + MNC + null */
|
||||
op_path_len = prefix_len;
|
||||
op_path_len += OFONO_MAX_MCC_LENGTH + OFONO_MAX_MNC_LENGTH + 2;
|
||||
|
||||
/* Quoting 27.007: "The list of operators shall be in order: home
|
||||
* network, networks referenced in SIM or active application in the
|
||||
* UICC (GSM or USIM) in the following order: HPLMN selector, User
|
||||
* controlled PLMN selector, Operator controlled PLMN selector and
|
||||
* PLMN selector (in the SIM or GSM application), and other networks."
|
||||
* Thus we must make sure we return the list in the same order,
|
||||
* if possible. Luckily the operator_list is stored in order already
|
||||
*/
|
||||
i = 0;
|
||||
for (l = netreg->operator_list; l; l = l->next) {
|
||||
struct network_operator_data *opd = l->data;
|
||||
int j;
|
||||
|
||||
for (j = 0; children[j]; j++) {
|
||||
sscanf(children[j], "%3[0-9]%[0-9]", mcc, mnc);
|
||||
if (!strcmp(opd->mcc, mcc) && !strcmp(opd->mnc, mnc)) {
|
||||
(*network_operators)[i] =
|
||||
g_try_new(char, op_path_len);
|
||||
snprintf((*network_operators)[i], op_path_len,
|
||||
"%s/%s", path, children[j]);
|
||||
++i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dbus_free_string_array(children);
|
||||
}
|
||||
|
||||
static struct network_operator_data *
|
||||
network_operator_create(const struct ofono_network_operator *op)
|
||||
{
|
||||
|
@ -340,7 +273,7 @@ static gint network_operator_data_compare(gconstpointer a, gconstpointer b)
|
|||
return comp1 != 0 ? comp1 : comp2;
|
||||
}
|
||||
|
||||
static inline const char *network_operator_build_path(struct ofono_netreg *netreg,
|
||||
static const char *network_operator_build_path(struct ofono_netreg *netreg,
|
||||
const char *mcc,
|
||||
const char *mnc)
|
||||
{
|
||||
|
@ -353,23 +286,6 @@ static inline const char *network_operator_build_path(struct ofono_netreg *netre
|
|||
return path;
|
||||
}
|
||||
|
||||
static void network_operator_emit_available_operators(struct ofono_netreg *netreg)
|
||||
{
|
||||
DBusConnection *conn = ofono_dbus_get_connection();
|
||||
const char *path = __ofono_atom_get_path(netreg->atom);
|
||||
char **network_operators;
|
||||
|
||||
network_operator_populate_registered(netreg, &network_operators);
|
||||
|
||||
ofono_dbus_signal_array_property_changed(conn, path,
|
||||
OFONO_NETWORK_REGISTRATION_INTERFACE,
|
||||
"Operators",
|
||||
DBUS_TYPE_OBJECT_PATH,
|
||||
&network_operators);
|
||||
|
||||
g_strfreev(network_operators);
|
||||
}
|
||||
|
||||
static void set_network_operator_status(struct network_operator_data *opd,
|
||||
int status)
|
||||
{
|
||||
|
@ -585,6 +501,55 @@ static void set_network_operator_eons_info(struct network_operator_data *opd,
|
|||
DBUS_TYPE_STRING, &newinfo);
|
||||
}
|
||||
|
||||
static void append_operator_properties(struct network_operator_data *opd,
|
||||
DBusMessageIter *dict)
|
||||
{
|
||||
const char *name = opd->name;
|
||||
const char *status = network_operator_status_to_string(opd->status);
|
||||
char mccmnc[OFONO_MAX_MCC_LENGTH + OFONO_MAX_MNC_LENGTH + 1];
|
||||
|
||||
if (opd->eons_info && opd->eons_info->longname)
|
||||
name = opd->eons_info->longname;
|
||||
|
||||
if (name[0] == '\0') {
|
||||
snprintf(mccmnc, sizeof(mccmnc), "%s%s", opd->mcc, opd->mnc);
|
||||
name = mccmnc;
|
||||
}
|
||||
|
||||
ofono_dbus_dict_append(dict, "Name", DBUS_TYPE_STRING, &name);
|
||||
|
||||
ofono_dbus_dict_append(dict, "Status", DBUS_TYPE_STRING, &status);
|
||||
|
||||
if (*opd->mcc != '\0') {
|
||||
const char *mcc = opd->mcc;
|
||||
ofono_dbus_dict_append(dict, "MobileCountryCode",
|
||||
DBUS_TYPE_STRING, &mcc);
|
||||
}
|
||||
|
||||
if (*opd->mnc != '\0') {
|
||||
const char *mnc = opd->mnc;
|
||||
ofono_dbus_dict_append(dict, "MobileNetworkCode",
|
||||
DBUS_TYPE_STRING, &mnc);
|
||||
}
|
||||
|
||||
if (opd->techs != 0) {
|
||||
char **technologies = network_operator_technologies(opd);
|
||||
|
||||
ofono_dbus_dict_append_array(dict, "Technologies",
|
||||
DBUS_TYPE_STRING,
|
||||
&technologies);
|
||||
|
||||
g_strfreev(technologies);
|
||||
}
|
||||
|
||||
if (opd->eons_info && opd->eons_info->info) {
|
||||
const char *additional = opd->eons_info->info;
|
||||
|
||||
ofono_dbus_dict_append(dict, "AdditionalInformation",
|
||||
DBUS_TYPE_STRING, &additional);
|
||||
}
|
||||
}
|
||||
|
||||
static DBusMessage *network_operator_get_properties(DBusConnection *conn,
|
||||
DBusMessage *msg,
|
||||
void *data)
|
||||
|
@ -593,15 +558,6 @@ static DBusMessage *network_operator_get_properties(DBusConnection *conn,
|
|||
DBusMessage *reply;
|
||||
DBusMessageIter iter;
|
||||
DBusMessageIter dict;
|
||||
char mccmnc[OFONO_MAX_MCC_LENGTH + OFONO_MAX_MNC_LENGTH + 1];
|
||||
|
||||
const char *name = opd->name;
|
||||
const char *status =
|
||||
network_operator_status_to_string(opd->status);
|
||||
|
||||
if (opd->eons_info && opd->eons_info->longname)
|
||||
name = opd->eons_info->longname;
|
||||
|
||||
reply = dbus_message_new_method_return(msg);
|
||||
if (!reply)
|
||||
return NULL;
|
||||
|
@ -612,43 +568,7 @@ static DBusMessage *network_operator_get_properties(DBusConnection *conn,
|
|||
OFONO_PROPERTIES_ARRAY_SIGNATURE,
|
||||
&dict);
|
||||
|
||||
if (name[0] == '\0') {
|
||||
snprintf(mccmnc, sizeof(mccmnc), "%s%s", opd->mcc, opd->mnc);
|
||||
name = mccmnc;
|
||||
}
|
||||
|
||||
ofono_dbus_dict_append(&dict, "Name", DBUS_TYPE_STRING, &name);
|
||||
|
||||
ofono_dbus_dict_append(&dict, "Status", DBUS_TYPE_STRING, &status);
|
||||
|
||||
if (*opd->mcc != '\0') {
|
||||
const char *mcc = opd->mcc;
|
||||
ofono_dbus_dict_append(&dict, "MobileCountryCode",
|
||||
DBUS_TYPE_STRING, &mcc);
|
||||
}
|
||||
|
||||
if (*opd->mnc != '\0') {
|
||||
const char *mnc = opd->mnc;
|
||||
ofono_dbus_dict_append(&dict, "MobileNetworkCode",
|
||||
DBUS_TYPE_STRING, &mnc);
|
||||
}
|
||||
|
||||
if (opd->techs != 0) {
|
||||
char **technologies = network_operator_technologies(opd);
|
||||
|
||||
ofono_dbus_dict_append_array(&dict, "Technologies",
|
||||
DBUS_TYPE_STRING,
|
||||
&technologies);
|
||||
|
||||
g_strfreev(technologies);
|
||||
}
|
||||
|
||||
if (opd->eons_info && opd->eons_info->info) {
|
||||
const char *additional = opd->eons_info->info;
|
||||
|
||||
ofono_dbus_dict_append(&dict, "AdditionalInformation",
|
||||
DBUS_TYPE_STRING, &additional);
|
||||
}
|
||||
append_operator_properties(opd, &dict);
|
||||
|
||||
dbus_message_iter_close_container(&iter, &dict);
|
||||
|
||||
|
@ -729,6 +649,97 @@ static gboolean network_operator_dbus_unregister(struct ofono_netreg *netreg,
|
|||
OFONO_NETWORK_OPERATOR_INTERFACE);
|
||||
}
|
||||
|
||||
static GSList *compress_operator_list(const struct ofono_network_operator *list,
|
||||
int total)
|
||||
{
|
||||
GSList *oplist = 0;
|
||||
GSList *o;
|
||||
int i;
|
||||
struct network_operator_data *opd;
|
||||
|
||||
for (i = 0; i < total; i++) {
|
||||
o = NULL;
|
||||
|
||||
if (oplist)
|
||||
o = g_slist_find_custom(oplist, &list[i],
|
||||
network_operator_compare);
|
||||
|
||||
if (!o) {
|
||||
opd = network_operator_create(&list[i]);
|
||||
oplist = g_slist_prepend(oplist, opd);
|
||||
} else if (o && list[i].tech != -1) {
|
||||
opd = o->data;
|
||||
opd->techs |= 1 << list[i].tech;
|
||||
}
|
||||
}
|
||||
|
||||
if (oplist)
|
||||
oplist = g_slist_reverse(oplist);
|
||||
|
||||
return oplist;
|
||||
}
|
||||
|
||||
static gboolean update_operator_list(struct ofono_netreg *netreg, int total,
|
||||
const struct ofono_network_operator *list)
|
||||
{
|
||||
GSList *n = NULL;
|
||||
GSList *o;
|
||||
GSList *compressed;
|
||||
GSList *c;
|
||||
gboolean changed = FALSE;
|
||||
|
||||
compressed = compress_operator_list(list, total);
|
||||
|
||||
for (c = compressed; c; c = c->next) {
|
||||
struct network_operator_data *copd = c->data;
|
||||
|
||||
o = g_slist_find_custom(netreg->operator_list, copd,
|
||||
network_operator_data_compare);
|
||||
|
||||
if (o) { /* Update and move to a new list */
|
||||
set_network_operator_status(o->data, copd->status);
|
||||
set_network_operator_techs(o->data, copd->techs);
|
||||
set_network_operator_name(o->data, copd->name);
|
||||
|
||||
n = g_slist_prepend(n, o->data);
|
||||
netreg->operator_list =
|
||||
g_slist_remove(netreg->operator_list, o->data);
|
||||
} else {
|
||||
/* New operator */
|
||||
struct network_operator_data *opd;
|
||||
|
||||
opd = g_memdup(copd,
|
||||
sizeof(struct network_operator_data));
|
||||
|
||||
if (!network_operator_dbus_register(netreg, opd)) {
|
||||
g_free(opd);
|
||||
continue;
|
||||
}
|
||||
|
||||
n = g_slist_prepend(n, opd);
|
||||
changed = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
g_slist_foreach(compressed, (GFunc)g_free, NULL);
|
||||
g_slist_free(compressed);
|
||||
|
||||
if (n)
|
||||
n = g_slist_reverse(n);
|
||||
|
||||
if (netreg->operator_list)
|
||||
changed = TRUE;
|
||||
|
||||
for (o = netreg->operator_list; o; o = o->next)
|
||||
network_operator_dbus_unregister(netreg, o->data);
|
||||
|
||||
g_slist_free(netreg->operator_list);
|
||||
|
||||
netreg->operator_list = n;
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
static DBusMessage *network_get_properties(DBusConnection *conn,
|
||||
DBusMessage *msg, void *data)
|
||||
{
|
||||
|
@ -741,8 +752,6 @@ static DBusMessage *network_get_properties(DBusConnection *conn,
|
|||
const char *operator;
|
||||
const char *mode = registration_mode_to_string(netreg->mode);
|
||||
|
||||
char **network_operators;
|
||||
|
||||
reply = dbus_message_new_method_return(msg);
|
||||
if (!reply)
|
||||
return NULL;
|
||||
|
@ -793,14 +802,6 @@ static DBusMessage *network_get_properties(DBusConnection *conn,
|
|||
operator = get_operator_display_name(netreg);
|
||||
ofono_dbus_dict_append(&dict, "Name", DBUS_TYPE_STRING, &operator);
|
||||
|
||||
network_operator_populate_registered(netreg, &network_operators);
|
||||
|
||||
ofono_dbus_dict_append_array(&dict, "Operators",
|
||||
DBUS_TYPE_OBJECT_PATH,
|
||||
&network_operators);
|
||||
|
||||
g_strfreev(network_operators);
|
||||
|
||||
if (netreg->signal_strength != -1) {
|
||||
dbus_uint16_t strength = netreg->signal_strength;
|
||||
ofono_dbus_dict_append(&dict, "Strength", DBUS_TYPE_UINT16,
|
||||
|
@ -856,8 +857,106 @@ static DBusMessage *network_deregister(DBusConnection *conn,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static DBusMessage *network_propose_scan(DBusConnection *conn,
|
||||
DBusMessage *msg, void *data)
|
||||
static void append_operator_struct(struct ofono_netreg *netreg,
|
||||
struct network_operator_data *opd,
|
||||
DBusMessageIter *iter)
|
||||
{
|
||||
DBusMessageIter entry, dict;
|
||||
const char *path;
|
||||
|
||||
path = network_operator_build_path(netreg, opd->mcc, opd->mnc);
|
||||
|
||||
dbus_message_iter_open_container(iter, DBUS_TYPE_STRUCT, NULL, &entry);
|
||||
dbus_message_iter_append_basic(&entry, DBUS_TYPE_OBJECT_PATH, &path);
|
||||
dbus_message_iter_open_container(&entry, DBUS_TYPE_ARRAY,
|
||||
OFONO_PROPERTIES_ARRAY_SIGNATURE,
|
||||
&dict);
|
||||
append_operator_properties(opd, &dict);
|
||||
dbus_message_iter_close_container(&entry, &dict);
|
||||
dbus_message_iter_close_container(iter, &entry);
|
||||
}
|
||||
|
||||
static void append_operator_struct_list(struct ofono_netreg *netreg,
|
||||
DBusMessageIter *array)
|
||||
{
|
||||
DBusConnection *conn = ofono_dbus_get_connection();
|
||||
char **children;
|
||||
char path[256];
|
||||
GSList *l;
|
||||
|
||||
snprintf(path, sizeof(path), "%s/operator",
|
||||
__ofono_atom_get_path(netreg->atom));
|
||||
|
||||
if (!dbus_connection_list_registered(conn, path, &children)) {
|
||||
DBG("Unable to obtain registered NetworkOperator(s)");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Quoting 27.007: "The list of operators shall be in order: home
|
||||
* network, networks referenced in SIM or active application in the
|
||||
* UICC (GSM or USIM) in the following order: HPLMN selector, User
|
||||
* controlled PLMN selector, Operator controlled PLMN selector and
|
||||
* PLMN selector (in the SIM or GSM application), and other networks."
|
||||
* Thus we must make sure we return the list in the same order,
|
||||
* if possible. Luckily the operator_list is stored in order already
|
||||
*/
|
||||
for (l = netreg->operator_list; l; l = l->next) {
|
||||
struct network_operator_data *opd = l->data;
|
||||
char mnc[OFONO_MAX_MNC_LENGTH + 1];
|
||||
char mcc[OFONO_MAX_MCC_LENGTH + 1];
|
||||
int j;
|
||||
|
||||
for (j = 0; children[j]; j++) {
|
||||
sscanf(children[j], "%3[0-9]%[0-9]", mcc, mnc);
|
||||
|
||||
if (!strcmp(opd->mcc, mcc) && !strcmp(opd->mnc, mnc))
|
||||
append_operator_struct(netreg, opd, array);
|
||||
}
|
||||
}
|
||||
|
||||
dbus_free_string_array(children);
|
||||
}
|
||||
|
||||
static void operator_list_callback(const struct ofono_error *error, int total,
|
||||
const struct ofono_network_operator *list,
|
||||
void *data)
|
||||
{
|
||||
struct ofono_netreg *netreg = data;
|
||||
DBusMessage *reply;
|
||||
DBusMessageIter iter;
|
||||
DBusMessageIter array;
|
||||
|
||||
if (error->type != OFONO_ERROR_TYPE_NO_ERROR) {
|
||||
DBG("Error occurred during operator list");
|
||||
__ofono_dbus_pending_reply(&netreg->pending,
|
||||
__ofono_error_failed(netreg->pending));
|
||||
return;
|
||||
}
|
||||
|
||||
update_operator_list(netreg, total, list);
|
||||
|
||||
reply = dbus_message_new_method_return(netreg->pending);
|
||||
|
||||
dbus_message_iter_init_append(reply, &iter);
|
||||
|
||||
dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
|
||||
DBUS_STRUCT_BEGIN_CHAR_AS_STRING
|
||||
DBUS_TYPE_OBJECT_PATH_AS_STRING
|
||||
DBUS_TYPE_ARRAY_AS_STRING
|
||||
DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
|
||||
DBUS_TYPE_STRING_AS_STRING
|
||||
DBUS_TYPE_VARIANT_AS_STRING
|
||||
DBUS_DICT_ENTRY_END_CHAR_AS_STRING
|
||||
DBUS_STRUCT_END_CHAR_AS_STRING,
|
||||
&array);
|
||||
append_operator_struct_list(netreg, &array);
|
||||
dbus_message_iter_close_container(&iter, &array);
|
||||
|
||||
__ofono_dbus_pending_reply(&netreg->pending, reply);
|
||||
}
|
||||
|
||||
static DBusMessage *network_scan(DBusConnection *conn,
|
||||
DBusMessage *msg, void *data)
|
||||
{
|
||||
struct ofono_netreg *netreg = data;
|
||||
|
||||
|
@ -874,14 +973,45 @@ static DBusMessage *network_propose_scan(DBusConnection *conn,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static DBusMessage *network_get_operators(DBusConnection *conn,
|
||||
DBusMessage *msg, void *data)
|
||||
{
|
||||
struct ofono_netreg *netreg = data;
|
||||
DBusMessage *reply;
|
||||
DBusMessageIter iter;
|
||||
DBusMessageIter array;
|
||||
|
||||
reply = dbus_message_new_method_return(msg);
|
||||
if (reply == NULL)
|
||||
return NULL;
|
||||
|
||||
dbus_message_iter_init_append(reply, &iter);
|
||||
|
||||
dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
|
||||
DBUS_STRUCT_BEGIN_CHAR_AS_STRING
|
||||
DBUS_TYPE_OBJECT_PATH_AS_STRING
|
||||
DBUS_TYPE_ARRAY_AS_STRING
|
||||
DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
|
||||
DBUS_TYPE_STRING_AS_STRING
|
||||
DBUS_TYPE_VARIANT_AS_STRING
|
||||
DBUS_DICT_ENTRY_END_CHAR_AS_STRING
|
||||
DBUS_STRUCT_END_CHAR_AS_STRING,
|
||||
&array);
|
||||
append_operator_struct_list(netreg, &array);
|
||||
dbus_message_iter_close_container(&iter, &array);
|
||||
|
||||
return reply;
|
||||
}
|
||||
|
||||
static GDBusMethodTable network_registration_methods[] = {
|
||||
{ "GetProperties", "", "a{sv}", network_get_properties },
|
||||
{ "Register", "", "", network_register,
|
||||
G_DBUS_METHOD_FLAG_ASYNC },
|
||||
{ "Deregister", "", "", network_deregister,
|
||||
G_DBUS_METHOD_FLAG_ASYNC },
|
||||
{ "ProposeScan", "", "ao", network_propose_scan,
|
||||
G_DBUS_METHOD_FLAG_ASYNC },
|
||||
{ "GetProperties", "", "a{sv}", network_get_properties },
|
||||
{ "Register", "", "", network_register,
|
||||
G_DBUS_METHOD_FLAG_ASYNC },
|
||||
{ "Deregister", "", "", network_deregister,
|
||||
G_DBUS_METHOD_FLAG_ASYNC },
|
||||
{ "GetOperators", "", "a(oa{sv})", network_get_operators },
|
||||
{ "Scan", "", "a(oa{sv})", network_scan,
|
||||
G_DBUS_METHOD_FLAG_ASYNC },
|
||||
{ }
|
||||
};
|
||||
|
||||
|
@ -1090,138 +1220,6 @@ void ofono_netreg_time_notify(struct ofono_netreg *netreg,
|
|||
__ofono_nettime_info_received(modem, info);
|
||||
}
|
||||
|
||||
static GSList *compress_operator_list(const struct ofono_network_operator *list,
|
||||
int total)
|
||||
{
|
||||
GSList *oplist = 0;
|
||||
GSList *o;
|
||||
int i;
|
||||
struct network_operator_data *opd;
|
||||
|
||||
for (i = 0; i < total; i++) {
|
||||
o = NULL;
|
||||
|
||||
if (oplist)
|
||||
o = g_slist_find_custom(oplist, &list[i],
|
||||
network_operator_compare);
|
||||
|
||||
if (!o) {
|
||||
opd = network_operator_create(&list[i]);
|
||||
oplist = g_slist_prepend(oplist, opd);
|
||||
} else if (o && list[i].tech != -1) {
|
||||
opd = o->data;
|
||||
opd->techs |= 1 << list[i].tech;
|
||||
}
|
||||
}
|
||||
|
||||
if (oplist)
|
||||
oplist = g_slist_reverse(oplist);
|
||||
|
||||
return oplist;
|
||||
}
|
||||
|
||||
static gboolean update_operator_list(struct ofono_netreg *netreg, int total,
|
||||
const struct ofono_network_operator *list)
|
||||
{
|
||||
GSList *n = NULL;
|
||||
GSList *o;
|
||||
GSList *compressed;
|
||||
GSList *c;
|
||||
gboolean changed = FALSE;
|
||||
|
||||
compressed = compress_operator_list(list, total);
|
||||
|
||||
for (c = compressed; c; c = c->next) {
|
||||
struct network_operator_data *copd = c->data;
|
||||
|
||||
o = g_slist_find_custom(netreg->operator_list, copd,
|
||||
network_operator_data_compare);
|
||||
|
||||
if (o) { /* Update and move to a new list */
|
||||
set_network_operator_status(o->data, copd->status);
|
||||
set_network_operator_techs(o->data, copd->techs);
|
||||
set_network_operator_name(o->data, copd->name);
|
||||
|
||||
n = g_slist_prepend(n, o->data);
|
||||
netreg->operator_list =
|
||||
g_slist_remove(netreg->operator_list, o->data);
|
||||
} else {
|
||||
/* New operator */
|
||||
struct network_operator_data *opd;
|
||||
|
||||
opd = g_memdup(copd,
|
||||
sizeof(struct network_operator_data));
|
||||
|
||||
if (!network_operator_dbus_register(netreg, opd)) {
|
||||
g_free(opd);
|
||||
continue;
|
||||
}
|
||||
|
||||
n = g_slist_prepend(n, opd);
|
||||
changed = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
g_slist_foreach(compressed, (GFunc)g_free, NULL);
|
||||
g_slist_free(compressed);
|
||||
|
||||
if (n)
|
||||
n = g_slist_reverse(n);
|
||||
|
||||
if (netreg->operator_list)
|
||||
changed = TRUE;
|
||||
|
||||
for (o = netreg->operator_list; o; o = o->next)
|
||||
network_operator_dbus_unregister(netreg, o->data);
|
||||
|
||||
g_slist_free(netreg->operator_list);
|
||||
|
||||
netreg->operator_list = n;
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
static void operator_list_callback(const struct ofono_error *error, int total,
|
||||
const struct ofono_network_operator *list,
|
||||
void *data)
|
||||
{
|
||||
struct ofono_netreg *netreg = data;
|
||||
DBusMessage *reply;
|
||||
char **network_operators;
|
||||
DBusMessageIter iter;
|
||||
DBusMessageIter array_iter;
|
||||
int i;
|
||||
gboolean need_to_emit;
|
||||
|
||||
if (error->type != OFONO_ERROR_TYPE_NO_ERROR) {
|
||||
DBG("Error occurred during operator list");
|
||||
__ofono_dbus_pending_reply(&netreg->pending,
|
||||
__ofono_error_failed(netreg->pending));
|
||||
return;
|
||||
}
|
||||
|
||||
need_to_emit = update_operator_list(netreg, total, list);
|
||||
|
||||
reply = dbus_message_new_method_return(netreg->pending);
|
||||
network_operator_populate_registered(netreg, &network_operators);
|
||||
|
||||
dbus_message_iter_init_append(reply, &iter);
|
||||
dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
|
||||
DBUS_TYPE_OBJECT_PATH_AS_STRING, &array_iter);
|
||||
|
||||
for (i = 0; network_operators[i]; i++)
|
||||
dbus_message_iter_append_basic(&array_iter,
|
||||
DBUS_TYPE_OBJECT_PATH, &network_operators[i]);
|
||||
|
||||
dbus_message_iter_close_container(&iter, &array_iter);
|
||||
__ofono_dbus_pending_reply(&netreg->pending, reply);
|
||||
|
||||
g_strfreev(network_operators);
|
||||
|
||||
if (need_to_emit)
|
||||
network_operator_emit_available_operators(netreg);
|
||||
}
|
||||
|
||||
static void current_operator_callback(const struct ofono_error *error,
|
||||
const struct ofono_network_operator *current,
|
||||
void *data)
|
||||
|
@ -1296,9 +1294,6 @@ static void current_operator_callback(const struct ofono_error *error,
|
|||
netreg->current_operator = opd;
|
||||
netreg->operator_list = g_slist_append(netreg->operator_list,
|
||||
opd);
|
||||
|
||||
if (opd->mcc[0] != '\0' && opd->mnc[0] != '\0')
|
||||
network_operator_emit_available_operators(netreg);
|
||||
} else {
|
||||
/* We don't free this here because operator is registered */
|
||||
/* Taken care of elsewhere */
|
||||
|
|
Loading…
Reference in New Issue