Skip to content

Commit

Permalink
Merge branch 'vendor_signal' into 'master'
Browse files Browse the repository at this point in the history
Add vendor-specific parsing of SIGNAL_STRENGTH messages

See merge request mer-core/ofono!242
  • Loading branch information
monich committed Oct 31, 2019
2 parents e40811f + 4322708 commit a76f50b
Show file tree
Hide file tree
Showing 8 changed files with 210 additions and 81 deletions.
5 changes: 4 additions & 1 deletion ofono/drivers/ril/ril_modem.c
Expand Up @@ -20,6 +20,7 @@
#include "ril_sim_card.h"
#include "ril_sim_settings.h"
#include "ril_cell_info.h"
#include "ril_vendor.h"
#include "ril_data.h"
#include "ril_util.h"
#include "ril_log.h"
Expand Down Expand Up @@ -435,6 +436,7 @@ static void ril_modem_remove(struct ofono_modem *ofono)
g_source_remove(md->set_offline.timeout_id);
}

ril_vendor_unref(modem->vendor);
ril_network_unref(modem->network);
ril_sim_card_unref(modem->sim_card);
ril_data_unref(modem->data);
Expand All @@ -456,7 +458,7 @@ struct ril_modem *ril_modem_create(GRilIoChannel *io, const char *log_prefix,
const char *ecclist_file, const struct ril_slot_config *config,
struct ril_radio *radio, struct ril_network *network,
struct ril_sim_card *card, struct ril_data *data,
struct ril_sim_settings *settings,
struct ril_sim_settings *settings, struct ril_vendor *vendor,
struct sailfish_cell_info *cell_info)
{
/* Skip the slash from the path, it looks like "/ril_0" */
Expand All @@ -483,6 +485,7 @@ struct ril_modem *ril_modem_create(GRilIoChannel *io, const char *log_prefix,
g_strconcat(log_prefix, " ", NULL) : g_strdup("");

modem->ofono = ofono;
modem->vendor = ril_vendor_ref(vendor);
modem->radio = ril_radio_ref(radio);
modem->network = ril_network_ref(network);
modem->sim_card = ril_sim_card_ref(card);
Expand Down
149 changes: 74 additions & 75 deletions ofono/drivers/ril/ril_netreg.c
Expand Up @@ -2,6 +2,7 @@
* oFono - Open Source Telephony - RIL-based devices
*
* Copyright (C) 2015-2019 Jolla Ltd.
* Copyright (C) 2019 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
Expand All @@ -16,6 +17,7 @@
#include "ril_plugin.h"
#include "ril_network.h"
#include "ril_util.h"
#include "ril_vendor.h"
#include "ril_log.h"

#include "common.h"
Expand All @@ -42,6 +44,7 @@ struct ril_netreg {
gboolean network_selection_manual_0;
struct ofono_netreg *netreg;
struct ril_network *network;
struct ril_vendor *vendor;
char *log_prefix;
guint timer_id;
guint notify_id;
Expand Down Expand Up @@ -331,100 +334,92 @@ static void ril_netreg_register_manual(struct ofono_netreg *netreg,
grilio_request_unref(req);
}

static int ril_netreg_dbm_to_percentage(int dbm)
static int ril_netreg_qdbm_to_percentage(int qdbm /* 4*dBm */)
{
const int min_dbm = -100; /* very weak signal, 0.0000000001 mW */
const int max_dbm = -60; /* strong signal, 0.000001 mW */
const int min_qdbm = -4*100; /* very weak signal, 0.0000000001 mW */
const int max_qdbm = -4*60; /* strong signal, 0.000001 mW */

return (dbm <= min_dbm) ? 1 :
(dbm >= max_dbm) ? 100 :
(100 * (dbm - min_dbm) / (max_dbm - min_dbm));
return (qdbm <= min_qdbm) ? 1 :
(qdbm >= max_qdbm) ? 100 :
(100 * (qdbm - min_qdbm) / (max_qdbm - min_qdbm));
}

static int ril_netreg_get_signal_strength(const void *data, guint len)
static int ril_netreg_get_signal_strength(struct ril_vendor *vendor,
const void *data, guint len)
{
GRilIoParser rilp;
int gw_signal = 0, cdma_dbm = 0, evdo_dbm = 0, lte_signal = 0;
int rsrp = 0, tdscdma_dbm = 0;
struct ril_vendor_signal_strength signal;

grilio_parser_init(&rilp, data, len);

/* GW_SignalStrength */
grilio_parser_get_int32(&rilp, &gw_signal);
grilio_parser_get_int32(&rilp, NULL); /* bitErrorRate */

/* CDMA_SignalStrength */
grilio_parser_get_int32(&rilp, &cdma_dbm);
grilio_parser_get_int32(&rilp, NULL); /* ecio */

/* EVDO_SignalStrength */
grilio_parser_get_int32(&rilp, &evdo_dbm);
grilio_parser_get_int32(&rilp, NULL); /* ecio */
grilio_parser_get_int32(&rilp, NULL); /* signalNoiseRatio */

/* LTE_SignalStrength */
grilio_parser_get_int32(&rilp, &lte_signal);
grilio_parser_get_int32(&rilp, &rsrp);

/* Skip the rest of LTE_SignalStrength_v8 */
if (grilio_parser_get_int32(&rilp, NULL) && /* rsrq */
grilio_parser_get_int32(&rilp, NULL) && /* rssnr */
grilio_parser_get_int32(&rilp, NULL) && /* cqi */
grilio_parser_get_int32(&rilp, NULL)) { /* timingAdvance */

/* TD_SCDMA_SignalStrength */
grilio_parser_get_int32(&rilp, &tdscdma_dbm); /* rscp */
signal.gsm = INT_MAX;
signal.lte = INT_MAX;
signal.qdbm = 0;

if (!ril_vendor_signal_strength_parse(vendor, &signal, &rilp)) {
gint32 rsrp = 0, tdscdma_dbm = 0;

/* Apply default parsing algorithm */
grilio_parser_init(&rilp, data, len);
signal.gsm = INT_MAX;
signal.lte = INT_MAX;
signal.qdbm = 0;

/* GW_SignalStrength */
grilio_parser_get_int32(&rilp, &signal.gsm);
grilio_parser_get_int32(&rilp, NULL); /* bitErrorRate */

/* CDMA_SignalStrength */
grilio_parser_get_int32(&rilp, NULL); /* dbm */
grilio_parser_get_int32(&rilp, NULL); /* ecio */

/* EVDO_SignalStrength */
grilio_parser_get_int32(&rilp, NULL); /* dbm */
grilio_parser_get_int32(&rilp, NULL); /* ecio */
grilio_parser_get_int32(&rilp, NULL); /* signalNoiseRatio */

/* LTE_SignalStrength */
grilio_parser_get_int32(&rilp, &signal.lte);
grilio_parser_get_int32(&rilp, &rsrp);

/* The rest is considered optional */
if (grilio_parser_get_int32(&rilp, NULL) && /* rsrq */
grilio_parser_get_int32(&rilp, NULL) && /* rssnr */
grilio_parser_get_int32(&rilp, NULL) && /* cqi */
grilio_parser_get_int32(&rilp, NULL) && /* timingAdv */
/* TD_SCDMA_SignalStrength */
grilio_parser_get_int32(&rilp, &tdscdma_dbm) &&
/* RSCP range: 25 to 120 dBm per 3GPP TS 25.123 */
tdscdma_dbm >= 25 && tdscdma_dbm <= 120) {
signal.qdbm = -4 * tdscdma_dbm;
} else if (signal.lte == 99 && rsrp >= 44 && rsrp <= 140) {
/* RSRP range: 44 to 140 dBm per 3GPP TS 36.133 */
signal.qdbm = -rsrp;
}
}

if (rsrp == INT_MAX) {
DBG("gw: %d, cdma: %d, evdo: %d, lte: %d, tdscdma: %d",
gw_signal, cdma_dbm, evdo_dbm,
lte_signal, tdscdma_dbm);
} else {
DBG("gw: %d, cdma: %d, evdo: %d, lte: %d rsrp: %d, tdscdma: %d",
gw_signal, cdma_dbm, evdo_dbm,
lte_signal, rsrp, tdscdma_dbm);
}
DBG("gw: %d, lte: %d, qdbm: %d", signal.gsm, signal.lte, signal.qdbm);

/* Return the first valid one */

/* Some RILs (namely, from MediaTek) report 0 here AND a valid LTE
* RSRP value. If we've got zero, don't report it just yet. */
if (gw_signal >= 1 && gw_signal <= 31) {
if (signal.gsm >= 1 && signal.gsm <= 31) {
/* Valid values are (0-31, 99) as defined in TS 27.007 */
return (gw_signal * 100) / 31;
return (signal.gsm * 100) / 31;
}

/* Valid values are (0-31, 99) as defined in TS 27.007 */
if (lte_signal >= 0 && lte_signal <= 31) {
return (lte_signal * 100) / 31;
}

/* RSCP range: 25 to 120 dBm as defined in 3GPP TS 25.123 */
if (tdscdma_dbm >= 25 && tdscdma_dbm <= 120) {
return ril_netreg_dbm_to_percentage(-tdscdma_dbm);
if (signal.lte >= 0 && signal.lte <= 31) {
return (signal.lte * 100) / 31;
}

/* RSRP range: 44 to 140 dBm as defined in 3GPP TS 36.133 */
if (lte_signal == 99 && rsrp >= 44 && rsrp <= 140) {
return ril_netreg_dbm_to_percentage(-rsrp);
}

/* If we've got zero strength and no valid RSRP, then so be it */
if (gw_signal == 0) {
if (signal.qdbm < 0) {
return ril_netreg_qdbm_to_percentage(signal.qdbm);
} else if (signal.gsm == 0) {
return 0;
} else {
return -1;
}

/* In case of dbm, return the value directly */
if (cdma_dbm != -1) {
return MIN(cdma_dbm, 100);
}

if (evdo_dbm != -1) {
return MIN(evdo_dbm, 100);
}

return -1;
}

static void ril_netreg_strength_notify(GRilIoChannel *io, guint ril_event,
Expand All @@ -434,9 +429,11 @@ static void ril_netreg_strength_notify(GRilIoChannel *io, guint ril_event,
int strength;

GASSERT(ril_event == RIL_UNSOL_SIGNAL_STRENGTH);
strength = ril_netreg_get_signal_strength(data, len);
strength = ril_netreg_get_signal_strength(nd->vendor, data, len);
DBG_(nd, "%d", strength);
ofono_netreg_strength_notify(nd->netreg, strength);
if (strength >= 0) {
ofono_netreg_strength_notify(nd->netreg, strength);
}
}

static void ril_netreg_strength_cb(GRilIoChannel *io, int status,
Expand All @@ -447,8 +444,8 @@ static void ril_netreg_strength_cb(GRilIoChannel *io, int status,
struct ofono_error error;

if (status == RIL_E_SUCCESS) {
int strength = ril_netreg_get_signal_strength(data, len);
cb(ril_error_ok(&error), strength, cbd->data);
cb(ril_error_ok(&error), ril_netreg_get_signal_strength
(cbd->nd->vendor, data, len), cbd->data);
} else {
ofono_error("Failed to retrive the signal strength: %s",
ril_error_to_string(status));
Expand Down Expand Up @@ -558,6 +555,7 @@ static int ril_netreg_probe(struct ofono_netreg *netreg, unsigned int vendor,
DBG_(nd, "%p", netreg);
nd->io = grilio_channel_ref(ril_modem_io(modem));
nd->q = grilio_queue_new(nd->io);
nd->vendor = ril_vendor_ref(modem->vendor);
nd->network = ril_network_ref(modem->network);
nd->netreg = netreg;
nd->network_selection_manual_0 = config->network_selection_manual_0;
Expand Down Expand Up @@ -589,6 +587,7 @@ static void ril_netreg_remove(struct ofono_netreg *netreg)

ril_network_remove_all_handlers(nd->network, nd->network_event_id);
ril_network_unref(nd->network);
ril_vendor_unref(nd->vendor);

grilio_channel_remove_all_handlers(nd->io, nd->ril_event_id);
grilio_channel_unref(nd->io);
Expand Down
2 changes: 1 addition & 1 deletion ofono/drivers/ril/ril_plugin.c
Expand Up @@ -838,7 +838,7 @@ static void ril_plugin_create_modem(ril_slot *slot)
modem = ril_modem_create(slot->io, log_prefix, slot->path, slot->imei,
slot->imeisv, slot->ecclist_file, &slot->config, slot->radio,
slot->network, slot->sim_card, slot->data, slot->sim_settings,
slot->cell_info);
slot->vendor, slot->cell_info);

if (modem) {
slot->modem = modem;
Expand Down
6 changes: 4 additions & 2 deletions ofono/drivers/ril/ril_plugin.h
@@ -1,7 +1,8 @@
/*
* oFono - Open Source Telephony - RIL-based devices
*
* Copyright (C) 2015-2017 Jolla Ltd.
* Copyright (C) 2015-2019 Jolla Ltd.
* Copyright (C) 2019 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
Expand Down Expand Up @@ -52,6 +53,7 @@ struct ril_modem {
const char *ecclist_file;
struct ofono_modem *ofono;
struct sailfish_cell_info *cell_info;
struct ril_vendor *vendor;
struct ril_radio *radio;
struct ril_data *data;
struct ril_network *network;
Expand All @@ -70,7 +72,7 @@ struct ril_modem *ril_modem_create(GRilIoChannel *io, const char *log_prefix,
const char *ecclist_file, const struct ril_slot_config *config,
struct ril_radio *radio, struct ril_network *network,
struct ril_sim_card *card, struct ril_data *data,
struct ril_sim_settings *settings,
struct ril_sim_settings *settings, struct ril_vendor *vendor,
struct sailfish_cell_info *cell_info);
void ril_modem_delete(struct ril_modem *modem);
struct ofono_sim *ril_modem_ofono_sim(struct ril_modem *modem);
Expand Down
17 changes: 17 additions & 0 deletions ofono/drivers/ril/ril_vendor.c
Expand Up @@ -2,6 +2,7 @@
* oFono - Open Source Telephony - RIL-based devices
*
* Copyright (C) 2019 Jolla Ltd.
* Copyright (C) 2019 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
Expand Down Expand Up @@ -116,6 +117,14 @@ gboolean ril_vendor_data_call_parse(RilVendor *self,
data_call_parse(self, call, ver, rilp);
}

gboolean ril_vendor_signal_strength_parse(RilVendor *self,
struct ril_vendor_signal_strength *signal_strength,
GRilIoParser *rilp)
{
return G_LIKELY(self) && RIL_VENDOR_GET_CLASS(self)->
signal_strength_parse(self, signal_strength, rilp);
}

static void ril_vendor_default_set_network(RilVendor *self,
struct ril_network *network)
{
Expand Down Expand Up @@ -160,6 +169,13 @@ static gboolean ril_vendor_default_data_call_parse(RilVendor *self,
return FALSE;
}

static gboolean ril_vendor_default_signal_strength_parse(RilVendor *self,
struct ril_vendor_signal_strength *signal_strength,
GRilIoParser *rilp)
{
return FALSE;
}

void ril_vendor_init_base(RilVendor *self, GRilIoChannel *io)
{
self->io = grilio_channel_ref(io);
Expand Down Expand Up @@ -190,6 +206,7 @@ static void ril_vendor_class_init(RilVendorClass* klass)
klass->set_attach_apn_req = ril_vendor_default_set_attach_apn_req;
klass->data_call_req = ril_vendor_default_data_call_req;
klass->data_call_parse = ril_vendor_default_data_call_parse;
klass->signal_strength_parse = ril_vendor_default_signal_strength_parse;
}

/*
Expand Down
9 changes: 9 additions & 0 deletions ofono/drivers/ril/ril_vendor.h
Expand Up @@ -39,6 +39,12 @@ struct ril_vendor_driver {
const struct ril_slot_config *cfg);
};

struct ril_vendor_signal_strength {
gint32 gsm; /* (0-31, 99) per TS 27.007 8.5 */
gint32 lte; /* (0-31, 99) per TS 27.007 8.5 */
gint32 qdbm; /* 4*dBm, 0 if none */
};

const struct ril_vendor_driver *ril_vendor_find_driver(const char *name);
struct ril_vendor *ril_vendor_create
(const struct ril_vendor_driver *vendor, GRilIoChannel *io,
Expand All @@ -65,6 +71,9 @@ GRilIoRequest *ril_vendor_data_call_req(struct ril_vendor *vendor, int tech,
gboolean ril_vendor_data_call_parse(struct ril_vendor *vendor,
struct ril_data_call *call, int version,
GRilIoParser *rilp);
gboolean ril_vendor_signal_strength_parse(struct ril_vendor *vendor,
struct ril_vendor_signal_strength *signal_strength,
GRilIoParser *rilp);

/* Put vendor driver descriptors to the "__vendor" section */
#define RIL_VENDOR_DRIVER_DEFINE(name) const struct ril_vendor_driver name \
Expand Down
4 changes: 4 additions & 0 deletions ofono/drivers/ril/ril_vendor_impl.h
Expand Up @@ -2,6 +2,7 @@
* oFono - Open Source Telephony - RIL-based devices
*
* Copyright (C) 2019 Jolla Ltd.
* Copyright (C) 2019 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
Expand Down Expand Up @@ -42,6 +43,9 @@ typedef struct ril_vendor_class {
gboolean (*data_call_parse)(RilVendor *vendor,
struct ril_data_call *call, int version,
GRilIoParser *rilp);
gboolean (*signal_strength_parse)(RilVendor *vendor,
struct ril_vendor_signal_strength *signal_strength,
GRilIoParser *rilp);
} RilVendorClass;

GType ril_vendor_get_type(void);
Expand Down

0 comments on commit a76f50b

Please sign in to comment.