Compare commits

...

24 Commits

Author SHA1 Message Date
Matti Lehtimäki
0bd4932f0c Version 1.1.12 2023-05-23 14:33:43 +03:00
Matti Lehtimäki
541faa7847 Merge pull request #28 from mer-hybris/jb58763
Add NR support
2023-05-23 14:32:23 +03:00
Matti Lehtimäki
1a71970f82 [ofono-binder] Add NR support. JB#58763 2023-04-21 14:58:59 +03:00
Matti Lehtimäki
6e2b7102c9 [ofono-binder] Make technologies configurable. JB#58763 2023-04-21 14:10:52 +03:00
Matti Lehtimäki
0969d8c13e [ofono-binder] Use correct indication filter for IRadio@1.5. JB#58746 2023-04-21 14:10:52 +03:00
Matti Lehtimäki
d8825b020d [ofono-binder] Add support for setRadioPower_1_5. JB#58746 2023-04-21 14:10:51 +03:00
Slava Monich
5ed68de345 Version 1.1.11 2022-11-30 15:42:40 +02:00
Slava Monich
6125c577aa Merge pull request #27 from monich/no-config
Fix startup without IRadioConfig at all
2022-11-30 15:26:26 +02:00
Slava Monich
a9fc9a0dce Merge pull request #26 from monich/mode-config
Make LTE and 3G modes configurable
2022-11-30 15:26:06 +02:00
Slava Monich
393cb9d820 Merge pull request #25 from monich/data-reg
Use data registration state when available
2022-11-30 15:25:10 +02:00
Slava Monich
0174eb3523 [ofono-binder] Fix startup without IRadioConfig at all 2022-11-30 12:41:45 +02:00
Slava Monich
6286318db9 [ofono-binder] Made UMTS network mode configurable. JB#59207 2022-11-29 18:18:32 +02:00
Slava Monich
bf16469738 [ofono-binder] Made LTE network mode configurable 2022-11-29 18:09:53 +02:00
Slava Monich
89b22d61b6 [ofono-binder] Use data registration state when available. JB#59329
Data connectivity makes perfect sense without voice, VoLTE may also
work without voice registration. In that sense, data registration
is even more functional than voice. In any case, if we have any
sort of registration, report that to the ofono core.
2022-11-29 02:29:53 +02:00
Slava Monich
29234d826d Merge pull request #24 from monich/data-profile
Use gbinder_writer_append_struct() to encode DataProfile
2022-11-27 19:52:06 +02:00
Slava Monich
993fe31fac [ofono-binder] Use gbinder_writer_append_struct() to encode DataProfile 2022-11-25 02:27:35 +02:00
Slava Monich
44fc6e6554 Version 1.1.10 2022-11-23 18:46:22 +02:00
Slava Monich
cc77d8eb82 Merge pull request #23 from monich/network-scan
Add support for network scan API
2022-11-23 18:39:36 +02:00
Slava Monich
1ca4036fca [ofono-binder] Add support for network scan API. JB#58746
It doesn't seem to work reliably on all supported devices and
currently only used a fallback if getAvailableNetworks is not
supported.
2022-11-23 16:34:58 +02:00
Slava Monich
1ee5bde1b3 [ofono-binder] Document radioInterface config option. JB#58746 2022-11-19 03:28:31 +02:00
Slava Monich
43e29a9904 Version 1.1.9 2022-09-16 17:17:51 +03:00
Slava Monich
6e3d429942 Merge pull request #22 from mer-hybris/jb58746
Add support for Radio@1.5 and RadioConfig@1.2
2022-09-16 17:10:54 +03:00
Matti Lehtimäki
534a948916 [ofono-binder] Add support for Radio@1.5 interface. JB#58746 2022-09-16 02:58:39 +03:00
Matti Lehtimäki
304b9eb439 [ofono-binder] Add support for RadioConfig@1.2 interface. JB#58746 2022-09-16 02:55:59 +03:00
19 changed files with 1917 additions and 193 deletions

View File

@@ -58,6 +58,7 @@ SRC = \
binder_modem.c \
binder_netreg.c \
binder_network.c \
binder_oplist.c \
binder_radio.c \
binder_radio_caps.c \
binder_radio_settings.c \

View File

@@ -91,6 +91,13 @@
#
# [slot1]
# Radio interface version. At the time of this writing, versions 1.0
# to 1.5 were supported.
#
# Default 1.2 (android.hardware.radio@1.2::IRadio)
#
#radioInterface = 1.2
# Specifies the extension plugin to use. The plugin must be properly
# installed and registered at startup with libofonobinderpluginext by
# calling binder_ext_plugin_register()
@@ -146,6 +153,17 @@
#
#signalStrengthRange=-100,-60
# If getAvailableNetworks API is unsupported or for whatever reason
# doesn't work, startNetworkScan can also be used to get the list of
# available networks. Network scan API provides even more information
# about radio technologies supported by the available operators but
# it's only usable with IRadio interface version >= 1.2 and doesn't
# seem to work on some devices
#
# Default false (try getAvailableNetworks first)
#
#useNetworkScan=false
# With some modems, network scan returns strange operator names, i.e.
# numeric MCC+MNC values or the same name for all operators (which is
# actually SPN fetched from the SIM). Such strange names can be replaced
@@ -177,3 +195,15 @@
# Default none (all supported features are enabled)
#
#disableFeatures=
# LTE network mode.
#
# Default 9 (LTE_GSM_WCDMA)
#
#lteNetworkMode=9
# UMTS network mode.
#
# Default 3 (GSM_WCDMA_AUTO)
#
#umtsNetworkMode=3

View File

@@ -25,7 +25,7 @@ all: debug release pkgconfig
VERSION_MAJOR = 1
VERSION_MINOR = 1
VERSION_RELEASE = 8
VERSION_RELEASE = 12
# Version for pkg-config
PCVERSION = $(VERSION_MAJOR).$(VERSION_MINOR).$(VERSION_RELEASE)

View File

@@ -1,6 +1,6 @@
Name: ofono-binder-plugin
Version: 1.1.8
Version: 1.1.12
Release: 1
Summary: Binder based ofono plugin
License: GPLv2
@@ -8,11 +8,11 @@ URL: https://github.com/mer-hybris/ofono-binder-plugin
Source: %{name}-%{version}.tar.bz2
%define libglibutil_version 1.0.61
%define libgbinder_version 1.1.15
%define libgbinder_radio_version 1.4.11
%define libgbinder_version 1.1.29
%define libgbinder_radio_version 1.5.6
%define libmce_version 1.0.6
%define libofonobinderpluginext_version 1.1.0
%define ofono_version 1.28+git3
%define ofono_version 1.28+git8
BuildRequires: pkgconfig
BuildRequires: ofono-devel >= %{ofono_version}
@@ -55,7 +55,6 @@ make %{_smp_mflags} -C lib LIBDIR=%{_libdir} KEEP_SYMBOLS=1 release pkgconfig
make test
%install
rm -rf %{buildroot}
make DESTDIR=%{buildroot} PLUGINDIR=%{plugin_dir} install
make -C lib DESTDIR=%{buildroot} LIBDIR=%{_libdir} install install-dev
mkdir -p %{buildroot}%{config_dir}
@@ -103,6 +102,7 @@ Interfaces for ofono binder plugin extensions
%files -n libofonobinderpluginext-devel
%defattr(-,root,root,-)
%dir %{_includedir}/ofonobinderpluginext
%{_libdir}/pkgconfig/libofonobinderpluginext.pc
%{_libdir}/libofonobinderpluginext.so
%{_includedir}/ofonobinderpluginext/*.h

View File

@@ -37,6 +37,7 @@ enum binder_cell_info_event {
CELL_INFO_EVENT_1_0,
CELL_INFO_EVENT_1_2,
CELL_INFO_EVENT_1_4,
CELL_INFO_EVENT_1_5,
CELL_INFO_EVENT_COUNT
};
@@ -66,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)
@@ -92,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);
@@ -184,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(
@@ -294,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*
@@ -426,9 +503,56 @@ 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);
}
return l;
}
static
GPtrArray*
binder_cell_info_array_new_1_5(
const RadioCellInfo_1_5* cells,
gsize count)
{
gsize i;
GPtrArray* l = g_ptr_array_sized_new(count + 1);
for (i = 0; i < count; i++) {
const RadioCellInfo_1_5* cell = cells + i;
const gboolean registered = cell->registered;
switch ((RADIO_CELL_INFO_TYPE_1_5)cell->cellInfoType) {
case RADIO_CELL_INFO_1_5_GSM:
g_ptr_array_add(l, binder_cell_info_new_cell_gsm(registered,
&cell->info.gsm.cellIdentityGsm.base.base,
&cell->info.gsm.signalStrengthGsm));
continue;
case RADIO_CELL_INFO_1_5_LTE:
g_ptr_array_add(l, binder_cell_info_new_cell_lte(registered,
&cell->info.lte.cellIdentityLte.base.base,
&cell->info.lte.signalStrengthLte));
continue;
case RADIO_CELL_INFO_1_5_WCDMA:
g_ptr_array_add(l, binder_cell_info_new_cell_wcdma(registered,
&cell->info.wcdma.cellIdentityWcdma.base.base,
&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;
}
DBG("unsupported cell type %d", cell->cellInfoType);
@@ -490,6 +614,24 @@ binder_cell_info_list_1_4(
}
}
static
void
binder_cell_info_list_1_5(
BinderCellInfo* self,
GBinderReader* reader)
{
gsize count;
const RadioCellInfo_1_5* cells = gbinder_reader_read_hidl_type_vec(reader,
RadioCellInfo_1_5, &count);
if (cells) {
binder_cell_info_update_cells(self,
binder_cell_info_array_new_1_5(cells, count));
} else {
ofono_warn("Failed to parse cellInfoList_1_5 payload");
}
}
static
void
binder_cell_info_list_changed_1_0(
@@ -547,6 +689,25 @@ binder_cell_info_list_changed_1_4(
}
}
static
void
binder_cell_info_list_changed_1_5(
RadioClient* client,
RADIO_IND code,
const GBinderReader* args,
gpointer user_data)
{
BinderCellInfo* self = THIS(user_data);
GASSERT(code == RADIO_IND_CELL_INFO_LIST_1_5);
if (self->enabled) {
GBinderReader reader;
gbinder_reader_copy(&reader, args);
binder_cell_info_list_1_5(self, &reader);
}
}
static
void
binder_cell_info_list_cb(
@@ -579,6 +740,9 @@ binder_cell_info_list_cb(
case RADIO_RESP_GET_CELL_INFO_LIST_1_4:
binder_cell_info_list_1_4(self, &reader);
break;
case RADIO_RESP_GET_CELL_INFO_LIST_1_5:
binder_cell_info_list_1_5(self, &reader);
break;
default:
ofono_warn("Unexpected getCellInfoList response %d", resp);
break;
@@ -857,6 +1021,10 @@ binder_cell_info_new(
radio_client_add_indication_handler(client,
RADIO_IND_CELL_INFO_LIST_1_4,
binder_cell_info_list_changed_1_4, self);
self->event_id[CELL_INFO_EVENT_1_5] =
radio_client_add_indication_handler(client,
RADIO_IND_CELL_INFO_LIST_1_5,
binder_cell_info_list_changed_1_5, self);
self->radio_state_event_id =
binder_radio_add_property_handler(radio,
BINDER_RADIO_PROPERTY_STATE,

View File

@@ -81,6 +81,7 @@ enum binder_data_io_event_id {
IO_EVENT_RESTRICTED_STATE_CHANGED,
IO_EVENT_DATA_CALL_LIST_CHANGED_1_0,
IO_EVENT_DATA_CALL_LIST_CHANGED_1_4,
IO_EVENT_DATA_CALL_LIST_CHANGED_1_5,
IO_EVENT_DEATH,
IO_EVENT_COUNT
};
@@ -181,6 +182,108 @@ typedef struct binder_data_request_allow_data {
gboolean allow;
} BinderDataRequestAllowData;
/* Data type descriptors */
/*
* typedef struct radio_data_profile {
* RADIO_DATA_PROFILE_ID profileId;
* GBinderHidlString apn;
* GBinderHidlString protocol;
* GBinderHidlString roamingProtocol;
* RADIO_APN_AUTH_TYPE authType;
* GBinderHidlString user;
* GBinderHidlString password;
* RADIO_DATA_PROFILE_TYPE type;
* gint32 maxConnsTime;
* gint32 maxConns;
* gint32 waitTime;
* guint8 enabled;
* RADIO_APN_TYPES supportedApnTypesBitmap;
* RADIO_ACCESS_FAMILY bearerBitmap;
* gint32 mtu;
* gint32 mvnoType;
* GBinderHidlString mvnoMatchData;
* } RadioDataProfile;
*/
static const GBinderWriterField binder_data_profile_f[] = {
GBINDER_WRITER_FIELD_HIDL_STRING(RadioDataProfile,apn),
GBINDER_WRITER_FIELD_HIDL_STRING(RadioDataProfile,protocol),
GBINDER_WRITER_FIELD_HIDL_STRING(RadioDataProfile,roamingProtocol),
GBINDER_WRITER_FIELD_HIDL_STRING(RadioDataProfile,user),
GBINDER_WRITER_FIELD_HIDL_STRING(RadioDataProfile,password),
GBINDER_WRITER_FIELD_HIDL_STRING(RadioDataProfile,mvnoMatchData),
GBINDER_WRITER_FIELD_END()
};
const GBinderWriterType binder_data_profile_type = {
GBINDER_WRITER_STRUCT_NAME_AND_SIZE(RadioDataProfile),
binder_data_profile_f
};
/*
* typedef struct radio_data_profile_1_4 {
* RADIO_DATA_PROFILE_ID profileId;
* GBinderHidlString apn;
* RADIO_PDP_PROTOCOL_TYPE protocol;
* RADIO_PDP_PROTOCOL_TYPE roamingProtocol;
* RADIO_APN_AUTH_TYPE authType;
* GBinderHidlString user;
* GBinderHidlString password;
* RADIO_DATA_PROFILE_TYPE type;
* gint32 maxConnsTime;
* gint32 maxConns;
* gint32 waitTime;
* guint8 enabled;
* RADIO_APN_TYPES supportedApnTypesBitmap;
* RADIO_ACCESS_FAMILY bearerBitmap;
* gint32 mtu;
* guint8 preferred;
* guint8 persistent;
* } RadioDataProfile_1_4;
*/
static const GBinderWriterField binder_data_profile_1_4_f[] = {
GBINDER_WRITER_FIELD_HIDL_STRING(RadioDataProfile_1_4,apn),
GBINDER_WRITER_FIELD_HIDL_STRING(RadioDataProfile_1_4,user),
GBINDER_WRITER_FIELD_HIDL_STRING(RadioDataProfile_1_4,password),
GBINDER_WRITER_FIELD_END()
};
const GBinderWriterType binder_data_profile_1_4_type = {
GBINDER_WRITER_STRUCT_NAME_AND_SIZE(RadioDataProfile_1_4),
binder_data_profile_1_4_f
};
/*
* typedef struct radio_data_profile_1_5 {
* RADIO_DATA_PROFILE_ID profileId;
* GBinderHidlString apn;
* RADIO_PDP_PROTOCOL_TYPE protocol;
* RADIO_PDP_PROTOCOL_TYPE roamingProtocol;
* RADIO_APN_AUTH_TYPE authType;
* GBinderHidlString user;
* GBinderHidlString password;
* RADIO_DATA_PROFILE_TYPE type;
* gint32 maxConnsTime;
* gint32 maxConns;
* gint32 waitTime;
* guint8 enabled;
* RADIO_APN_TYPES supportedApnTypesBitmap;
* RADIO_ACCESS_FAMILY bearerBitmap;
* gint32 mtuV4;
* gint32 mtuV6;
* guint8 preferred;
* guint8 persistent;
* } RadioDataProfile_1_5;
*/
static const GBinderWriterField binder_data_profile_1_5_f[] = {
GBINDER_WRITER_FIELD_HIDL_STRING(RadioDataProfile_1_5,apn),
GBINDER_WRITER_FIELD_HIDL_STRING(RadioDataProfile_1_5,user),
GBINDER_WRITER_FIELD_HIDL_STRING(RadioDataProfile_1_5,password),
GBINDER_WRITER_FIELD_END()
};
const GBinderWriterType binder_data_profile_1_5_type = {
GBINDER_WRITER_STRUCT_NAME_AND_SIZE(RadioDataProfile_1_5),
binder_data_profile_1_5_f
};
static struct ofono_debug_desc binder_data_debug_desc OFONO_DEBUG_ATTR = {
.file = __FILE__,
.flags = OFONO_DEBUG_FLAG_DEFAULT,
@@ -437,6 +540,36 @@ binder_data_call_new_1_4(
return call;
}
static
BinderDataCall*
binder_data_call_new_1_5(
const RadioDataCall_1_5* dc)
{
BinderDataCall* call = binder_data_call_new();
call->cid = dc->cid;
call->status = dc->cause;
call->active = dc->active;
call->prot = dc->type;
call->retry_time = dc->suggestedRetryTime;
call->mtu = dc->mtuV4;
call->ifname = g_strdup(dc->ifname.data.str);
call->dnses = binder_strv_from_hidl_string_vec(&dc->dnses);
call->gateways = binder_strv_from_hidl_string_vec(&dc->gateways);
call->addresses = binder_strv_from_hidl_string_vec(&dc->addresses);
call->pcscf = binder_strv_from_hidl_string_vec(&dc->pcscf);
DBG("[status=%d,retry=%d,cid=%d,active=%d,type=%d,ifname=%s,"
"mtu=%d,address=%s,dns=%s,gateways=%s,pcscf=%s]",
call->status, call->retry_time, call->cid, call->active,
dc->type, call->ifname, call->mtu,
binder_print_strv(call->addresses, " "),
binder_print_strv(call->dnses, " "),
binder_print_strv(call->gateways, " "),
binder_print_strv(call->pcscf, " "));
return call;
}
static
GSList*
binder_data_call_list_1_4(
@@ -459,6 +592,28 @@ binder_data_call_list_1_4(
}
}
static
GSList*
binder_data_call_list_1_5(
const RadioDataCall_1_5* calls,
gsize n)
{
if (n) {
gsize i;
GSList* l = NULL;
DBG("num=%u", (guint) n);
for (i = 0; i < n; i++) {
l = g_slist_insert_sorted(l, binder_data_call_new_1_5(calls + i),
binder_data_call_compare);
}
return l;
} else {
DBG("no data calls");
return NULL;
}
}
static
gboolean
binder_data_call_equal(
@@ -686,6 +841,26 @@ binder_data_call_list_changed_1_4(
binder_data_call_list_changed(data, binder_data_call_list_1_4(calls, n));
}
static
void
binder_data_call_list_changed_1_5(
RadioClient* client,
RADIO_IND code,
const GBinderReader* args,
gpointer user_data)
{
BinderDataObject* data = THIS(user_data);
GBinderReader reader;
const RadioDataCall_1_5* calls;
gsize n = 0;
/* dataCallListChanged_1_5(RadioIndicationType,vec<SetupDataCallResult>) */
GASSERT(code == RADIO_IND_DATA_CALL_LIST_CHANGED_1_5);
gbinder_reader_copy(&reader, args);
calls = gbinder_reader_read_hidl_type_vec(&reader, RadioDataCall_1_5, &n);
binder_data_call_list_changed(data, binder_data_call_list_1_5(calls, n));
}
static
void binder_data_query_data_calls_cb(
RadioRequest* req,
@@ -733,6 +908,16 @@ void binder_data_query_data_calls_cb(
RadioDataCall_1_4, &count);
list = binder_data_call_list_1_4(calls, count);
} else if (resp == RADIO_RESP_GET_DATA_CALL_LIST_1_5) {
/*
* getDataCallListResponse_1_5(RadioResponseInfo,
* vec<SetupDataCallResult> dcResponse);
*/
const RadioDataCall_1_5* calls =
gbinder_reader_read_hidl_type_vec(&reader,
RadioDataCall_1_5, &count);
list = binder_data_call_list_1_5(calls, count);
} else {
ofono_error("Unexpected getDataCallList response %d", resp);
}
@@ -1060,6 +1245,17 @@ binder_data_call_setup_cb(
if (dc) {
call = binder_data_call_new_1_4(dc);
}
} else if (resp == RADIO_RESP_SETUP_DATA_CALL_1_5) {
/*
* setupDataCallResponse_1_5(RadioResponseInfo,
* SetupDataCallResult dcResponse);
*/
const RadioDataCall_1_5* dc =
gbinder_reader_read_hidl_struct(&reader, RadioDataCall_1_5);
if (dc) {
call = binder_data_call_new_1_5(dc);
}
} else {
ofono_error("Unexpected setupDataCall response %d", resp);
}
@@ -1151,9 +1347,44 @@ binder_data_call_setup_submit(
binder_radio_auth_from_ofono_method(setup->auth_method) :
RADIO_APN_AUTH_NONE;
if (iface >= RADIO_INTERFACE_1_4) {
if (iface >= RADIO_INTERFACE_1_5) {
RadioDataProfile_1_5* dp;
req = radio_request_new2(g, RADIO_REQ_SETUP_DATA_CALL_1_5,
&writer, binder_data_call_setup_cb, NULL, setup);
/*
* setupDataCall_1_4(int32_t serial, AccessNetwork accessNetwork,
* DataProfileInfo dataProfileInfo, bool roamingAllowed,
* DataRequestReason reason, vec<string> addresses,
* vec<string> dnses);
*/
dp = gbinder_writer_new0(&writer, RadioDataProfile_1_5);
// profile id is only meaningful when it's persistent on the modem.
// dp->profileId = setup->profile_id;
dp->profileId = RADIO_DATA_PROFILE_INVALID;
binder_copy_hidl_string(&writer, &dp->apn, setup->apn);
dp->protocol = dp->roamingProtocol =
binder_proto_from_ofono_proto(setup->proto);
dp->authType = auth;
binder_copy_hidl_string(&writer, &dp->user, setup->username);
binder_copy_hidl_string(&writer, &dp->password, setup->password);
dp->enabled = TRUE;
dp->supportedApnTypesBitmap =
binder_radio_apn_types_for_profile(setup->profile_id,
&data->profile_config);
gbinder_writer_append_int32(&writer,
binder_radio_access_network_for_tech(tech)); /* accessNetwork */
gbinder_writer_append_struct(&writer, dp,
&binder_data_profile_1_5_type, NULL); /* dataProfileInfo */
gbinder_writer_append_bool(&writer, TRUE); /* roamingAllowed */
gbinder_writer_append_int32(&writer,
RADIO_DATA_REQUEST_REASON_NORMAL); /* reason */
gbinder_writer_append_hidl_string_vec(&writer, &nothing, -1);
gbinder_writer_append_hidl_string_vec(&writer, &nothing, -1);
} else if (iface >= RADIO_INTERFACE_1_4) {
RadioDataProfile_1_4* dp;
guint parent;
req = radio_request_new2(g, RADIO_REQ_SETUP_DATA_CALL_1_4,
&writer, binder_data_call_setup_cb, NULL, setup);
@@ -1181,11 +1412,8 @@ binder_data_call_setup_submit(
gbinder_writer_append_int32(&writer,
binder_radio_access_network_for_tech(tech)); /* accessNetwork */
/* dataProfileInfo */
parent = gbinder_writer_append_buffer_object(&writer, dp, sizeof(*dp));
binder_append_hidl_string_data(&writer, dp, apn, parent);
binder_append_hidl_string_data(&writer, dp, user, parent);
binder_append_hidl_string_data(&writer, dp, password, parent);
gbinder_writer_append_struct(&writer, dp,
&binder_data_profile_1_4_type, NULL); /* dataProfileInfo */
gbinder_writer_append_bool(&writer, TRUE); /* roamingAllowed */
gbinder_writer_append_int32(&writer,
RADIO_DATA_REQUEST_REASON_NORMAL); /* reason */
@@ -1194,7 +1422,6 @@ binder_data_call_setup_submit(
} else {
RadioDataProfile* dp;
const char* proto_str = binder_proto_str_from_ofono_proto(setup->proto);
guint parent;
req = radio_request_new2(g, (iface >= RADIO_INTERFACE_1_2) ?
RADIO_REQ_SETUP_DATA_CALL_1_2 : RADIO_REQ_SETUP_DATA_CALL,
@@ -1232,14 +1459,8 @@ binder_data_call_setup_submit(
gbinder_writer_append_int32(&writer, tech); /* radioTechnology */
}
/* dataProfileInfo */
parent = gbinder_writer_append_buffer_object(&writer, dp, sizeof(*dp));
binder_append_hidl_string_data(&writer, dp, apn, parent);
binder_append_hidl_string_data(&writer, dp, protocol, parent);
binder_append_hidl_string_data(&writer, dp, roamingProtocol, parent);
binder_append_hidl_string_data(&writer, dp, user, parent);
binder_append_hidl_string_data(&writer, dp, password, parent);
binder_append_hidl_string_data(&writer, dp, mvnoMatchData, parent);
gbinder_writer_append_struct(&writer, dp,
&binder_data_profile_type, NULL); /* dataProfileInfo */
gbinder_writer_append_bool(&writer, FALSE); /* modemCognitive */
gbinder_writer_append_bool(&writer, TRUE); /* roamingAllowed */
gbinder_writer_append_bool(&writer, FALSE); /* isRoaming */
@@ -1771,6 +1992,10 @@ binder_data_new(
radio_client_add_indication_handler(client,
RADIO_IND_DATA_CALL_LIST_CHANGED_1_4,
binder_data_call_list_changed_1_4, self);
self->io_event_id[IO_EVENT_DATA_CALL_LIST_CHANGED_1_5] =
radio_client_add_indication_handler(client,
RADIO_IND_DATA_CALL_LIST_CHANGED_1_5,
binder_data_call_list_changed_1_5, self);
self->io_event_id[IO_EVENT_RESTRICTED_STATE_CHANGED] =
radio_client_add_indication_handler(client,
RADIO_IND_RESTRICTED_STATE_CHANGED,

View File

@@ -18,6 +18,8 @@
#include "binder_types.h"
#include <gbinder_writer.h>
#include <radio_request.h>
#include <ofono/slot.h>
@@ -252,6 +254,10 @@ binder_data_set_data_allowed_request_new(
void* user_data)
BINDER_INTERNAL;
extern const GBinderWriterType binder_data_profile_type BINDER_INTERNAL;
extern const GBinderWriterType binder_data_profile_1_4_type BINDER_INTERNAL;
extern const GBinderWriterType binder_data_profile_1_5_type BINDER_INTERNAL;
#endif /* BINDER_DATA_H */
/*

View File

@@ -148,10 +148,14 @@ binder_devmon_if_io_set_indication_filter(
code = RADIO_REQ_SET_INDICATION_FILTER;
value = self->display_on ? RADIO_IND_FILTER_ALL :
RADIO_IND_FILTER_DATA_CALL_DORMANCY;
} else {
} else if (radio_client_interface(self->client) < RADIO_INTERFACE_1_5) {
code = RADIO_REQ_SET_INDICATION_FILTER_1_2;
value = self->display_on ? RADIO_IND_FILTER_ALL_1_2 :
RADIO_IND_FILTER_DATA_CALL_DORMANCY;
} else {
code = RADIO_REQ_SET_INDICATION_FILTER_1_5;
value = self->display_on ? RADIO_IND_FILTER_ALL_1_5 :
RADIO_IND_FILTER_DATA_CALL_DORMANCY;
}
radio_request_drop(self->req);

File diff suppressed because it is too large Load Diff

View File

@@ -14,6 +14,7 @@
*/
#include "binder_base.h"
#include "binder_data.h"
#include "binder_log.h"
#include "binder_network.h"
#include "binder_radio.h"
@@ -40,6 +41,7 @@
#define SET_PREF_MODE_HOLDOFF_SEC BINDER_RETRY_SECS
#define INTINITE_TIMEOUT UINT_MAX
#define MAX_DATA_CALLS 16
typedef enum binder_network_timer {
TIMER_SET_RAT_HOLDOFF,
@@ -68,6 +70,7 @@ enum binder_network_sim_events {
enum binder_network_ind_events {
IND_NETWORK_STATE,
IND_MODEM_RESET,
IND_CURRENT_PHYSICAL_CHANNEL_CONFIGS_1_4,
IND_COUNT
};
@@ -108,6 +111,7 @@ typedef struct binder_network_object {
RADIO_PREF_NET_TYPE rat;
RADIO_PREF_NET_TYPE lte_network_mode;
RADIO_PREF_NET_TYPE umts_network_mode;
gboolean nr_connected;
int network_mode_timeout_ms;
char* log_prefix;
RadioRequest* operator_poll_req;
@@ -149,6 +153,7 @@ G_STATIC_ASSERT(OFONO_RADIO_ACCESS_MODE_ANY == 0);
G_STATIC_ASSERT(OFONO_RADIO_ACCESS_MODE_GSM > OFONO_RADIO_ACCESS_MODE_ANY);
G_STATIC_ASSERT(OFONO_RADIO_ACCESS_MODE_UMTS > OFONO_RADIO_ACCESS_MODE_GSM);
G_STATIC_ASSERT(OFONO_RADIO_ACCESS_MODE_LTE > OFONO_RADIO_ACCESS_MODE_UMTS);
G_STATIC_ASSERT(OFONO_RADIO_ACCESS_MODE_NR > OFONO_RADIO_ACCESS_MODE_LTE);
static
void
@@ -479,6 +484,56 @@ binder_network_location_1_2(
l->lac = l->ci = -1;
}
static
void
binder_network_location_1_5(
const RadioCellIdentity_1_5* cell,
BinderNetworkLocation* l)
{
switch (cell->cellIdentityType) {
case RADIO_CELL_IDENTITY_1_5_GSM: {
const RadioCellIdentityGsm_1_5* gsm = &cell->identity.gsm;
l->lac = gsm->base.base.lac;
l->ci = gsm->base.base.cid;
return;
}
case RADIO_CELL_IDENTITY_1_5_WCDMA: {
const RadioCellIdentityWcdma_1_5* wcdma = &cell->identity.wcdma;
l->lac = wcdma->base.base.lac;
l->ci = wcdma->base.base.cid;
return;
}
case RADIO_CELL_IDENTITY_1_5_TD_SCDMA: {
const RadioCellIdentityTdscdma_1_5* tds = &cell->identity.tdscdma;
l->lac = tds->base.base.lac;
l->ci = tds->base.base.cid;
return;
}
case RADIO_CELL_IDENTITY_1_5_LTE: {
const RadioCellIdentityLte_1_5* lte = &cell->identity.lte;
l->lac = -1;
l->ci = lte->base.base.ci;
return;
}
case RADIO_CELL_IDENTITY_1_5_NR: {
const RadioCellIdentityNr_1_5* nr = &cell->identity.nr;
l->lac = -1;
l->ci = nr->base.nci;
return;
}
default:
break;
}
/* Unknown location */
l->lac = l->ci = -1;
}
static
void
binder_network_poll_voice_state_1_0(
@@ -505,6 +560,19 @@ binder_network_poll_voice_state_1_2(
result->rat, l.lac, l.ci);
}
static
void
binder_network_poll_voice_state_1_5(
BinderRegistrationState* state,
const RadioRegStateResult_1_5* result)
{
BinderNetworkLocation l;
binder_network_location_1_5(&result->cellIdentity, &l);
binder_network_set_registration_state(state, result->regState,
result->rat, l.lac, l.ci);
}
static
void
binder_network_poll_voice_state_cb(
@@ -549,6 +617,16 @@ binder_network_poll_voice_state_cb(
reason = result->reasonForDenial;
binder_network_poll_voice_state_1_2(reg, result);
}
} else if (resp == RADIO_RESP_GET_VOICE_REGISTRATION_STATE_1_5) {
const RadioRegStateResult_1_5* result =
gbinder_reader_read_hidl_struct(&reader,
RadioRegStateResult_1_5);
if (result) {
reg = &state;
reason = result->reasonDataDenied;
binder_network_poll_voice_state_1_5(reg, result);
}
} else {
ofono_error("Unexpected getVoiceRegistrationState response %d",
resp);
@@ -604,13 +682,54 @@ static
void
binder_network_poll_data_state_1_4(
BinderRegistrationState* state,
BinderNetworkObject* self,
const RadioDataRegStateResult_1_4* result)
{
BinderNetworkLocation l;
RADIO_TECH rat = result->rat;
binder_network_location_1_2(&result->cellIdentity, &l);
if (result->rat == RADIO_TECH_LTE || result->rat == RADIO_TECH_LTE_CA) {
const RadioDataRegNrIndicators *nrIndicators = &result->nrIndicators;
if (self->nr_connected && nrIndicators->isEndcAvailable &&
!nrIndicators->isDcNrRestricted &&
nrIndicators->isNrAvailable) {
rat = RADIO_TECH_NR;
}
}
binder_network_set_registration_state(state, result->regState,
result->rat, l.lac, l.ci);
rat, l.lac, l.ci);
}
static
void
binder_network_poll_data_state_1_5(
BinderRegistrationState* state,
BinderNetworkObject* self,
const RadioRegStateResult_1_5* result)
{
BinderNetworkLocation l;
RADIO_TECH rat = result->rat;
binder_network_location_1_5(&result->cellIdentity, &l);
if (result->accessTechnologySpecificInfoType == RADIO_REG_ACCESS_TECHNOLOGY_SPECIFIC_INFO_EUTRAN) {
RadioRegEutranRegistrationInfo *eutranInfo = (RadioRegEutranRegistrationInfo *)&result->accessTechnologySpecificInfo;
RadioDataRegNrIndicators *nrIndicators = &eutranInfo->nrIndicators;
if ((rat == RADIO_TECH_LTE || rat == RADIO_TECH_LTE_CA) &&
self->nr_connected && nrIndicators->isEndcAvailable &&
!nrIndicators->isDcNrRestricted &&
nrIndicators->isNrAvailable) {
DBG_(self, "Setting radio technology for NSA 5G");
rat = RADIO_TECH_NR;
}
}
binder_network_set_registration_state(state, result->regState,
rat, l.lac, l.ci);
}
static
@@ -668,7 +787,18 @@ binder_network_poll_data_state_cb(
reg = &state;
reason = result->reasonDataDenied;
max_data_calls = result->maxDataCalls;
binder_network_poll_data_state_1_4(reg, result);
binder_network_poll_data_state_1_4(reg, self, result);
}
} else if (resp == RADIO_RESP_GET_DATA_REGISTRATION_STATE_1_5) {
const RadioRegStateResult_1_5* result =
gbinder_reader_read_hidl_struct(&reader,
RadioRegStateResult_1_5);
if (result) {
reg = &state;
reason = result->reasonDataDenied;
max_data_calls = MAX_DATA_CALLS;
binder_network_poll_data_state_1_5(reg, self, result);
}
} else {
ofono_error("Unexpected getDataRegistrationState response %d",
@@ -748,12 +878,22 @@ void
binder_network_poll_registration_state(
BinderNetworkObject* self)
{
RadioClient* client = self->g->client;
const RADIO_INTERFACE iface = radio_client_interface(client);
self->voice_poll_req = binder_network_poll_and_retry(self,
self->voice_poll_req, RADIO_REQ_GET_VOICE_REGISTRATION_STATE,
binder_network_poll_voice_state_cb);
self->data_poll_req = binder_network_poll_and_retry(self,
self->data_poll_req, RADIO_REQ_GET_DATA_REGISTRATION_STATE,
binder_network_poll_data_state_cb);
if (iface >= RADIO_INTERFACE_1_5) {
self->data_poll_req = binder_network_poll_and_retry(self,
self->data_poll_req, RADIO_REQ_GET_DATA_REGISTRATION_STATE_1_5,
binder_network_poll_data_state_cb);
} else {
self->data_poll_req = binder_network_poll_and_retry(self,
self->data_poll_req, RADIO_REQ_GET_DATA_REGISTRATION_STATE,
binder_network_poll_data_state_cb);
}
}
static
@@ -778,6 +918,11 @@ binder_network_mode_to_pref(
switch (ofono_radio_access_max_mode(mode)) {
case OFONO_RADIO_ACCESS_MODE_ANY:
case OFONO_RADIO_ACCESS_MODE_NR:
if (settings->techs & OFONO_RADIO_ACCESS_MODE_NR) {
return RADIO_PREF_NET_NR_LTE_GSM_WCDMA;
}
/* fallthrough */
case OFONO_RADIO_ACCESS_MODE_LTE:
if (settings->techs & OFONO_RADIO_ACCESS_MODE_LTE) {
return self->lte_network_mode;
@@ -937,25 +1082,6 @@ binder_network_new_radio_data_profile(
gbinder_writer_new0(writer, RadioDataProfile), src, dpc);
}
static
void
binder_network_write_data_profile_strings(
GBinderWriter* writer,
const RadioDataProfile* dp,
guint parent,
guint i)
{
const guint off = sizeof(*dp) * i;
/* Write the string data in the right order */
binder_append_hidl_string_data2(writer, dp, apn, parent, off);
binder_append_hidl_string_data2(writer, dp, protocol, parent, off);
binder_append_hidl_string_data2(writer, dp, roamingProtocol, parent, off);
binder_append_hidl_string_data2(writer, dp, user, parent, off);
binder_append_hidl_string_data2(writer, dp, password, parent, off);
binder_append_hidl_string_data2(writer, dp, mvnoMatchData, parent, off);
}
static
RadioDataProfile_1_4*
binder_network_fill_radio_data_profile_1_4(
@@ -978,6 +1104,28 @@ binder_network_fill_radio_data_profile_1_4(
return dp;
}
static
RadioDataProfile_1_5*
binder_network_fill_radio_data_profile_1_5(
GBinderWriter* writer,
RadioDataProfile_1_5* dp,
const BinderNetworkDataProfile* src,
const BinderDataProfileConfig* dpc)
{
binder_copy_hidl_string(writer, &dp->apn, src->apn);
binder_copy_hidl_string(writer, &dp->user, src->username);
binder_copy_hidl_string(writer, &dp->password, src->password);
dp->protocol = dp->roamingProtocol =
binder_proto_from_ofono_proto(src->proto);
dp->authType = binder_radio_auth_from_ofono_method(src->auth_method);
dp->supportedApnTypesBitmap = binder_radio_apn_types_for_profile(src->id,
dpc);
dp->enabled = TRUE;
dp->preferred = TRUE;
return dp;
}
static
RadioDataProfile_1_4*
binder_network_new_radio_data_profile_1_4(
@@ -990,22 +1138,16 @@ binder_network_new_radio_data_profile_1_4(
}
static
void
binder_network_write_data_profile_strings_1_4(
RadioDataProfile_1_5*
binder_network_new_radio_data_profile_1_5(
GBinderWriter* writer,
const RadioDataProfile_1_4* dp,
guint parent,
guint i)
const BinderNetworkDataProfile* src,
const BinderDataProfileConfig* dpc)
{
const guint off = sizeof(*dp) * i;
/* Write the string data in the right order */
binder_append_hidl_string_data2(writer, dp, apn, parent, off);
binder_append_hidl_string_data2(writer, dp, user, parent, off);
binder_append_hidl_string_data2(writer, dp, password, parent, off);
return binder_network_fill_radio_data_profile_1_5(writer,
gbinder_writer_new0(writer, RadioDataProfile_1_5), src, dpc);
}
static
gboolean
binder_network_data_profile_equal(
@@ -1100,46 +1242,53 @@ binder_network_set_data_profiles(
RadioRequest* req;
GBinderWriter writer;
GSList* l;
guint i, parent;
guint i;
if (iface >= RADIO_INTERFACE_1_4) {
if (iface >= RADIO_INTERFACE_1_5) {
RadioDataProfile_1_5* dp;
/* setDataProfile_1_5(int32 serial, vec<DataProfileInfo>); */
req = radio_request_new(client, RADIO_REQ_SET_DATA_PROFILE_1_5,
&writer, binder_network_set_data_profiles_done, NULL, self);
dp = gbinder_writer_malloc0(&writer, sizeof(*dp) * n);
for (l = self->data_profiles, i = 0; i < n; l = l->next, i++) {
binder_network_fill_radio_data_profile_1_5(&writer, dp + i,
(BinderNetworkDataProfile*) l->data, dpc);
}
gbinder_writer_append_struct_vec(&writer, dp, n,
&binder_data_profile_1_5_type);
} else if (iface >= RADIO_INTERFACE_1_4) {
RadioDataProfile_1_4* dp;
const gsize elem = sizeof(*dp);
/* setDataProfile_1_4(int32 serial, vec<DataProfileInfo>); */
req = radio_request_new(client, RADIO_REQ_SET_DATA_PROFILE_1_4,
&writer, binder_network_set_data_profiles_done, NULL, self);
dp = gbinder_writer_malloc0(&writer, elem * n);
dp = gbinder_writer_malloc0(&writer, sizeof(*dp) * n);
for (l = self->data_profiles, i = 0; i < n; l = l->next, i++) {
binder_network_fill_radio_data_profile_1_4(&writer, dp + i,
(BinderNetworkDataProfile*) l->data, dpc);
}
parent = binder_append_vec_with_data(&writer, dp, elem, n, NULL);
for (i = 0; i < n; i++) {
binder_network_write_data_profile_strings_1_4(&writer, dp + i,
parent, i);
}
gbinder_writer_append_struct_vec(&writer, dp, n,
&binder_data_profile_1_4_type);
} else {
RadioDataProfile* dp;
const gsize elem = sizeof(*dp);
/* setDataProfile(int32 serial, vec<DataProfileInfo>, bool roaming); */
req = radio_request_new(client, RADIO_REQ_SET_DATA_PROFILE,
&writer, binder_network_set_data_profiles_done, NULL, self);
dp = gbinder_writer_malloc0(&writer, elem * n);
dp = gbinder_writer_malloc0(&writer, sizeof(*dp) * n);
for (l = self->data_profiles, i = 0; i < n; l = l->next, i++) {
binder_network_fill_radio_data_profile(&writer, dp + i,
(BinderNetworkDataProfile*) l->data, dpc);
}
parent = binder_append_vec_with_data(&writer, dp, elem, n, NULL);
for (i = 0; i < n; i++) {
binder_network_write_data_profile_strings(&writer, dp + i,
parent, i);
}
gbinder_writer_append_struct_vec(&writer, dp, n,
&binder_data_profile_type);
gbinder_writer_append_bool(&writer, FALSE); /* isRoaming */
}
@@ -1206,7 +1355,8 @@ binder_network_need_initial_attach_apn(
BinderNetworkObject* self)
{
return (binder_network_actual_pref_modes(self) &
OFONO_RADIO_ACCESS_MODE_LTE) ? TRUE : FALSE;
(OFONO_RADIO_ACCESS_MODE_LTE | OFONO_RADIO_ACCESS_MODE_NR))
? TRUE : FALSE;
}
static
@@ -1233,23 +1383,26 @@ binder_network_set_initial_attach_apn(
BinderNetworkDataProfile profile;
RadioRequest* req;
GBinderWriter writer;
guint parent;
binder_network_data_profile_init(&profile, ctx, RADIO_DATA_PROFILE_DEFAULT);
if (iface >= RADIO_INTERFACE_1_4) {
RadioDataProfile_1_4* dp;
if (iface >= RADIO_INTERFACE_1_5) {
/* setInitialAttachApn_1_4(int32 serial, DataProfileInfo profile); */
req = radio_request_new2(self->g, RADIO_REQ_SET_INITIAL_ATTACH_APN_1_5,
&writer, NULL, NULL, NULL);
gbinder_writer_append_struct(&writer,
binder_network_new_radio_data_profile_1_5(&writer, &profile, dpc),
&binder_data_profile_1_5_type, NULL);
} else if (iface >= RADIO_INTERFACE_1_4) {
/* setInitialAttachApn_1_4(int32 serial, DataProfileInfo profile); */
req = radio_request_new2(self->g, RADIO_REQ_SET_INITIAL_ATTACH_APN_1_4,
&writer, NULL, NULL, NULL);
dp = binder_network_new_radio_data_profile_1_4(&writer, &profile, dpc);
parent = gbinder_writer_append_buffer_object(&writer, dp, sizeof(*dp));
binder_network_write_data_profile_strings_1_4(&writer, dp, parent, 0);
gbinder_writer_append_struct(&writer,
binder_network_new_radio_data_profile_1_4(&writer, &profile, dpc),
&binder_data_profile_1_4_type, NULL);
} else {
RadioDataProfile* dp;
/*
* setInitialAttachApn(int32 serial, DataProfileInfo profile,
* bool modemCognitive, bool isRoaming);
@@ -1257,9 +1410,9 @@ binder_network_set_initial_attach_apn(
req = radio_request_new2(self->g, RADIO_REQ_SET_INITIAL_ATTACH_APN,
&writer, NULL, NULL, NULL);
dp = binder_network_new_radio_data_profile(&writer, &profile, dpc);
parent = gbinder_writer_append_buffer_object(&writer, dp, sizeof(*dp));
binder_network_write_data_profile_strings(&writer, dp, parent, 0);
gbinder_writer_append_struct(&writer,
binder_network_new_radio_data_profile(&writer, &profile, dpc),
&binder_data_profile_type, NULL);
gbinder_writer_append_bool(&writer, FALSE); /* modemCognitive */
gbinder_writer_append_bool(&writer, FALSE); /* isRoaming */
}
@@ -1898,6 +2051,39 @@ binder_network_modem_reset_cb(
binder_network_reset_initial_attach_apn(self);
}
static
void
binder_network_current_physical_channel_configs_cb(
RadioClient* client,
RADIO_IND code,
const GBinderReader* args,
gpointer user_data)
{
BinderNetworkObject* self = THIS(user_data);
GBinderReader reader;
gboolean nr_connected = FALSE;
gbinder_reader_copy(&reader, args);
if (code == RADIO_IND_CURRENT_PHYSICAL_CHANNEL_CONFIGS_1_4) {
gsize count;
guint i;
const RadioPhysicalChannelConfig_1_4* configs = gbinder_reader_read_hidl_type_vec(&reader,
RadioPhysicalChannelConfig_1_4, &count);
for (i = 0; i < count; i++) {
if (configs[i].rat == RADIO_TECH_NR &&
configs[i].base.connectionStatus == RADIO_CELL_CONNECTION_SECONDARY_SERVING) {
DBG_(self, "NSA 5G connected");
nr_connected = TRUE;
}
}
} else {
ofono_warn("Unexpected current physical channel configs code %d", code);
}
self->nr_connected = nr_connected;
}
static
void
binder_network_radio_state_cb(
@@ -2061,6 +2247,10 @@ binder_network_new(
radio_client_add_indication_handler(client,
RADIO_IND_MODEM_RESET,
binder_network_modem_reset_cb, self);
self->ind_id[IND_CURRENT_PHYSICAL_CHANNEL_CONFIGS_1_4] =
radio_client_add_indication_handler(client,
RADIO_IND_CURRENT_PHYSICAL_CHANNEL_CONFIGS_1_4,
binder_network_current_physical_channel_configs_cb, self);
self->radio_event_id[RADIO_EVENT_STATE_CHANGED] =
binder_radio_add_property_handler(self->radio,

66
src/binder_oplist.c Normal file
View File

@@ -0,0 +1,66 @@
/*
* oFono - Open Source Telephony - binder based adaptation
*
* Copyright (C) 2022 Jolla Ltd.
*
* 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 "binder_oplist.h"
#include <ofono/netreg.h>
BinderOpList*
binder_oplist_new()
{
return (BinderOpList*) g_array_new(FALSE, TRUE,
sizeof(struct ofono_network_operator));
}
BinderOpList*
binder_oplist_set_count(
BinderOpList* oplist,
guint count)
{
if (!oplist) {
oplist = binder_oplist_new();
}
g_array_set_size((GArray*)oplist, count);
return oplist;
}
BinderOpList*
binder_oplist_append(
BinderOpList* oplist,
const struct ofono_network_operator* op)
{
if (!oplist) {
oplist = binder_oplist_new();
}
g_array_append_vals((GArray*)oplist, op, 1);
return oplist;
}
void
binder_oplist_free(
BinderOpList* oplist)
{
if (oplist) {
g_array_free((GArray*)oplist, TRUE);
}
}
/*
* Local Variables:
* mode: C
* c-basic-offset: 4
* indent-tabs-mode: nil
* End:
*/

60
src/binder_oplist.h Normal file
View File

@@ -0,0 +1,60 @@
/*
* oFono - Open Source Telephony - binder based adaptation
*
* Copyright (C) 2022 Jolla Ltd.
*
* 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.
*/
#ifndef BINDER_OPLIST_H
#define BINDER_OPLIST_H
#include "binder_types.h"
/*
* This is basically a GArray providing better type safety at compile time.
* If NULL is passed to binder_oplist_set_count() and binder_oplist_append()
* they allocate a new list with binder_oplist_new() and return it.
*/
typedef struct binder_oplist {
struct ofono_network_operator* op;
guint count;
} BinderOpList;
BinderOpList*
binder_oplist_new()
BINDER_INTERNAL;
BinderOpList*
binder_oplist_set_count(
BinderOpList* oplist,
guint count)
BINDER_INTERNAL;
BinderOpList*
binder_oplist_append(
BinderOpList* oplist,
const struct ofono_network_operator* op)
BINDER_INTERNAL;
void
binder_oplist_free(
BinderOpList* oplist)
BINDER_INTERNAL;
#endif /* BINDER_OPLIST_H */
/*
* Local Variables:
* mode: C
* c-basic-offset: 4
* indent-tabs-mode: nil
* End:
*/

View File

@@ -88,13 +88,15 @@
#define BINDER_SLOT_RADIO_INTERFACE_1_2 "1.2"
#define BINDER_SLOT_RADIO_INTERFACE_1_3 "1.3"
#define BINDER_SLOT_RADIO_INTERFACE_1_4 "1.4"
#define BINDER_SLOT_RADIO_INTERFACE_1_5 "1.5"
static const char* const binder_radio_ifaces[] = {
RADIO_1_0, /* android.hardware.radio@1.0::IRadio */
RADIO_1_1, /* android.hardware.radio@1.1::IRadio */
RADIO_1_2, /* android.hardware.radio@1.2::IRadio */
RADIO_1_3, /* android.hardware.radio@1.3::IRadio */
RADIO_1_4 /* android.hardware.radio@1.4::IRadio */
RADIO_1_4, /* android.hardware.radio@1.4::IRadio */
RADIO_1_5 /* android.hardware.radio@1.5::IRadio */
};
/*
@@ -129,8 +131,12 @@ static const char* const binder_radio_ifaces[] = {
#define BINDER_CONF_SLOT_DEFAULT_DATA_PROFILE_ID "defaultDataProfileId"
#define BINDER_CONF_SLOT_MMS_DATA_PROFILE_ID "mmsDataProfileId"
#define BINDER_CONF_SLOT_ALLOW_DATA_REQ "allowDataReq"
#define BINDER_CONF_SLOT_USE_NETWORK_SCAN "useNetworkScan"
#define BINDER_CONF_SLOT_REPLACE_STRANGE_OPER "replaceStrangeOperatorNames"
#define BINDER_CONF_SLOT_SIGNAL_STRENGTH_RANGE "signalStrengthRange"
#define BINDER_CONF_SLOT_LTE_MODE "lteNetworkMode"
#define BINDER_CONF_SLOT_UMTS_MODE "umtsNetworkMode"
#define BINDER_CONF_SLOT_TECHNOLOGIES "technologies"
/* Defaults */
#define BINDER_DEFAULT_RADIO_INTERFACE RADIO_INTERFACE_1_2
@@ -166,6 +172,9 @@ static const char* const binder_radio_ifaces[] = {
#define BINDER_DEFAULT_SLOT_DATA_CALL_RETRY_LIMIT 4
#define BINDER_DEFAULT_SLOT_DATA_CALL_RETRY_DELAY_MS 200 /* ms */
/* The overall start timeout is the longest slot timeout plus this */
#define BINDER_SLOT_REGISTRATION_TIMEOUT_MS (10*1000) /* 10 sec */
/* Modem error ids */
#define BINDER_ERROR_ID_DEATH "binder-death"
#define BINDER_ERROR_ID_CAPS_SWITCH_ABORTED "binder-caps-switch-aborted"
@@ -721,12 +730,14 @@ binder_plugin_slot_startup_check(
BinderPlugin* plugin = slot->plugin;
if (!slot->handle && radio_client_connected(slot->client) &&
!slot->imei_req && slot->imei && slot->start_timeout_id) {
!slot->imei_req && slot->imei) {
struct ofono_slot* ofono_slot;
/* Looks like we have made it before the timeout expired */
g_source_remove(slot->start_timeout_id);
slot->start_timeout_id = 0;
if (slot->start_timeout_id) {
/* We have made it before the slot timeout has expired */
g_source_remove(slot->start_timeout_id);
slot->start_timeout_id = 0;
}
/* Register this slot with the sailfish manager plugin */
DBG("registering slot %s", slot->path);
@@ -1048,7 +1059,8 @@ binder_plugin_service_list_proc(
plugin->list_call_id = 0;
/* IRadioConfig 1.0 is of no use to us */
if (gutil_strv_contains(services, RADIO_CONFIG_1_1_FQNAME)) {
if (gutil_strv_contains(services, RADIO_CONFIG_1_2_FQNAME) ||
gutil_strv_contains(services, RADIO_CONFIG_1_1_FQNAME)) {
/* If it's there then we definitely need it */
plugin->flags |= (BINDER_PLUGIN_HAVE_CONFIG_SERVICE |
BINDER_PLUGIN_NEED_CONFIG_SERVICE);
@@ -1194,7 +1206,6 @@ binder_plugin_check_data_manager(
if (!plugin->data_manager) {
const BinderPluginSettings* ps = &plugin->settings;
GASSERT(plugin->radio_config);
plugin->data_manager = binder_data_manager_new(NULL, ps->dm_flags,
ps->non_data_mode);
}
@@ -1312,6 +1323,7 @@ binder_plugin_radio_interface_name(
case RADIO_INTERFACE_1_2: return BINDER_SLOT_RADIO_INTERFACE_1_2;
case RADIO_INTERFACE_1_3: return BINDER_SLOT_RADIO_INTERFACE_1_3;
case RADIO_INTERFACE_1_4: return BINDER_SLOT_RADIO_INTERFACE_1_4;
case RADIO_INTERFACE_1_5: return BINDER_SLOT_RADIO_INTERFACE_1_5;
case RADIO_INTERFACE_NONE:
case RADIO_INTERFACE_COUNT:
break;
@@ -1403,6 +1415,7 @@ binder_plugin_create_slot(
GError* error = NULL;
const char* group = name;
GUtilInts* ints;
char **strv;
char* sval;
int ival;
@@ -1604,6 +1617,69 @@ binder_plugin_create_slot(
slot->data_opt.allow_data = ival;
}
/* technologies */
strv = ofono_conf_get_strings(file, group, BINDER_CONF_SLOT_TECHNOLOGIES, ',');
if (strv) {
char **p;
config->techs = 0;
for (p = strv; *p; p++) {
const char *s = *p;
enum ofono_radio_access_mode m;
if (!s[0]) {
continue;
}
if (!strcmp(s, "all")) {
config->techs = OFONO_RADIO_ACCESS_MODE_ALL;
break;
}
if (!ofono_radio_access_mode_from_string(s, &m)) {
ofono_warn("Unknown technology %s in [%s] "
"section of %s", s, group,
BINDER_CONF_FILE);
continue;
}
if (m == OFONO_RADIO_ACCESS_MODE_ANY) {
config->techs = OFONO_RADIO_ACCESS_MODE_ALL;
break;
}
config->techs |= m;
}
g_strfreev(strv);
}
/* limit technologies based on radioInterface */
if (slot->version < RADIO_INTERFACE_1_4) {
config->techs &= ~OFONO_RADIO_ACCESS_MODE_NR;
}
/* lteNetworkMode */
if (ofono_conf_get_integer(file, group,
BINDER_CONF_SLOT_LTE_MODE, &ival)) {
DBG("%s: " BINDER_CONF_SLOT_LTE_MODE " %d", group, ival);
config->lte_network_mode = ival;
}
/* umtsNetworkMode */
if (ofono_conf_get_integer(file, group,
BINDER_CONF_SLOT_UMTS_MODE, &ival)) {
DBG("%s: " BINDER_CONF_SLOT_UMTS_MODE " %d", group, ival);
config->umts_network_mode = ival;
}
/* useNetworkScan */
if (ofono_conf_get_boolean(file, group,
BINDER_CONF_SLOT_USE_NETWORK_SCAN,
&config->use_network_scan)) {
DBG("%s: " BINDER_CONF_SLOT_USE_NETWORK_SCAN " %s", group,
config->use_network_scan ? "yes" : "no");
}
/* replaceStrangeOperatorNames */
if (ofono_conf_get_boolean(file, group,
BINDER_CONF_SLOT_REPLACE_STRANGE_OPER,
@@ -1855,7 +1931,9 @@ binder_plugin_parse_config_file(
ofono_radio_access_mode_to_string(OFONO_RADIO_ACCESS_MODE_UMTS),
OFONO_RADIO_ACCESS_MODE_UMTS,
ofono_radio_access_mode_to_string(OFONO_RADIO_ACCESS_MODE_LTE),
OFONO_RADIO_ACCESS_MODE_LTE, NULL)) {
OFONO_RADIO_ACCESS_MODE_LTE,
ofono_radio_access_mode_to_string(OFONO_RADIO_ACCESS_MODE_NR),
OFONO_RADIO_ACCESS_MODE_NR, NULL)) {
DBG(BINDER_CONF_PLUGIN_MAX_NON_DATA_MODE " %s",
ofono_radio_access_mode_to_string(ival));
ps->non_data_mode = ival;
@@ -2104,7 +2182,7 @@ binder_plugin_manager_start_timeout(
plugin->flags &= ~BINDER_PLUGIN_NEED_CONFIG_SERVICE;
}
binder_plugin_check_data_manager(plugin);
binder_plugin_foreach_slot(plugin, binder_plugin_slot_check_radio_client);
binder_plugin_manager_started(plugin);
return G_SOURCE_REMOVE;
}
@@ -2145,13 +2223,13 @@ binder_plugin_manager_start_done(
static
void
binder_plugin_slot_check_timeout_cb(
binder_plugin_slot_pick_shortest_timeout_cb(
BinderSlot* slot,
void* param)
{
guint* timeout = param;
if ((*timeout) < slot->start_timeout_ms) {
if (!(*timeout) || (*timeout) < slot->start_timeout_ms) {
(*timeout) = slot->start_timeout_ms;
}
}
@@ -2165,9 +2243,20 @@ binder_plugin_slot_start_timeout(
BinderPlugin* plugin = slot->plugin;
DBG("%s", slot->name);
plugin->slots = g_slist_remove(plugin->slots, slot);
slot->start_timeout_id = 0;
binder_plugin_slot_free(slot);
/*
* If any slot times out and we haven't seen IRadioConfig so far,
* then assume that we don't need it.
*/
if (!(plugin->flags & BINDER_PLUGIN_HAVE_CONFIG_SERVICE)) {
plugin->flags &= ~BINDER_PLUGIN_NEED_CONFIG_SERVICE;
}
binder_plugin_foreach_slot(plugin, binder_plugin_slot_check_radio_client);
if (!slot->client) {
plugin->slots = g_slist_remove(plugin->slots, slot);
binder_plugin_slot_free(slot);
}
binder_plugin_check_if_started(plugin);
return G_SOURCE_REMOVE;
}
@@ -2290,13 +2379,26 @@ binder_plugin_slot_driver_init(
return plugin;
}
static
void
binder_plugin_slot_check_plugin_flags_cb(
BinderSlot* slot,
void* param)
{
BinderPlugin* plugin = param;
if (slot->version >= RADIO_INTERFACE_1_2) {
plugin->flags |= BINDER_PLUGIN_NEED_CONFIG_SERVICE;
}
}
static
guint
binder_plugin_slot_driver_start(
BinderPlugin* plugin)
{
BinderPluginSettings* ps = &plugin->settings;
guint start_timeout = 0;
guint start_timeout, shortest_timeout = 0;
DBG("");
@@ -2305,9 +2407,11 @@ binder_plugin_slot_driver_start(
/* Pick the shortest timeout */
binder_plugin_foreach_slot_param(plugin,
binder_plugin_slot_check_timeout_cb, &start_timeout);
binder_plugin_slot_pick_shortest_timeout_cb, &shortest_timeout);
/* Timeout remains zero if there are no slots */
start_timeout = shortest_timeout ?
(shortest_timeout + BINDER_SLOT_REGISTRATION_TIMEOUT_MS) : 0;
GASSERT(!plugin->start_timeout_id);
plugin->start_timeout_id = g_timeout_add_full(G_PRIORITY_DEFAULT,
start_timeout, binder_plugin_manager_start_timeout,
@@ -2322,9 +2426,11 @@ binder_plugin_slot_driver_start(
* But if IRadioConfig 1.0 is there and IRadioConfig 1.1 isn't,
* then there's no point in waiting for IRadioConfig 1.1.
*
* At startup, assume that we need IRadioConfig
* At startup, assume that we need IRadioConfig for IRadio 1.2
* and higher.
*/
plugin->flags |= BINDER_PLUGIN_NEED_CONFIG_SERVICE;
binder_plugin_foreach_slot_param(plugin,
binder_plugin_slot_check_plugin_flags_cb, plugin);
plugin->radio_config_watch_id =
gbinder_servicemanager_add_registration_handler(plugin->svcmgr,
RADIO_CONFIG_1_0, binder_plugin_service_registration_proc, plugin);

View File

@@ -181,13 +181,17 @@ binder_radio_power_request_cb(
void* user_data)
{
BinderRadioObject* self = THIS(user_data);
const RADIO_INTERFACE iface = radio_client_interface(self->client);
const RADIO_RESP code = (iface >= RADIO_INTERFACE_1_5) ?
RADIO_RESP_SET_RADIO_POWER_1_5 :
RADIO_RESP_SET_RADIO_POWER;
GASSERT(self->pending_req == req);
radio_request_unref(self->pending_req);
self->pending_req = NULL;
if (status == RADIO_TX_STATUS_OK) {
if (resp != RADIO_RESP_SET_RADIO_POWER) {
if (resp != code) {
ofono_error("Unexpected setRadioPower response %d", resp);
} else if (error != RADIO_ERROR_NONE) {
ofono_error("Power request failed: %s",
@@ -206,13 +210,24 @@ binder_radio_submit_power_request(
BinderRadioObject* self,
gboolean on)
{
/* setRadioPower(int32 serial, bool on) */
/* setRadioPower(int32 serial, bool on)
* setRadioPower_1_5(int32 serial, bool on, bool forEmergencyCall,
* bool preferredForEmergencyCall)
*/
GBinderWriter writer;
const RADIO_INTERFACE iface = radio_client_interface(self->client);
const RADIO_REQ code = (iface >= RADIO_INTERFACE_1_5) ?
RADIO_REQ_SET_RADIO_POWER_1_5 :
RADIO_REQ_SET_RADIO_POWER;
RadioRequest* req = radio_request_new(self->client,
RADIO_REQ_SET_RADIO_POWER, &writer,
code, &writer,
binder_radio_power_request_cb, NULL, self);
gbinder_writer_append_bool(&writer, on);
if (iface >= RADIO_INTERFACE_1_5) {
gbinder_writer_append_bool(&writer, FALSE);
gbinder_writer_append_bool(&writer, FALSE);
}
self->next_state_valid = FALSE;
self->next_state = on;

View File

@@ -188,7 +188,8 @@ static const struct binder_access_mode_raf {
} binder_access_mode_raf_map[] = {
{ OFONO_RADIO_ACCESS_MODE_GSM, RAF_EDGE | RAF_GPRS | RAF_GSM },
{ OFONO_RADIO_ACCESS_MODE_UMTS, RAF_UMTS },
{ OFONO_RADIO_ACCESS_MODE_LTE, RAF_LTE | RAF_LTE_CA }
{ OFONO_RADIO_ACCESS_MODE_LTE, RAF_LTE | RAF_LTE_CA },
{ OFONO_RADIO_ACCESS_MODE_NR, RAF_NR }
};
static const BinderRadioCapsRequestTxPhase binder_radio_caps_tx_phase[] = {

View File

@@ -493,6 +493,7 @@ binder_sim_card_status_cb(
const RadioCardStatus* status_1_0;
const RadioCardStatus_1_2* status_1_2;
const RadioCardStatus_1_4* status_1_4;
const RadioCardStatus_1_5* status_1_5;
BinderSimCardStatus* status = NULL;
GBinderReader reader;
@@ -519,6 +520,13 @@ binder_sim_card_status_cb(
status = binder_sim_card_status_new(&status_1_4->base);
}
break;
case RADIO_RESP_GET_ICC_CARD_STATUS_1_5:
status_1_5 = gbinder_reader_read_hidl_struct(&reader,
RadioCardStatus_1_5);
if (status_1_5) {
status = binder_sim_card_status_new(&status_1_5->base.base);
}
break;
default:
ofono_warn("Unexpected getIccCardStatus response %u", resp);
}

View File

@@ -72,6 +72,7 @@ typedef struct binder_slot_config {
gboolean empty_pin_query;
gboolean radio_power_cycle;
gboolean confirm_radio_power_on;
gboolean use_network_scan;
gboolean replace_strange_oper;
gboolean force_gsm_when_radio_off;
BinderDataProfileConfig data_profile_config;
@@ -88,10 +89,13 @@ typedef struct binder_slot_config {
typedef void (*BinderCallback)(void);
#define BINDER_CB(f) ((BinderCallback)(f))
#define OFONO_RADIO_ACCESS_MODE_COUNT (4)
#define OFONO_RADIO_ACCESS_MODE_ALL (\
OFONO_RADIO_ACCESS_MODE_GSM |\
OFONO_RADIO_ACCESS_MODE_UMTS |\
OFONO_RADIO_ACCESS_MODE_LTE)
OFONO_RADIO_ACCESS_MODE_LTE |\
OFONO_RADIO_ACCESS_MODE_NR)
#define OFONO_RADIO_ACCESS_MODE_NONE \
((enum ofono_radio_access_mode) 0)
@@ -102,6 +106,8 @@ typedef void (*BinderCallback)(void);
(OFONO_RADIO_ACCESS_MODE_UMTS | (OFONO_RADIO_ACCESS_MODE_UMTS - 1))
#define OFONO_RADIO_ACCESS_LTE_MASK \
(OFONO_RADIO_ACCESS_MODE_LTE | (OFONO_RADIO_ACCESS_MODE_LTE - 1))
#define OFONO_RADIO_ACCESS_NR_MASK \
(OFONO_RADIO_ACCESS_MODE_NR | (OFONO_RADIO_ACCESS_MODE_NR - 1))
#endif /* BINDER_TYPES_H */

View File

@@ -39,6 +39,8 @@ static const char PROTO_IPV4V6_STR[] = "IPV4V6";
(RAF_UMTS|RAF_HSDPA|RAF_HSUPA|RAF_HSPA|RAF_HSPAP|RAF_TD_SCDMA|RAF_EHRPD)
#define RADIO_ACCESS_FAMILY_LTE \
(RAF_LTE|RAF_LTE_CA|RAF_EHRPD)
#define RADIO_ACCESS_FAMILY_NR \
(RAF_NR)
static
const char*
@@ -80,6 +82,8 @@ binder_radio_access_network_for_tech(
return RADIO_ACCESS_NETWORK_EUTRAN;
case RADIO_TECH_IWLAN:
return RADIO_ACCESS_NETWORK_IWLAN;
case RADIO_TECH_NR:
return RADIO_ACCESS_NETWORK_NGRAN;
case RADIO_TECH_UNKNOWN:
break;
}
@@ -224,6 +228,9 @@ binder_pref_from_raf(
if (raf & RADIO_ACCESS_FAMILY_GSM) {
if (raf & RADIO_ACCESS_FAMILY_UMTS) {
if (raf & RADIO_ACCESS_FAMILY_LTE) {
if (raf & RADIO_ACCESS_FAMILY_NR) {
return RADIO_PREF_NET_NR_LTE_GSM_WCDMA;
}
return RADIO_PREF_NET_LTE_GSM_WCDMA;
}
return RADIO_PREF_NET_GSM_WCDMA;
@@ -231,11 +238,19 @@ binder_pref_from_raf(
return RADIO_PREF_NET_GSM_ONLY;
} else if (raf & RADIO_ACCESS_FAMILY_UMTS) {
if (raf & RADIO_ACCESS_FAMILY_LTE) {
if (raf & RADIO_ACCESS_FAMILY_NR) {
return RADIO_PREF_NET_NR_LTE_WCDMA;
}
return RADIO_PREF_NET_LTE_WCDMA;
}
return RADIO_PREF_NET_WCDMA;
} else if (raf & RADIO_ACCESS_FAMILY_LTE) {
if (raf & RADIO_ACCESS_FAMILY_NR) {
return RADIO_PREF_NET_NR_LTE;
}
return RADIO_PREF_NET_LTE_ONLY;
} else if (raf & RADIO_ACCESS_FAMILY_NR) {
return RADIO_PREF_NET_NR_ONLY;
} else {
return RADIO_PREF_NET_INVALID;
}
@@ -248,7 +263,8 @@ binder_pref_mask(
int none,
int gsm_mask,
int umts_mask,
int lte_mask)
int lte_mask,
int nr_mask)
{
switch (pref) {
case RADIO_PREF_NET_GSM_ONLY:
@@ -263,6 +279,12 @@ binder_pref_mask(
case RADIO_PREF_NET_LTE_CDMA_EVDO:
return lte_mask;
case RADIO_PREF_NET_NR_ONLY:
return nr_mask;
case RADIO_PREF_NET_NR_LTE:
return lte_mask | nr_mask;
case RADIO_PREF_NET_TD_SCDMA_GSM:
case RADIO_PREF_NET_GSM_WCDMA:
case RADIO_PREF_NET_GSM_WCDMA_AUTO:
@@ -283,6 +305,19 @@ binder_pref_mask(
case RADIO_PREF_NET_TD_SCDMA_LTE_CDMA_EVDO_GSM_WCDMA:
return gsm_mask | umts_mask | lte_mask;
case RADIO_PREF_NET_NR_LTE_CDMA_EVDO:
case RADIO_PREF_NET_NR_LTE_WCDMA:
case RADIO_PREF_NET_NR_LTE_TD_SCDMA:
case RADIO_PREF_NET_NR_LTE_TD_SCDMA_WCDMA:
return umts_mask | lte_mask | nr_mask;
case RADIO_PREF_NET_NR_LTE_GSM_WCDMA:
case RADIO_PREF_NET_NR_LTE_TD_SCDMA_GSM:
case RADIO_PREF_NET_NR_LTE_CDMA_EVDO_GSM_WCDMA:
case RADIO_PREF_NET_NR_LTE_TD_SCDMA_GSM_WCDMA:
case RADIO_PREF_NET_NR_LTE_TD_SCDMA_CDMA_EVDO_GSM_WCDMA:
return gsm_mask | umts_mask | lte_mask | nr_mask;
case RADIO_PREF_NET_CDMA_ONLY:
case RADIO_PREF_NET_EVDO_ONLY:
case RADIO_PREF_NET_CDMA_EVDO_AUTO:
@@ -300,7 +335,7 @@ binder_raf_from_pref(
{
return binder_pref_mask(pref, RAF_NONE,
RADIO_ACCESS_FAMILY_GSM, RADIO_ACCESS_FAMILY_UMTS,
RADIO_ACCESS_FAMILY_LTE);
RADIO_ACCESS_FAMILY_LTE, RADIO_ACCESS_FAMILY_NR);
}
enum ofono_radio_access_mode
@@ -309,7 +344,7 @@ binder_access_modes_from_pref(
{
return binder_pref_mask(pref, OFONO_RADIO_ACCESS_MODE_NONE,
OFONO_RADIO_ACCESS_MODE_GSM, OFONO_RADIO_ACCESS_MODE_UMTS,
OFONO_RADIO_ACCESS_MODE_LTE);
OFONO_RADIO_ACCESS_MODE_LTE, OFONO_RADIO_ACCESS_MODE_NR);
}
enum ofono_radio_access_mode
@@ -331,6 +366,9 @@ binder_access_modes_from_raf(
if (raf & RADIO_ACCESS_FAMILY_LTE) {
modes |= OFONO_RADIO_ACCESS_MODE_LTE;
}
if (raf & RADIO_ACCESS_FAMILY_NR) {
modes |= OFONO_RADIO_ACCESS_MODE_NR;
}
return modes;
}
}
@@ -371,6 +409,8 @@ binder_access_tech_from_radio_tech(
case RADIO_TECH_LTE:
case RADIO_TECH_LTE_CA:
return OFONO_ACCESS_TECHNOLOGY_EUTRAN;
case RADIO_TECH_NR:
return OFONO_ACCESS_TECHNOLOGY_NR_5GCN;
case RADIO_TECH_IWLAN:
case RADIO_TECH_IS95B:
case RADIO_TECH_ONE_X_RTT:
@@ -410,6 +450,12 @@ binder_ofono_access_technology_string(
return "utran";
case OFONO_ACCESS_TECHNOLOGY_EUTRAN:
return "eutran";
case OFONO_ACCESS_TECHNOLOGY_EUTRA_5GCN:
return "eutran";
case OFONO_ACCESS_TECHNOLOGY_NR_5GCN:
case OFONO_ACCESS_TECHNOLOGY_NG_RAN:
case OFONO_ACCESS_TECHNOLOGY_EUTRA_NR:
return "nr";
}
return binder_pool_string(g_strdup_printf("%d (?)", act));
}

View File

@@ -44,6 +44,21 @@ struct ofono_network_operator;
#define binder_error_sim(err,sw1,sw2) \
(binder_error_init_sim_error(err,sw1,sw2), err)
/* Internal extension for RADIO_PREF_NET_TYPE */
typedef enum radio_pref_net_type_internal {
RADIO_PREF_NET_NR_ONLY = RADIO_PREF_NET_TD_SCDMA_LTE_CDMA_EVDO_GSM_WCDMA + 1,
RADIO_PREF_NET_NR_LTE,
RADIO_PREF_NET_NR_LTE_CDMA_EVDO,
RADIO_PREF_NET_NR_LTE_GSM_WCDMA,
RADIO_PREF_NET_NR_LTE_CDMA_EVDO_GSM_WCDMA,
RADIO_PREF_NET_NR_LTE_WCDMA,
RADIO_PREF_NET_NR_LTE_TD_SCDMA,
RADIO_PREF_NET_NR_LTE_TD_SCDMA_GSM,
RADIO_PREF_NET_NR_LTE_TD_SCDMA_WCDMA,
RADIO_PREF_NET_NR_LTE_TD_SCDMA_GSM_WCDMA,
RADIO_PREF_NET_NR_LTE_TD_SCDMA_CDMA_EVDO_GSM_WCDMA
} RADIO_PREF_NET_TYPE_INTERNAL;
RADIO_ACCESS_NETWORK
binder_radio_access_network_for_tech(
RADIO_TECH tech)