Skip to content

Commit

Permalink
[ofono-binder] Add NR support. JB#58763
Browse files Browse the repository at this point in the history
  • Loading branch information
mlehtima committed Apr 20, 2023
1 parent c6c881e commit 268a14b
Show file tree
Hide file tree
Showing 9 changed files with 337 additions and 32 deletions.
88 changes: 86 additions & 2 deletions src/binder_cell_info.c
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ enum binder_cell_info_signal {

#define SIGNAL_CELLS_CHANGED_NAME "binder-cell-info-cells-changed"

static GUtilIdlePool* binder_cell_info_pool = NULL;
static guint binder_cell_info_signals[SIGNAL_COUNT] = { 0 };

G_DEFINE_TYPE(BinderCellInfo, binder_cell_info, G_TYPE_OBJECT)
Expand All @@ -93,7 +94,23 @@ binder_cell_info_int_format(
if (value == OFONO_CELL_INVALID_VALUE) {
return "";
} else {
static GUtilIdlePool* binder_cell_info_pool = NULL;
GUtilIdlePool* pool = gutil_idle_pool_get(&binder_cell_info_pool);
char* str = g_strdup_printf(format, value);

gutil_idle_pool_add(pool, str, g_free);
return str;
}
}

static
const char*
binder_cell_info_int64_format(
guint64 value,
const char* format)
{
if (value == OFONO_CELL_INVALID_VALUE_INT64) {
return "";
} else {
GUtilIdlePool* pool = gutil_idle_pool_get(&binder_cell_info_pool);
char* str = g_strdup_printf(format, value);

Expand Down Expand Up @@ -185,6 +202,25 @@ binder_cell_info_invalidate(
}
}

static
void
binder_cell_info_invalidate_nr(
struct ofono_cell_info_nr* nr)
{
nr->mcc = OFONO_CELL_INVALID_VALUE;
nr->mnc = OFONO_CELL_INVALID_VALUE;
nr->nci = OFONO_CELL_INVALID_VALUE_INT64;
nr->pci = OFONO_CELL_INVALID_VALUE;
nr->tac = OFONO_CELL_INVALID_VALUE;
nr->nrarfcn = OFONO_CELL_INVALID_VALUE;
nr->ssRsrp = OFONO_CELL_INVALID_VALUE;
nr->ssRsrq = OFONO_CELL_INVALID_VALUE;
nr->ssSinr = OFONO_CELL_INVALID_VALUE;
nr->csiRsrp = OFONO_CELL_INVALID_VALUE;
nr->csiRsrq = OFONO_CELL_INVALID_VALUE;
nr->csiSinr = OFONO_CELL_INVALID_VALUE;
}

static
struct ofono_cell*
binder_cell_info_new_cell_gsm(
Expand Down Expand Up @@ -295,6 +331,46 @@ binder_cell_info_new_cell_lte(
binder_cell_info_int_format(lte->timingAdvance, ",t=%d"));
return cell;
}
static
struct ofono_cell*
binder_cell_info_new_cell_nr(
gboolean registered,
const RadioCellIdentityNr* id,
const RadioSignalStrengthNr* ss)
{
struct ofono_cell* cell = binder_cell_new();
struct ofono_cell_info_nr* nr = &cell->info.nr;

cell->type = OFONO_CELL_TYPE_NR;
cell->registered = registered;

binder_cell_info_invalidate_nr(nr);
gutil_parse_int(id->mcc.data.str, 10, &nr->mcc);
gutil_parse_int(id->mnc.data.str, 10, &nr->mnc);
nr->nci = id->nci;
nr->pci = id->pci;
nr->tac = id->tac;
nr->nrarfcn = id->nrarfcn;
nr->ssRsrp = ss->ssRsrp;
nr->ssRsrq = ss->ssRsrq;
nr->ssSinr = ss->ssSinr;
nr->csiRsrp = ss->csiRsrp;
nr->csiRsrq = ss->csiRsrq;
nr->csiSinr = ss->csiSinr;
DBG("[nr] reg=%d%s%s%s%s%s%s%s%s%s%s%s", registered,
binder_cell_info_int_format(nr->mcc, ",mcc=%d"),
binder_cell_info_int_format(nr->mnc, ",mnc=%d"),
binder_cell_info_int64_format(nr->nci, ",nci=%" G_GINT64_FORMAT),
binder_cell_info_int_format(nr->pci, ",pci=%d"),
binder_cell_info_int_format(nr->tac, ",tac=%d"),
binder_cell_info_int_format(nr->ssRsrp, ",ssRsrp=%d"),
binder_cell_info_int_format(nr->ssRsrq, ",ssRsrq=%d"),
binder_cell_info_int_format(nr->ssSinr, ",ssSinr=%d"),
binder_cell_info_int_format(nr->csiRsrp, ",csiRsrp=%d"),
binder_cell_info_int_format(nr->csiRsrq, ",csiRsrq=%d"),
binder_cell_info_int_format(nr->csiSinr, ",csiSinr=%d"));
return cell;
}

static
GPtrArray*
Expand Down Expand Up @@ -427,9 +503,13 @@ binder_cell_info_array_new_1_4(
&cell->info.wcdma.cellIdentityWcdma.base,
&cell->info.wcdma.signalStrengthWcdma.base));
continue;
case RADIO_CELL_INFO_1_4_NR:
g_ptr_array_add(l, binder_cell_info_new_cell_nr(registered,
&cell->info.nr.cellIdentity,
&cell->info.nr.signalStrength));
continue;
case RADIO_CELL_INFO_1_4_TD_SCDMA:
case RADIO_CELL_INFO_1_4_CDMA:
case RADIO_CELL_INFO_1_4_NR:
break;
}
DBG("unsupported cell type %d", cell->cellInfoType);
Expand Down Expand Up @@ -467,6 +547,10 @@ binder_cell_info_array_new_1_5(
&cell->info.wcdma.signalStrengthWcdma.base));
continue;
case RADIO_CELL_INFO_1_5_NR:
g_ptr_array_add(l, binder_cell_info_new_cell_nr(registered,
&cell->info.nr.cellIdentityNr.base,
&cell->info.nr.signalStrengthNr));
continue;
case RADIO_CELL_INFO_1_5_TD_SCDMA:
case RADIO_CELL_INFO_1_5_CDMA:
break;
Expand Down
101 changes: 86 additions & 15 deletions src/binder_netreg.c
Original file line number Diff line number Diff line change
Expand Up @@ -121,17 +121,33 @@ static const BinderNetRegRadioType binder_netreg_radio_types[] = {
OFONO_RADIO_ACCESS_MODE_LTE,
RADIO_ACCESS_NETWORKS_EUTRAN,
RADIO_NETWORK_SCAN_SPECIFIER_1_5_EUTRAN
#if 0
}
};

static const BinderNetRegRadioType binder_netreg_radio_types_1_5[] = {
{
OFONO_RADIO_ACCESS_MODE_GSM,
RADIO_ACCESS_NETWORKS_GERAN,
RADIO_NETWORK_SCAN_SPECIFIER_1_5_GERAN
},{
OFONO_RADIO_ACCESS_MODE_UMTS,
RADIO_ACCESS_NETWORKS_UTRAN,
RADIO_NETWORK_SCAN_SPECIFIER_1_5_UTRAN
},{
OFONO_RADIO_ACCESS_MODE_LTE,
RADIO_ACCESS_NETWORKS_EUTRAN,
RADIO_NETWORK_SCAN_SPECIFIER_1_5_EUTRAN
},{
OFONO_RADIO_ACCESS_MODE_NR,
RADIO_ACCESS_NETWORKS_NGRAN,
RADIO_NETWORK_SCAN_SPECIFIER_1_5_NGRAN
#endif
}
};

#define N_RADIO_TYPES G_N_ELEMENTS(binder_netreg_radio_types)
G_STATIC_ASSERT(N_RADIO_TYPES == OFONO_RADIO_ACCESS_MODE_COUNT);
#define N_RADIO_TYPES_1_5 G_N_ELEMENTS(binder_netreg_radio_types_1_5)
G_STATIC_ASSERT(N_RADIO_TYPES == (OFONO_RADIO_ACCESS_MODE_COUNT - 1));
G_STATIC_ASSERT(N_RADIO_TYPES_1_5 == OFONO_RADIO_ACCESS_MODE_COUNT);

#define DBG_(self,fmt,args...) DBG("%s" fmt, (self)->log_prefix, ##args)

Expand Down Expand Up @@ -572,12 +588,21 @@ binder_netreg_start_network_scan(
RADIO_REQ_START_NETWORK_SCAN_1_5;
GBinderWriter writer;
guint i, nspecs = 0;
const BinderNetRegRadioType* radio_types[N_RADIO_TYPES];
const BinderNetRegRadioType* radio_types[(iface < RADIO_INTERFACE_1_5) ?
N_RADIO_TYPES : N_RADIO_TYPES_1_5];

/* Which modes are supported and enabled */
for (i = 0; i < N_RADIO_TYPES; i++) {
if (self->techs & binder_netreg_radio_types[i].mode) {
radio_types[nspecs++] = binder_netreg_radio_types + i;
if (iface <= RADIO_INTERFACE_1_4) {
for (i = 0; i < N_RADIO_TYPES; i++) {
if (self->techs & binder_netreg_radio_types[i].mode) {
radio_types[nspecs++] = binder_netreg_radio_types + i;
}
}
} else {
for (i = 0; i < N_RADIO_TYPES_1_5; i++) {
if (self->techs & binder_netreg_radio_types_1_5[i].mode) {
radio_types[nspecs++] = binder_netreg_radio_types + i;
}
}
}

Expand Down Expand Up @@ -716,13 +741,14 @@ binder_netreg_start_network_scan(

specs[i].radioAccessNetwork = radio_type->ran;
spec->type = radio_type->spec_1_5_type;
/* The rest may (hopfully) remain zero-initialized */
/* The rest may (hopefully) remain zero-initialized */
}
scan->type = RADIO_SCAN_ONE_SHOT;
scan->interval = 10;
scan->specifiers.owns_buffer = TRUE;
scan->specifiers.count = nspecs;
scan->specifiers.data.ptr = specs;
scan->maxSearchTime = 60;
scan->incrementalResults = TRUE;
scan->incrementalResultsPeriodicity = 3;
gbinder_writer_append_struct(&writer, scan,
Expand Down Expand Up @@ -928,6 +954,29 @@ binder_netreg_scan_op_convert_lte(
binder_radio_op_status_string(dest->status));
}

static
void
binder_netreg_scan_op_convert_nr(
gboolean registered,
const RadioCellIdentityNr* src,
struct ofono_network_operator* dest)
{
const RadioCellIdentityNr* nr = src;

memset(dest, 0, sizeof(*dest));
dest->status = registered ?
OFONO_OPERATOR_STATUS_CURRENT :
OFONO_OPERATOR_STATUS_AVAILABLE;
dest->tech = OFONO_ACCESS_TECHNOLOGY_NG_RAN;
binder_netreg_scan_op_copy_name(&src->operatorNames, dest);
g_strlcpy(dest->mcc, nr->mcc.data.str, sizeof(dest->mcc));
g_strlcpy(dest->mnc, nr->mnc.data.str, sizeof(dest->mnc));
DBG("[registered=%d, operator=%s, %s, %s, %s, %s]",
registered, dest->name, dest->mcc, dest->mnc,
binder_ofono_access_technology_string(dest->tech),
binder_radio_op_status_string(dest->status));
}

static
struct ofono_network_operator*
binder_netreg_scan_op_append(
Expand Down Expand Up @@ -1021,6 +1070,10 @@ binder_netreg_scan_result_notify(
binder_netreg_scan_op_append(scan));
break;
case RADIO_CELL_INFO_1_4_NR:
binder_netreg_scan_op_convert_nr(cell->registered,
&cell->info.nr.cellIdentity,
binder_netreg_scan_op_append(scan));
break;
case RADIO_CELL_INFO_1_4_CDMA:
case RADIO_CELL_INFO_1_4_TD_SCDMA:
break;
Expand Down Expand Up @@ -1049,6 +1102,10 @@ binder_netreg_scan_result_notify(
binder_netreg_scan_op_append(scan));
break;
case RADIO_CELL_INFO_1_5_NR:
binder_netreg_scan_op_convert_nr(cell->registered,
&cell->info.nr.cellIdentityNr.base,
binder_netreg_scan_op_append(scan));
break;
case RADIO_CELL_INFO_1_5_CDMA:
case RADIO_CELL_INFO_1_5_TD_SCDMA:
break;
Expand Down Expand Up @@ -1218,13 +1275,20 @@ binder_netreg_register_manual(
char* numeric = g_strconcat(mcc, mnc, NULL);
GBinderWriter writer;
RadioRequest* req = radio_request_new(self->client,
(radio_client_interface(self->client) >= RADIO_INTERFACE_1_5) ?
RADIO_REQ_SET_NETWORK_SELECTION_MODE_MANUAL_1_5 :
RADIO_REQ_SET_NETWORK_SELECTION_MODE_MANUAL, &writer,
binder_netreg_register_cb, binder_netreg_cbd_destroy,
binder_netreg_cbd_new(self, BINDER_CB(cb), data));

/* setNetworkSelectionModeManual(int32 serial, string operatorNumeric); */
gbinder_writer_add_cleanup(&writer, g_free, numeric);
gbinder_writer_append_hidl_string(&writer, numeric);
/* setNetworkSelectionModeManual_1_5 adds also suggested radio access network */
if (radio_client_interface(self->client) >= RADIO_INTERFACE_1_5) {
gbinder_writer_append_int32(&writer, RADIO_ACCESS_NETWORKS_UNKNOWN);
}

radio_request_set_timeout(req, self->network_selection_timeout_ms);

radio_request_drop(self->register_req);
Expand Down Expand Up @@ -1327,7 +1391,8 @@ binder_netreg_get_signal_strength_dbm(
const RadioSignalStrengthGsm* gsm,
const RadioSignalStrengthLte* lte,
const RadioSignalStrengthWcdma_1_2* wcdma,
const RadioSignalStrengthTdScdma_1_2* tdscdma)
const RadioSignalStrengthTdScdma_1_2* tdscdma,
const RadioSignalStrengthNr* nr)
{
int rssi = -1, rscp = -1, rsrp = -1;

Expand Down Expand Up @@ -1365,6 +1430,12 @@ binder_netreg_get_signal_strength_dbm(
}
}

if (nr) {
if (nr->ssRsrp >= RSRP_MIN && nr->ssRsrp <= RSRP_MAX) {
rsrp = nr->ssRsrp;
}
}

if (rssi >= RSCP_MIN) {
return binder_netreg_dbm_from_rssi(rssi);
} else if (rscp >= RSCP_MIN) {
Expand Down Expand Up @@ -1409,23 +1480,23 @@ binder_netreg_strength_notify(

if (ss) {
dbm = binder_netreg_get_signal_strength_dbm
(&ss->gw, &ss->lte, NULL, NULL);
(&ss->gw, &ss->lte, NULL, NULL, NULL);
}
} else if (code == RADIO_IND_CURRENT_SIGNAL_STRENGTH_1_2) {
const RadioSignalStrength_1_2* ss = gbinder_reader_read_hidl_struct
(&reader, RadioSignalStrength_1_2);

if (ss) {
dbm = binder_netreg_get_signal_strength_dbm
(&ss->gw, &ss->lte, &ss->wcdma, NULL);
(&ss->gw, &ss->lte, &ss->wcdma, NULL, NULL);
}
} else if (code == RADIO_IND_CURRENT_SIGNAL_STRENGTH_1_4) {
const RadioSignalStrength_1_4* ss = gbinder_reader_read_hidl_struct
(&reader, RadioSignalStrength_1_4);

if (ss) {
dbm = binder_netreg_get_signal_strength_dbm
(&ss->gsm, &ss->lte, &ss->wcdma, &ss->tdscdma);
(&ss->gsm, &ss->lte, &ss->wcdma, &ss->tdscdma, &ss->nr);
}
}

Expand Down Expand Up @@ -1467,7 +1538,7 @@ static void binder_netreg_strength_cb(

if (ss) {
dbm = binder_netreg_get_signal_strength_dbm
(&ss->gw, &ss->lte, NULL, NULL);
(&ss->gw, &ss->lte, NULL, NULL, NULL);
}
} else if (resp == RADIO_RESP_GET_SIGNAL_STRENGTH_1_2) {
const RadioSignalStrength_1_2* ss =
Expand All @@ -1476,7 +1547,7 @@ static void binder_netreg_strength_cb(

if (ss) {
dbm = binder_netreg_get_signal_strength_dbm
(&ss->gw, &ss->lte, &ss->wcdma, NULL);
(&ss->gw, &ss->lte, &ss->wcdma, NULL, NULL);
}
} else if (resp == RADIO_RESP_GET_SIGNAL_STRENGTH_1_4) {
const RadioSignalStrength_1_4* ss =
Expand All @@ -1485,7 +1556,7 @@ static void binder_netreg_strength_cb(

if (ss) {
dbm = binder_netreg_get_signal_strength_dbm
(&ss->gsm, &ss->lte, &ss->wcdma, &ss->tdscdma);
(&ss->gsm, &ss->lte, &ss->wcdma, &ss->tdscdma, &ss->nr);
}
} else {
ofono_error("Unexpected getSignalStrength response %d", resp);
Expand Down

0 comments on commit 268a14b

Please sign in to comment.