ofono.lists.linux.dev archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 01/14] simutil: Convert eons APIs to use ell
@ 2024-04-03 16:05 Denis Kenzior
  2024-04-03 16:05 ` [PATCH v2 02/14] sim: Simplify SPN management logic Denis Kenzior
                   ` (13 more replies)
  0 siblings, 14 replies; 15+ messages in thread
From: Denis Kenzior @ 2024-04-03 16:05 UTC (permalink / raw)
  To: ofono; +Cc: Denis Kenzior

While here, also remove sim_eons_optimize() as it is no longer needed.
The ell queue implementation natively supports pushing to the back of a
linked list.  Also tighten up some length checks and make 'length'
arguments unsigned.
---
 src/network.c       |   2 -
 src/simutil.c       | 116 +++++++++++++++++++++-----------------------
 src/simutil.h       |  15 +++---
 unit/test-simutil.c |   1 -
 4 files changed, 63 insertions(+), 71 deletions(-)

diff --git a/src/network.c b/src/network.c
index 886e5bf0f9a3..629d5fb91eb8 100644
--- a/src/network.c
+++ b/src/network.c
@@ -1581,8 +1581,6 @@ static void sim_opl_read_cb(int ok, int length, int record,
 		return;
 
 optimize:
-	sim_eons_optimize(netreg->eons);
-
 	for (l = netreg->operator_list; l; l = l->next) {
 		struct network_operator_data *opd = l->data;
 		const struct sim_eons_operator_info *eons_info;
diff --git a/src/simutil.c b/src/simutil.c
index 543ab9962ef2..fbecf6db67de 100644
--- a/src/simutil.c
+++ b/src/simutil.c
@@ -36,10 +36,10 @@
 #include "missing.h"
 
 struct sim_eons {
-	struct sim_eons_operator_info *pnn_list;
-	GSList *opl_list;
-	gboolean pnn_valid;
-	int pnn_max;
+	struct l_queue *opl_list;
+	bool pnn_valid;
+	uint32_t pnn_max;
+	struct sim_eons_operator_info pnn_list[];
 };
 
 struct spdi_operator {
@@ -782,12 +782,12 @@ bool validate_utf8_tlv(const unsigned char *tlv)
 }
 
 static char *sim_network_name_parse(const unsigned char *buffer, int length,
-					gboolean *add_ci)
+					bool *add_ci)
 {
 	char *ret = NULL;
 	unsigned char dcs;
 	int i;
-	gboolean ci = FALSE;
+	bool ci = FALSE;
 	unsigned char *unpacked_buf;
 	long num_char, written;
 	int spare_bits;
@@ -999,22 +999,18 @@ void sim_spdi_free(struct sim_spdi *spdi)
 	g_free(spdi);
 }
 
-static void pnn_operator_free(struct sim_eons_operator_info *oper)
+struct sim_eons *sim_eons_new(uint32_t pnn_records)
 {
-	if (oper == NULL)
-		return;
+	struct sim_eons *eons = l_malloc(sizeof(struct sim_eons) +
+			sizeof(struct sim_eons_operator_info) * pnn_records);
 
-	l_free(oper->info);
-	l_free(oper->shortname);
-	l_free(oper->longname);
-}
+	eons->pnn_valid = false;
+	eons->pnn_max = pnn_records;
 
-struct sim_eons *sim_eons_new(int pnn_records)
-{
-	struct sim_eons *eons = g_new0(struct sim_eons, 1);
+	memset(eons->pnn_list, 0,
+			sizeof(struct sim_eons_operator_info) * pnn_records);
 
-	eons->pnn_list = g_new0(struct sim_eons_operator_info, pnn_records);
-	eons->pnn_max = pnn_records;
+	eons->opl_list = l_queue_new();
 
 	return eons;
 }
@@ -1024,8 +1020,8 @@ gboolean sim_eons_pnn_is_empty(struct sim_eons *eons)
 	return !eons->pnn_valid;
 }
 
-void sim_eons_add_pnn_record(struct sim_eons *eons, int record,
-				const guint8 *tlv, int length)
+void sim_eons_add_pnn_record(struct sim_eons *eons, uint32_t record,
+				const uint8_t *tlv, uint16_t length)
 {
 	const unsigned char *name;
 	int namelength;
@@ -1053,9 +1049,9 @@ void sim_eons_add_pnn_record(struct sim_eons *eons, int record,
 	eons->pnn_valid = TRUE;
 }
 
-static struct opl_operator *opl_operator_alloc(const guint8 *record)
+static struct opl_operator *opl_operator_alloc(const uint8_t *record)
 {
-	struct opl_operator *oper = g_new0(struct opl_operator, 1);
+	struct opl_operator *oper = l_new(struct opl_operator, 1);
 
 	sim_parse_mcc_mnc(record, oper->mcc, oper->mnc);
 	record += 3;
@@ -1071,40 +1067,52 @@ static struct opl_operator *opl_operator_alloc(const guint8 *record)
 }
 
 void sim_eons_add_opl_record(struct sim_eons *eons,
-				const guint8 *contents, int length)
+				const uint8_t *contents, uint16_t length)
 {
 	struct opl_operator *oper;
 
+	if (length < 8)
+		return;
+
 	oper = opl_operator_alloc(contents);
 
-	if (oper->id > eons->pnn_max) {
-		g_free(oper);
+	if (!oper->id || oper->id > eons->pnn_max) {
+		l_free(oper);
 		return;
 	}
 
-	eons->opl_list = g_slist_prepend(eons->opl_list, oper);
-}
-
-void sim_eons_optimize(struct sim_eons *eons)
-{
-	eons->opl_list = g_slist_reverse(eons->opl_list);
+	l_queue_push_tail(eons->opl_list, oper);
 }
 
 void sim_eons_free(struct sim_eons *eons)
 {
-	int i;
+	uint32_t i;
 
 	if (eons == NULL)
 		return;
 
-	for (i = 0; i < eons->pnn_max; i++)
-		pnn_operator_free(eons->pnn_list + i);
+	for (i = 0; i < eons->pnn_max; i++) {
+		struct sim_eons_operator_info *oper = eons->pnn_list + i;
 
-	g_free(eons->pnn_list);
+		l_free(oper->info);
+		l_free(oper->shortname);
+		l_free(oper->longname);
+	}
 
-	g_slist_free_full(eons->opl_list, g_free);
+	l_queue_destroy(eons->opl_list, l_free);
 
-	g_free(eons);
+	l_free(eons);
+}
+
+static bool opl_match_mcc_mnc(const char *opl, const char *s, size_t max)
+{
+	unsigned int i;
+
+	for (i = 0; i < max; i++)
+		if (s[i] != opl[i] && !(opl[i] == 'b' && s[i]))
+			return false;
+
+	return true;
 }
 
 static const struct sim_eons_operator_info *
@@ -1112,46 +1120,32 @@ static const struct sim_eons_operator_info *
 				const char *mcc, const char *mnc,
 				gboolean have_lac, guint16 lac)
 {
-	GSList *l;
+	const struct l_queue_entry *entry;
 	const struct opl_operator *opl;
-	int i;
 
-	for (l = eons->opl_list; l; l = l->next) {
-		opl = l->data;
+	for (entry = l_queue_get_entries(eons->opl_list);
+						entry; entry = entry->next) {
+		opl = entry->data;
 
-		for (i = 0; i < OFONO_MAX_MCC_LENGTH; i++)
-			if (mcc[i] != opl->mcc[i] &&
-					!(opl->mcc[i] == 'b' && mcc[i]))
-				break;
-		if (i < OFONO_MAX_MCC_LENGTH)
+		if (!opl_match_mcc_mnc(opl->mcc, mcc, OFONO_MAX_MCC_LENGTH))
 			continue;
 
-		for (i = 0; i < OFONO_MAX_MNC_LENGTH; i++)
-			if (mnc[i] != opl->mnc[i] &&
-					!(opl->mnc[i] == 'b' && mnc[i]))
-				break;
-		if (i < OFONO_MAX_MNC_LENGTH)
+		if (!opl_match_mcc_mnc(opl->mnc, mnc, OFONO_MAX_MNC_LENGTH))
 			continue;
 
 		if (opl->lac_tac_low == 0 && opl->lac_tac_high == 0xfffe)
-			break;
+			goto found;
 
 		if (have_lac == FALSE)
 			continue;
 
 		if ((lac >= opl->lac_tac_low) && (lac <= opl->lac_tac_high))
-			break;
+			goto found;
 	}
 
-	if (l == NULL)
-		return NULL;
-
-	opl = l->data;
-
-	/* 0 is not a valid record id */
-	if (opl->id == 0)
-		return NULL;
+	return NULL;
 
+found:
 	return &eons->pnn_list[opl->id - 1];
 }
 
diff --git a/src/simutil.h b/src/simutil.h
index 9584d4d9cd62..8c34f9f36488 100644
--- a/src/simutil.h
+++ b/src/simutil.h
@@ -20,6 +20,7 @@
  */
 
 #include <stdbool.h>
+#include <stdint.h>
 
 #define SIM_EFSPN_DC_HOME_PLMN_BIT 0x1
 #define SIM_EFSPN_DC_ROAMING_SPN_BIT 0x2
@@ -299,9 +300,9 @@ enum ber_tlv_data_encoding_type {
 
 struct sim_eons_operator_info {
 	char *longname;
-	gboolean long_ci;
+	bool long_ci;
 	char *shortname;
-	gboolean short_ci;
+	bool short_ci;
 	char *info;
 };
 
@@ -460,18 +461,18 @@ gboolean ber_tlv_builder_recurse_comprehension(struct ber_tlv_builder *builder,
 void ber_tlv_builder_optimize(struct ber_tlv_builder *builder,
 				unsigned char **pdu, unsigned int *len);
 
-struct sim_eons *sim_eons_new(int pnn_records);
-void sim_eons_add_pnn_record(struct sim_eons *eons, int record,
-				const guint8 *tlv, int length);
+struct sim_eons *sim_eons_new(uint32_t pnn_records);
+void sim_eons_add_pnn_record(struct sim_eons *eons, uint32_t record,
+				const uint8_t *tlv, uint16_t length);
 gboolean sim_eons_pnn_is_empty(struct sim_eons *eons);
 void sim_eons_add_opl_record(struct sim_eons *eons,
-				const guint8 *contents, int length);
+				const uint8_t *contents, uint16_t length);
 void sim_eons_optimize(struct sim_eons *eons);
 const struct sim_eons_operator_info *sim_eons_lookup_with_lac(
 						struct sim_eons *eons,
 						const char *mcc,
 						const char *mnc,
-						guint16 lac);
+						uint16_t lac);
 const struct sim_eons_operator_info *sim_eons_lookup(struct sim_eons *eons,
 						const char *mcc,
 						const char *mnc);
diff --git a/unit/test-simutil.c b/unit/test-simutil.c
index 4199991a4d2a..365ef318d937 100644
--- a/unit/test-simutil.c
+++ b/unit/test-simutil.c
@@ -393,7 +393,6 @@ static void test_eons(void)
 	g_assert(!sim_eons_pnn_is_empty(eons_info));
 
 	sim_eons_add_opl_record(eons_info, valid_efopl, sizeof(valid_efopl));
-	sim_eons_optimize(eons_info);
 
 	op_info = sim_eons_lookup(eons_info, "246", "82");
 	g_assert(op_info == NULL);
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH v2 02/14] sim: Simplify SPN management logic
  2024-04-03 16:05 [PATCH v2 01/14] simutil: Convert eons APIs to use ell Denis Kenzior
@ 2024-04-03 16:05 ` Denis Kenzior
  2024-04-03 16:05 ` [PATCH v2 03/14] data: Remove AweSIM entry Denis Kenzior
                   ` (12 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Denis Kenzior @ 2024-04-03 16:05 UTC (permalink / raw)
  To: ofono; +Cc: Denis Kenzior

The current implementation kicks off reading of the SPN only if an spn
watch has been registered.  This made sense at the time since the only
atoms that used spn were netreg and gprs.  Typically they were
initialized in the post_online state, which in effect delayed SPN
reading until that time.

With the introduction of provisioning inside the LTE atom, the spn watch
is always registered for LTE modems (nearly all modems now and going
forward).  Simplify the SPN reading logic by reading it once the sim has
been initialized by kicking off the read procedure inside sim_ready().

While here, remove tracking of cphs_spn_watch, ef_spn_watch and
cphs_spn_short_watch.  All sim file watches are automatically destroyed
once the ofono_sim_context is destroyed.
---
 src/sim.c | 353 +++++++++++++++++++++++-------------------------------
 1 file changed, 153 insertions(+), 200 deletions(-)

diff --git a/src/sim.c b/src/sim.c
index 8a97e87612d9..861cfe826f05 100644
--- a/src/sim.c
+++ b/src/sim.c
@@ -113,9 +113,6 @@ struct ofono_sim {
 	char *spn;
 	char *spn_dc;
 	struct ofono_watchlist *spn_watches;
-	unsigned int ef_spn_watch;
-	unsigned int cphs_spn_watch;
-	unsigned int cphs_spn_short_watch;
 
 	struct sim_fs *simfs;
 	struct sim_fs *simfs_isim;
@@ -139,13 +136,13 @@ struct ofono_sim {
 	GSList *aid_sessions;
 	GSList *aid_list;
 	char *impi;
-	bool reading_spn : 1;
 	bool language_prefs_update : 1;
 	bool fixed_dialing : 1;
 	bool barred_dialing : 1;
 	bool sdn_ready : 1;
 	bool initialized : 1;
 	bool wait_initialized : 1;
+	bool spn_initialized : 1;
 };
 
 struct cached_pin {
@@ -1532,6 +1529,137 @@ static void sim_own_numbers_changed(int id, void *userdata)
 	sim_own_numbers_update(sim);
 }
 
+static void spn_watch_cb(gpointer data, gpointer user_data)
+{
+	struct ofono_watchlist_item *item = data;
+	struct ofono_sim *sim = user_data;
+
+	if (item->notify)
+		((ofono_sim_spn_cb_t) item->notify)(sim->spn, sim->spn_dc,
+							item->notify_data);
+}
+
+static void sim_spn_set(struct ofono_sim *sim, const void *data, int length,
+						const unsigned char *dc)
+{
+	DBusConnection *conn = ofono_dbus_get_connection();
+	const char *path = __ofono_atom_get_path(sim->atom);
+
+	l_free(sim->spn);
+	sim->spn = NULL;
+
+	l_free(sim->spn_dc);
+	sim->spn_dc = NULL;
+
+	if (data == NULL)
+		goto notify;
+
+	/*
+	 * TS 31.102 says:
+	 *
+	 * the string shall use:
+	 *
+	 * - either the SMS default 7-bit coded alphabet as defined in
+	 *   TS 23.038 [5] with bit 8 set to 0. The string shall be left
+	 *   justified. Unused bytes shall be set to 'FF'.
+	 *
+	 * - or one of the UCS2 code options defined in the annex of TS
+	 *   31.101 [11].
+	 *
+	 * 31.101 has no such annex though.  51.101 refers to Annex B of
+	 * itself which is not there either.  11.11 contains the same
+	 * paragraph as 51.101 and has an Annex B which we implement.
+	 */
+	sim->spn = sim_string_to_utf8(data, length);
+	if (sim->spn == NULL) {
+		ofono_error("EFspn read successfully, but couldn't parse");
+		goto notify;
+	}
+
+	if (strlen(sim->spn) == 0) {
+		l_free(sim->spn);
+		sim->spn = NULL;
+		goto notify;
+	}
+
+	if (dc)
+		sim->spn_dc = l_memdup(dc, 1);
+
+notify:
+	sim->spn_initialized = true;
+
+	if (sim->spn)
+		ofono_dbus_signal_property_changed(conn, path,
+						OFONO_SIM_MANAGER_INTERFACE,
+						"ServiceProviderName",
+						DBUS_TYPE_STRING, &sim->spn);
+
+	g_slist_foreach(sim->spn_watches->items, spn_watch_cb, sim);
+}
+
+static void sim_cphs_spn_short_read_cb(int ok, int length, int record,
+					const unsigned char *data,
+					int record_length, void *user_data)
+{
+	struct ofono_sim *sim = user_data;
+
+	if (!ok) {
+		sim_spn_set(sim, NULL, 0, NULL);
+		return;
+	}
+
+	sim_spn_set(sim, data, length, NULL);
+}
+
+static void sim_cphs_spn_read_cb(int ok, int length, int record,
+					const unsigned char *data,
+					int record_length, void *user_data)
+{
+	struct ofono_sim *sim = user_data;
+
+	if (!ok) {
+		if (__ofono_sim_cphs_service_available(sim,
+						SIM_CPHS_SERVICE_SHORT_SPN))
+			ofono_sim_read(sim->context,
+					SIM_EF_CPHS_SPN_SHORT_FILEID,
+					OFONO_SIM_FILE_STRUCTURE_TRANSPARENT,
+					sim_cphs_spn_short_read_cb, sim);
+		else
+			sim_spn_set(sim, NULL, 0, NULL);
+
+		return;
+	}
+
+	sim_spn_set(sim, data, length, NULL);
+}
+
+static void sim_spn_read_cb(int ok, int length, int record,
+				const unsigned char *data,
+				int record_length, void *user_data)
+{
+	struct ofono_sim *sim = user_data;
+
+	if (!ok) {
+		ofono_sim_read(sim->context, SIM_EF_CPHS_SPN_FILEID,
+				OFONO_SIM_FILE_STRUCTURE_TRANSPARENT,
+				sim_cphs_spn_read_cb, sim);
+
+		return;
+	}
+
+	sim_spn_set(sim, data + 1, length - 1, data);
+}
+
+static void sim_spn_changed(int id, void *userdata)
+{
+	struct ofono_sim *sim = userdata;
+
+	sim->spn_initialized = false;
+	ofono_sim_read(sim->context, SIM_EFSPN_FILEID,
+			OFONO_SIM_FILE_STRUCTURE_TRANSPARENT,
+			sim_spn_read_cb, sim);
+}
+
 static void sim_efimg_read_cb(int ok, int length, int record,
 				const unsigned char *data,
 				int record_length, void *userdata)
@@ -1622,6 +1750,18 @@ static void sim_ready(enum ofono_sim_state new_state, void *user)
 	ofono_sim_add_file_watch(sim->context, SIM_EFSDN_FILEID,
 					sim_service_numbers_changed, sim, NULL);
 
+	/* Service Provider Name (EFspn and CPHS equivalents) */
+	sim_spn_changed(SIM_EFSPN_FILEID, sim);
+	ofono_sim_add_file_watch(sim->context, SIM_EFSPN_FILEID,
+					sim_spn_changed, sim, NULL);
+	ofono_sim_add_file_watch(sim->context, SIM_EF_CPHS_SPN_FILEID,
+					sim_spn_changed, sim, NULL);
+
+	if (__ofono_sim_cphs_service_available(sim, SIM_CPHS_SERVICE_SHORT_SPN))
+		ofono_sim_add_file_watch(sim->context,
+					SIM_EF_CPHS_SPN_SHORT_FILEID,
+					sim_spn_changed, sim, NULL);
+
 	ofono_sim_read(sim->context, SIM_EFIMG_FILEID,
 			OFONO_SIM_FILE_STRUCTURE_FIXED, sim_efimg_read_cb, sim);
 	ofono_sim_add_file_watch(sim->context, SIM_EFIMG_FILEID,
@@ -2611,37 +2751,6 @@ static void sim_free_early_state(struct ofono_sim *sim)
 	}
 }
 
-static void sim_spn_close(struct ofono_sim *sim)
-{
-	/*
-	 * We have not initialized SPN logic at all yet, either because
-	 * no netreg / gprs atom has been needed or we have not reached the
-	 * post_sim state
-	 */
-	if (sim->ef_spn_watch == 0)
-		return;
-
-	ofono_sim_remove_file_watch(sim->context, sim->ef_spn_watch);
-	sim->ef_spn_watch = 0;
-
-	ofono_sim_remove_file_watch(sim->context, sim->cphs_spn_watch);
-	sim->cphs_spn_watch = 0;
-
-	if (sim->cphs_spn_short_watch) {
-		ofono_sim_remove_file_watch(sim->context,
-						sim->cphs_spn_short_watch);
-		sim->cphs_spn_short_watch = 0;
-	}
-
-	sim->reading_spn = false;
-
-	l_free(sim->spn);
-	sim->spn = NULL;
-
-	l_free(sim->spn_dc);
-	sim->spn_dc = NULL;
-}
-
 static void aid_session_free(gpointer data)
 {
 	struct ofono_sim_aid_session *session = data;
@@ -2709,7 +2818,14 @@ static void sim_free_main_state(struct ofono_sim *sim)
 	sim->fixed_dialing = false;
 	sim->barred_dialing = false;
 
-	sim_spn_close(sim);
+	/* Service Provider Name related */
+	sim->spn_initialized = false;
+
+	l_free(sim->spn);
+	sim->spn = NULL;
+
+	l_free(sim->spn_dc);
+	sim->spn_dc = NULL;
 
 	if (sim->context) {
 		ofono_sim_context_free(sim->context);
@@ -2929,163 +3045,6 @@ enum ofono_sim_state ofono_sim_get_state(struct ofono_sim *sim)
 	return sim->state;
 }
 
-static void spn_watch_cb(gpointer data, gpointer user_data)
-{
-	struct ofono_watchlist_item *item = data;
-	struct ofono_sim *sim = user_data;
-
-	if (item->notify)
-		((ofono_sim_spn_cb_t) item->notify)(sim->spn, sim->spn_dc,
-							item->notify_data);
-}
-
-static inline void spn_watches_notify(struct ofono_sim *sim)
-{
-	if (sim->spn_watches->items)
-		g_slist_foreach(sim->spn_watches->items, spn_watch_cb, sim);
-
-	sim->reading_spn = false;
-}
-
-static void sim_spn_set(struct ofono_sim *sim, const void *data, int length,
-						const unsigned char *dc)
-{
-	DBusConnection *conn = ofono_dbus_get_connection();
-	const char *path = __ofono_atom_get_path(sim->atom);
-
-	l_free(sim->spn);
-	sim->spn = NULL;
-
-	l_free(sim->spn_dc);
-	sim->spn_dc = NULL;
-
-	if (data == NULL)
-		goto notify;
-
-	/*
-	 * TS 31.102 says:
-	 *
-	 * the string shall use:
-	 *
-	 * - either the SMS default 7-bit coded alphabet as defined in
-	 *   TS 23.038 [5] with bit 8 set to 0. The string shall be left
-	 *   justified. Unused bytes shall be set to 'FF'.
-	 *
-	 * - or one of the UCS2 code options defined in the annex of TS
-	 *   31.101 [11].
-	 *
-	 * 31.101 has no such annex though.  51.101 refers to Annex B of
-	 * itself which is not there either.  11.11 contains the same
-	 * paragraph as 51.101 and has an Annex B which we implement.
-	 */
-	sim->spn = sim_string_to_utf8(data, length);
-	if (sim->spn == NULL) {
-		ofono_error("EFspn read successfully, but couldn't parse");
-		goto notify;
-	}
-
-	if (strlen(sim->spn) == 0) {
-		l_free(sim->spn);
-		sim->spn = NULL;
-		goto notify;
-	}
-
-	if (dc)
-		sim->spn_dc = l_memdup(dc, 1);
-
-notify:
-	if (sim->spn)
-		ofono_dbus_signal_property_changed(conn, path,
-						OFONO_SIM_MANAGER_INTERFACE,
-						"ServiceProviderName",
-						DBUS_TYPE_STRING, &sim->spn);
-
-	spn_watches_notify(sim);
-}
-
-static void sim_cphs_spn_short_read_cb(int ok, int length, int record,
-					const unsigned char *data,
-					int record_length, void *user_data)
-{
-	struct ofono_sim *sim = user_data;
-
-	if (!ok) {
-		sim_spn_set(sim, NULL, 0, NULL);
-		return;
-	}
-
-	sim_spn_set(sim, data, length, NULL);
-}
-
-static void sim_cphs_spn_read_cb(int ok, int length, int record,
-					const unsigned char *data,
-					int record_length, void *user_data)
-{
-	struct ofono_sim *sim = user_data;
-
-	if (!ok) {
-		if (__ofono_sim_cphs_service_available(sim,
-						SIM_CPHS_SERVICE_SHORT_SPN))
-			ofono_sim_read(sim->context,
-					SIM_EF_CPHS_SPN_SHORT_FILEID,
-					OFONO_SIM_FILE_STRUCTURE_TRANSPARENT,
-					sim_cphs_spn_short_read_cb, sim);
-		else
-			sim_spn_set(sim, NULL, 0, NULL);
-
-		return;
-	}
-
-	sim_spn_set(sim, data, length, NULL);
-}
-
-static void sim_spn_read_cb(int ok, int length, int record,
-				const unsigned char *data,
-				int record_length, void *user_data)
-{
-	struct ofono_sim *sim = user_data;
-
-	if (!ok) {
-		ofono_sim_read(sim->context, SIM_EF_CPHS_SPN_FILEID,
-				OFONO_SIM_FILE_STRUCTURE_TRANSPARENT,
-				sim_cphs_spn_read_cb, sim);
-
-		return;
-	}
-
-	sim_spn_set(sim, data + 1, length - 1, data);
-}
-
-static void sim_spn_changed(int id, void *userdata)
-{
-	struct ofono_sim *sim = userdata;
-
-	if (sim->reading_spn)
-		return;
-
-	sim->reading_spn = true;
-	ofono_sim_read(sim->context, SIM_EFSPN_FILEID,
-			OFONO_SIM_FILE_STRUCTURE_TRANSPARENT,
-			sim_spn_read_cb, sim);
-}
-
-static void sim_spn_init(struct ofono_sim *sim)
-{
-	sim->ef_spn_watch = ofono_sim_add_file_watch(sim->context,
-					SIM_EFSPN_FILEID, sim_spn_changed, sim,
-					NULL);
-
-	sim->cphs_spn_watch = ofono_sim_add_file_watch(sim->context,
-					SIM_EF_CPHS_SPN_FILEID,
-					sim_spn_changed, sim, NULL);
-
-	if (__ofono_sim_cphs_service_available(sim,
-						SIM_CPHS_SERVICE_SHORT_SPN))
-		sim->cphs_spn_short_watch = ofono_sim_add_file_watch(
-				sim->context, SIM_EF_CPHS_SPN_SHORT_FILEID,
-				sim_spn_changed, sim, NULL);
-}
-
 ofono_bool_t ofono_sim_add_spn_watch(struct ofono_sim *sim, unsigned int *id,
 					ofono_sim_spn_cb_t cb, void *data,
 					ofono_destroy_func destroy)
@@ -3110,13 +3069,7 @@ ofono_bool_t ofono_sim_add_spn_watch(struct ofono_sim *sim, unsigned int *id,
 
 	*id = watch_id;
 
-	if (sim->ef_spn_watch == 0) {
-		sim_spn_init(sim);
-		sim_spn_changed(0, sim);
-		return TRUE;
-	}
-
-	if (sim->reading_spn)
+	if (!sim->spn_initialized)
 		return TRUE;
 
 	((ofono_sim_spn_cb_t) item->notify)(sim->spn, sim->spn_dc,
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH v2 03/14] data: Remove AweSIM entry
  2024-04-03 16:05 [PATCH v2 01/14] simutil: Convert eons APIs to use ell Denis Kenzior
  2024-04-03 16:05 ` [PATCH v2 02/14] sim: Simplify SPN management logic Denis Kenzior
@ 2024-04-03 16:05 ` Denis Kenzior
  2024-04-03 16:05 ` [PATCH v2 04/14] data: Mark some MVNOs via the "spn" attribute Denis Kenzior
                   ` (11 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Denis Kenzior @ 2024-04-03 16:05 UTC (permalink / raw)
  To: ofono; +Cc: Denis Kenzior

It has the same MCC/MNC and APN settings as AT&T
---
 data/provision.json | 24 ------------------------
 1 file changed, 24 deletions(-)

diff --git a/data/provision.json b/data/provision.json
index 77d5bb977254..6856ce0f0eaf 100644
--- a/data/provision.json
+++ b/data/provision.json
@@ -14425,30 +14425,6 @@
       }
     ]
   },
-  {
-    "name": "AweSIM",
-    "ids": [
-      "310410"
-    ],
-    "apns": [
-      {
-        "name": "AweSIM Internet",
-        "apn": "NXTGENPHONE",
-        "type": [
-          "internet"
-        ]
-      },
-      {
-        "name": "AweSIM MMS",
-        "apn": "NXTGENPHONE",
-        "type": [
-          "mms"
-        ],
-        "mmsc": "http://mmsc.mobile.att.net",
-        "mmsproxy": "proxy.mobile.att.net:80"
-      }
-    ]
-  },
   {
     "name": "Straight Talk",
     "ids": [
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH v2 04/14] data: Mark some MVNOs via the "spn" attribute
  2024-04-03 16:05 [PATCH v2 01/14] simutil: Convert eons APIs to use ell Denis Kenzior
  2024-04-03 16:05 ` [PATCH v2 02/14] sim: Simplify SPN management logic Denis Kenzior
  2024-04-03 16:05 ` [PATCH v2 03/14] data: Remove AweSIM entry Denis Kenzior
@ 2024-04-03 16:05 ` Denis Kenzior
  2024-04-03 16:05 ` [PATCH v2 05/14] data: Remove outdated T-mobile settings Denis Kenzior
                   ` (10 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Denis Kenzior @ 2024-04-03 16:05 UTC (permalink / raw)
  To: ofono; +Cc: Denis Kenzior

Most likely these MVNOs use GID1/GID2 or some other magic to be
auto-detected properly.  Mark them using the SPN tag so major US
carriers can be autodetected easier.
---
 data/provision.json | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/data/provision.json b/data/provision.json
index 6856ce0f0eaf..e55ecc6f8d67 100644
--- a/data/provision.json
+++ b/data/provision.json
@@ -14372,6 +14372,7 @@
     "ids": [
       "310240"
     ],
+    "spn": "Ting",
     "apns": [
       {
         "name": "Ting Data",
@@ -14430,6 +14431,7 @@
     "ids": [
       "310410"
     ],
+    "spn": "Tracfone",
     "apns": [
       {
         "apn": "att.mvno",
@@ -14450,6 +14452,7 @@
     "ids": [
       "310260"
     ],
+    "spn": "SpeedTalk",
     "apns": [
       {
         "name": "Cellular (MMS)",
@@ -14480,6 +14483,7 @@
     "ids": [
       "310260"
     ],
+    "spn": "Mint",
     "apns": [
       {
         "name": "mint",
@@ -14495,6 +14499,7 @@
     "ids": [
       "310260"
     ],
+    "spn": "US Mobile",
     "apns": [
       {
         "name": "US Mobile",
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH v2 05/14] data: Remove outdated T-mobile settings
  2024-04-03 16:05 [PATCH v2 01/14] simutil: Convert eons APIs to use ell Denis Kenzior
                   ` (2 preceding siblings ...)
  2024-04-03 16:05 ` [PATCH v2 04/14] data: Mark some MVNOs via the "spn" attribute Denis Kenzior
@ 2024-04-03 16:05 ` Denis Kenzior
  2024-04-03 16:05 ` [PATCH v2 06/14] data: Remove RESELLER settings from AT&T Denis Kenzior
                   ` (9 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Denis Kenzior @ 2024-04-03 16:05 UTC (permalink / raw)
  To: ofono; +Cc: Denis Kenzior

---
 data/provision.json | 35 -----------------------------------
 1 file changed, 35 deletions(-)

diff --git a/data/provision.json b/data/provision.json
index e55ecc6f8d67..80abd78e6507 100644
--- a/data/provision.json
+++ b/data/provision.json
@@ -14229,41 +14229,6 @@
           "internet"
         ]
       },
-      {
-        "name": "Internet/WebConnect",
-        "apn": "epc.tmobile.com",
-        "type": [
-          "internet"
-        ]
-      },
-      {
-        "name": "Web2Go/t-zones",
-        "apn": "wap.voicestream.com",
-        "type": [
-          "internet"
-        ]
-      },
-      {
-        "name": "Internet (old)",
-        "apn": "internet2.voicestream.com",
-        "type": [
-          "internet"
-        ]
-      },
-      {
-        "name": "Internet with VPN (old)",
-        "apn": "internet3.voicestream.com",
-        "type": [
-          "internet"
-        ]
-      },
-      {
-        "name": "Broadband",
-        "apn": "mobilenet",
-        "type": [
-          "internet"
-        ]
-      },
       {
         "name": "IoT",
         "apn": "iot.t-mobile.com",
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH v2 06/14] data: Remove RESELLER settings from AT&T
  2024-04-03 16:05 [PATCH v2 01/14] simutil: Convert eons APIs to use ell Denis Kenzior
                   ` (3 preceding siblings ...)
  2024-04-03 16:05 ` [PATCH v2 05/14] data: Remove outdated T-mobile settings Denis Kenzior
@ 2024-04-03 16:05 ` Denis Kenzior
  2024-04-03 16:05 ` [PATCH v2 07/14] provisiontool: Add support for context tags Denis Kenzior
                   ` (8 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Denis Kenzior @ 2024-04-03 16:05 UTC (permalink / raw)
  To: ofono; +Cc: Denis Kenzior

This seems to be yet another MVNO, remove it for now.
---
 data/provision.json | 10 ----------
 1 file changed, 10 deletions(-)

diff --git a/data/provision.json b/data/provision.json
index 80abd78e6507..cef6e34e1ae3 100644
--- a/data/provision.json
+++ b/data/provision.json
@@ -14181,16 +14181,6 @@
         "mmsc": "http://mmsc.mobile.att.net",
         "mmsproxy": "proxy.mobile.att.net:80"
       },
-      {
-        "name": "RESELLER",
-        "apn": "RESELLER",
-        "type": [
-          "internet",
-          "mms"
-        ],
-        "mmsc": "http://mmsc.mobile.att.net",
-        "mmsproxy": "proxy.mobile.att.net:80"
-      },
       {
         "name": "AT&T M2M",
         "apn": "m2m005246.attz",
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH v2 07/14] provisiontool: Add support for context tags
  2024-04-03 16:05 [PATCH v2 01/14] simutil: Convert eons APIs to use ell Denis Kenzior
                   ` (4 preceding siblings ...)
  2024-04-03 16:05 ` [PATCH v2 06/14] data: Remove RESELLER settings from AT&T Denis Kenzior
@ 2024-04-03 16:05 ` Denis Kenzior
  2024-04-03 16:05 ` [PATCH v2 08/14] provisiondb: Add tags_filter support Denis Kenzior
                   ` (7 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Denis Kenzior @ 2024-04-03 16:05 UTC (permalink / raw)
  To: ofono; +Cc: Denis Kenzior

Since this changes the size of the context structure, bump the version
number generated by provisiontool.
---
 tools/provisiontool | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/tools/provisiontool b/tools/provisiontool
index 2067a66a9951..c08b9c4b9712 100755
--- a/tools/provisiontool
+++ b/tools/provisiontool
@@ -24,7 +24,8 @@ class ProviderInfo:
                                   'mmsproxy',
                                   'authentication',
                                   'username',
-                                  'password'] ) }
+                                  'password',
+                                  'tags'] ) }
 
     @classmethod
     def rawimport(cls, entry):
@@ -228,12 +229,13 @@ class ProvisionContext(ctypes.LittleEndianStructure):
         ('username_offset', ctypes.c_uint64),
         ('password_offset', ctypes.c_uint64),
         ('mmsproxy_offset', ctypes.c_uint64),
-        ('mmsc_offset', ctypes.c_uint64)
+        ('mmsc_offset', ctypes.c_uint64),
+        ('tags_offset', ctypes.c_uint64),
     ]
 
     authentication_dict = { 'chap' : 0, 'pap' : 1, 'none' : 2 }
     protocol_dict = { 'ipv4' : 0, 'ipv6' : 1, 'ipv4v6' : 2 }
-    attrs = ['name', 'apn', 'username', 'password', 'mmsproxy', 'mmsc']
+    attrs = ['name', 'apn', 'username', 'password', 'mmsproxy', 'mmsc', 'tags']
 
     @classmethod
     def type_to_context_type(cls, types):
@@ -515,7 +517,7 @@ class ProvisionDatabase(ctypes.LittleEndianStructure):
         visitor.visit(self.tree.root)
         self.tree.traverse(visitor)
 
-        self.version = 1
+        self.version = 2
         self.header_size = ctypes.sizeof(ProvisionDatabase)
         self.file_size = self.header_size
         self.node_struct_size = ctypes.sizeof(ProvisionNode)
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH v2 08/14] provisiondb: Add tags_filter support
  2024-04-03 16:05 [PATCH v2 01/14] simutil: Convert eons APIs to use ell Denis Kenzior
                   ` (5 preceding siblings ...)
  2024-04-03 16:05 ` [PATCH v2 07/14] provisiontool: Add support for context tags Denis Kenzior
@ 2024-04-03 16:05 ` Denis Kenzior
  2024-04-03 16:05 ` [PATCH v2 09/14] tools: lookup-apn: add support for optional tags filter Denis Kenzior
                   ` (6 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Denis Kenzior @ 2024-04-03 16:05 UTC (permalink / raw)
  To: ofono; +Cc: Denis Kenzior

Also update unit tests and other users of provisiondb APIs due to the
API change.
---
 src/provision.c       |  3 ++-
 src/provisiondb.c     | 54 ++++++++++++++++++++++++++++++++++---------
 src/provisiondb.h     |  2 ++
 tools/lookup-apn.c    |  2 +-
 unit/test-provision.c | 15 +++++++-----
 5 files changed, 57 insertions(+), 19 deletions(-)

diff --git a/src/provision.c b/src/provision.c
index a2dfcf6cde5a..22413d2ccde6 100644
--- a/src/provision.c
+++ b/src/provision.c
@@ -32,7 +32,8 @@ bool __ofono_provision_get_settings(const char *mcc,
 	if (mcc == NULL || strlen(mcc) == 0 || mnc == NULL || strlen(mnc) == 0)
 		return false;
 
-	r = provision_db_lookup(pdb, mcc, mnc, spn, &contexts, &n_contexts);
+	r = provision_db_lookup(pdb, mcc, mnc, spn, NULL,
+					&contexts, &n_contexts);
 	if (r < 0)
 		return false;
 
diff --git a/src/provisiondb.c b/src/provisiondb.c
index 53305eab0594..6a913d8d1540 100644
--- a/src/provisiondb.c
+++ b/src/provisiondb.c
@@ -69,6 +69,7 @@ struct context {
 	__le64 password_offset;
 	__le64 mmsproxy_offset;
 	__le64 mmsc_offset;
+	__le64 tags_offset;
 } __attribute__((packed));
 
 struct provision_db {
@@ -218,7 +219,25 @@ static int __get_string(struct provision_db *pdb, uint64_t offset,
 	return 0;
 }
 
+static bool tags_match(char **tags_filter, const char *tags)
+{
+	_auto_(l_strv_free) char **split_tags = 0;
+	unsigned int i;
+
+	if (!tags_filter || !tags)
+		return true;
+
+	split_tags = l_strsplit(tags, ',');
+
+	for (i = 0; tags_filter[i]; i++)
+		if (l_strv_contains(split_tags, tags_filter[i]))
+			return true;
+
+	return false;
+}
+
 static int __get_contexts(struct provision_db *pdb, uint64_t offset,
+				char **tags_filter,
 				struct provision_db_entry **contexts,
 				size_t *n_contexts)
 {
@@ -227,6 +246,7 @@ static int __get_contexts(struct provision_db *pdb, uint64_t offset,
 	uint64_t i;
 	struct provision_db_entry *ret;
 	int r;
+	uint64_t n_matched = 0;
 
 	if (offset + sizeof(__le64) >= pdb->contexts_size)
 		return -EPROTO;
@@ -242,43 +262,54 @@ static int __get_contexts(struct provision_db *pdb, uint64_t offset,
 	for (i = 0; i < num; i++, offset += sizeof(struct context)) {
 		struct context *context = start + offset;
 
-		ret[i].type = L_LE32_TO_CPU(context->type);
-		ret[i].proto = L_LE32_TO_CPU(context->protocol);
-		ret[i].auth_method = L_LE32_TO_CPU(context->authentication);
+		r = __get_string(pdb, L_LE64_TO_CPU(context->tags_offset),
+					&ret[n_matched].tags);
+		if (r < 0)
+			goto fail;
+
+		if (!tags_match(tags_filter, ret[n_matched].tags))
+			continue;
+
+		ret[n_matched].type = L_LE32_TO_CPU(context->type);
+		ret[n_matched].proto = L_LE32_TO_CPU(context->protocol);
+		ret[n_matched].auth_method =
+			L_LE32_TO_CPU(context->authentication);
 
 		r = __get_string(pdb, L_LE64_TO_CPU(context->name_offset),
-					&ret[i].name);
+					&ret[n_matched].name);
 		if (r < 0)
 			goto fail;
 
 		r = __get_string(pdb, L_LE64_TO_CPU(context->apn_offset),
-					&ret[i].apn);
+					&ret[n_matched].apn);
 		if (r < 0)
 			goto fail;
 
 		r = __get_string(pdb, L_LE64_TO_CPU(context->username_offset),
-					&ret[i].username);
+					&ret[n_matched].username);
 		if (r < 0)
 			goto fail;
 
 		r = __get_string(pdb, L_LE64_TO_CPU(context->password_offset),
-					&ret[i].password);
+					&ret[n_matched].password);
 		if (r < 0)
 			goto fail;
 
 		r = __get_string(pdb, L_LE64_TO_CPU(context->mmsproxy_offset),
-					&ret[i].message_proxy);
+					&ret[n_matched].message_proxy);
 		if (r < 0)
 			goto fail;
 
 		r = __get_string(pdb, L_LE64_TO_CPU(context->mmsc_offset),
-					&ret[i].message_center);
+					&ret[n_matched].message_center);
 		if (r < 0)
 			goto fail;
+
+		n_matched += 1;
 	}
 
 	*contexts = ret;
-	*n_contexts = num;
+	*n_contexts = n_matched;
 	return 0;
 
 fail:
@@ -374,6 +405,7 @@ static int key_from_mcc_mnc(const char *mcc, const char *mnc, uint32_t *key)
 
 int provision_db_lookup(struct provision_db *pdb,
 			const char *mcc, const char *mnc, const char *match_spn,
+			char **tags_filter,
 			struct provision_db_entry **items, size_t *n_items)
 {
 	int r;
@@ -436,5 +468,5 @@ int provision_db_lookup(struct provision_db *pdb,
 		return -ENOENT;
 
 	return __get_contexts(pdb, L_LE64_TO_CPU(found->context_offset),
-				items, n_items);
+				tags_filter, items, n_items);
 }
diff --git a/src/provisiondb.h b/src/provisiondb.h
index ee203c6154af..2c70bc15cb26 100644
--- a/src/provisiondb.h
+++ b/src/provisiondb.h
@@ -19,6 +19,7 @@ struct provision_db_entry {
 	enum ofono_gprs_auth_method auth_method;
 	const char *message_proxy;
 	const char *message_center;
+	const char *tags;
 };
 
 struct provision_db *provision_db_new(const char *pathname);
@@ -27,5 +28,6 @@ void provision_db_free(struct provision_db *pdb);
 
 int provision_db_lookup(struct provision_db *pdb,
 			const char *mcc, const char *mnc, const char *spn,
+			char **tags_filter,
 			struct provision_db_entry **items,
 			size_t *n_items);
diff --git a/tools/lookup-apn.c b/tools/lookup-apn.c
index 34d689a434cf..abb95f38f470 100644
--- a/tools/lookup-apn.c
+++ b/tools/lookup-apn.c
@@ -50,7 +50,7 @@ static int lookup_apn(const char *match_mcc, const char *match_mnc,
 	fprintf(stdout, "Searching for info for network: %s%s, spn: %s\n",
 			match_mcc, match_mnc, match_spn ? match_spn : "<None>");
 
-	r = provision_db_lookup(pdb, match_mcc, match_mnc, match_spn,
+	r = provision_db_lookup(pdb, match_mcc, match_mnc, match_spn, NULL,
 					&contexts, &n_contexts);
 	if (r < 0) {
 		fprintf(stderr, "Unable to lookup: %s\n", strerror(-r));
diff --git a/unit/test-provision.c b/unit/test-provision.c
index 9c3dfad43a62..b80f4d80fa0e 100644
--- a/unit/test-provision.c
+++ b/unit/test-provision.c
@@ -27,7 +27,8 @@ static void null_provision_db(const void *data)
 	size_t n_items;
 	int r;
 
-	r = provision_db_lookup(NULL, "123", "345", NULL, &items, &n_items);
+	r = provision_db_lookup(NULL, "123", "345", NULL, NULL,
+				&items, &n_items);
 	assert(r == -EBADF);
 }
 
@@ -37,16 +38,18 @@ static void invalid_mcc_mnc(const void *data)
 	size_t n_items;
 	int r;
 
-	r = provision_db_lookup(pdb, "3444", "33", NULL, &items, &n_items);
+	r = provision_db_lookup(pdb, "3444", "33", NULL, NULL,
+				&items, &n_items);
 	assert(r == -EINVAL);
 
-	r = provision_db_lookup(pdb, "3ab", "33", NULL, &items, &n_items);
+	r = provision_db_lookup(pdb, "3ab", "33", NULL, NULL, &items, &n_items);
 	assert(r == -EINVAL);
 
-	r = provision_db_lookup(pdb, "333", "3", NULL, &items, &n_items);
+	r = provision_db_lookup(pdb, "333", "3", NULL, NULL, &items, &n_items);
 	assert(r == -EINVAL);
 
-	r = provision_db_lookup(pdb, "333", "3334", NULL, &items, &n_items);
+	r = provision_db_lookup(pdb, "333", "3334", NULL, NULL,
+			&items, &n_items);
 	assert(r == -EINVAL);
 }
 
@@ -225,7 +228,7 @@ static void provision_lookup(const void *data)
 	size_t i;
 	int r;
 
-	r = provision_db_lookup(pdb, test->mcc, test->mnc, test->spn,
+	r = provision_db_lookup(pdb, test->mcc, test->mnc, test->spn, NULL,
 					&items, &n_items);
 	assert(r == test->result);
 
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH v2 09/14] tools: lookup-apn: add support for optional tags filter
  2024-04-03 16:05 [PATCH v2 01/14] simutil: Convert eons APIs to use ell Denis Kenzior
                   ` (6 preceding siblings ...)
  2024-04-03 16:05 ` [PATCH v2 08/14] provisiondb: Add tags_filter support Denis Kenzior
@ 2024-04-03 16:05 ` Denis Kenzior
  2024-04-03 16:05 ` [PATCH v2 10/14] data: Add tags for AT&T and T-Mobile contexts Denis Kenzior
                   ` (5 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Denis Kenzior @ 2024-04-03 16:05 UTC (permalink / raw)
  To: ofono; +Cc: Denis Kenzior

---
 tools/lookup-apn.c | 25 ++++++++++++++++++-------
 1 file changed, 18 insertions(+), 7 deletions(-)

diff --git a/tools/lookup-apn.c b/tools/lookup-apn.c
index abb95f38f470..e4fc79cd7819 100644
--- a/tools/lookup-apn.c
+++ b/tools/lookup-apn.c
@@ -26,7 +26,7 @@
 static const char *option_file;
 
 static int lookup_apn(const char *match_mcc, const char *match_mnc,
-							const char *match_spn)
+			const char *match_spn, char **tags_filter)
 {
 	struct provision_db *pdb;
 	struct provision_db_entry *contexts;
@@ -50,7 +50,8 @@ static int lookup_apn(const char *match_mcc, const char *match_mnc,
 	fprintf(stdout, "Searching for info for network: %s%s, spn: %s\n",
 			match_mcc, match_mnc, match_spn ? match_spn : "<None>");
 
-	r = provision_db_lookup(pdb, match_mcc, match_mnc, match_spn, NULL,
+	r = provision_db_lookup(pdb, match_mcc, match_mnc,
+					match_spn, tags_filter,
 					&contexts, &n_contexts);
 	if (r < 0) {
 		fprintf(stderr, "Unable to lookup: %s\n", strerror(-r));
@@ -78,6 +79,8 @@ static int lookup_apn(const char *match_mcc, const char *match_mnc,
 			fprintf(stdout, "Message Center: %s\n",
 							ap->message_center);
 		}
+
+		fprintf(stdout, "Tags: %s\n", ap->tags);
 	}
 
 	l_free(contexts);
@@ -92,22 +95,26 @@ static void usage(void)
 	printf("lookup-apn\nUsage:\n");
 	printf("lookup-apn [options] <mcc> <mnc> [spn]\n");
 	printf("Options:\n"
-			"\t-v, --version	Show version\n"
-			"\t-f, --file		Provision DB file to use\n"
-			"\t-h, --help		Show help options\n");
+		"\t-v, --version	Show version\n"
+		"\t-f, --file		Provision DB file to use\n"
+		"\t-t, --tags		Comma separated tag filter\n"
+		"\t-h, --help		Show help options\n");
 }
 
 static const struct option options[] = {
 	{ "version",	no_argument,		NULL, 'v' },
 	{ "help",	no_argument,		NULL, 'h' },
 	{ "file",	required_argument,	NULL, 'f' },
+	{ "tags",	required_argument,	NULL, 't' },
 	{ },
 };
 
 int main(int argc, char **argv)
 {
+	_auto_(l_strv_free) char **tags_filter = NULL;
+
 	for (;;) {
-		int opt = getopt_long(argc, argv, "f:vh", options, NULL);
+		int opt = getopt_long(argc, argv, "f:t:vh", options, NULL);
 
 		if (opt < 0)
 			break;
@@ -116,6 +123,9 @@ int main(int argc, char **argv)
 		case 'f':
 			option_file = optarg;
 			break;
+		case 't':
+			tags_filter = l_strsplit(optarg, ',');
+			break;
 		case 'v':
 			printf("%s\n", VERSION);
 			return EXIT_SUCCESS;
@@ -138,5 +148,6 @@ int main(int argc, char **argv)
 	}
 
 	return lookup_apn(argv[optind], argv[optind + 1],
-			argc - optind == 3 ? argv[optind + 2] : NULL);
+				argc - optind == 3 ? argv[optind + 2] : NULL,
+				tags_filter);
 }
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH v2 10/14] data: Add tags for AT&T and T-Mobile contexts
  2024-04-03 16:05 [PATCH v2 01/14] simutil: Convert eons APIs to use ell Denis Kenzior
                   ` (7 preceding siblings ...)
  2024-04-03 16:05 ` [PATCH v2 09/14] tools: lookup-apn: add support for optional tags filter Denis Kenzior
@ 2024-04-03 16:05 ` Denis Kenzior
  2024-04-03 16:05 ` [PATCH v2 11/14] ofono: Add support for ofono main.conf settings Denis Kenzior
                   ` (4 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Denis Kenzior @ 2024-04-03 16:05 UTC (permalink / raw)
  To: ofono; +Cc: Denis Kenzior

AT&T uses several APNs, one for lte/4g devices, one for 5G capable
devices and one for M2M.  Use the newly introduced tags field to tag
them appropriately.

Similarly, for T-mobile, add "iot" tag to the iot specific APN
configuration.
---
 data/provision.json | 18 ++++++++++++------
 1 file changed, 12 insertions(+), 6 deletions(-)

diff --git a/data/provision.json b/data/provision.json
index cef6e34e1ae3..434bfd8d8f7b 100644
--- a/data/provision.json
+++ b/data/provision.json
@@ -14169,7 +14169,8 @@
           "mms"
         ],
         "mmsc": "http://mmsc.mobile.att.net",
-        "mmsproxy": "proxy.mobile.att.net:80"
+        "mmsproxy": "proxy.mobile.att.net:80",
+        "tags": "lte"
       },
       {
         "name": "ENHANCEDPHONE",
@@ -14179,7 +14180,8 @@
           "mms"
         ],
         "mmsc": "http://mmsc.mobile.att.net",
-        "mmsproxy": "proxy.mobile.att.net:80"
+        "mmsproxy": "proxy.mobile.att.net:80",
+        "tags": "5g"
       },
       {
         "name": "AT&T M2M",
@@ -14187,7 +14189,8 @@
         "type": [
           "internet",
           "ia"
-        ]
+        ],
+        "tags": "m2m"
       }
     ]
   },
@@ -14216,8 +14219,10 @@
         "name": "T-Mobile LTE",
         "apn": "fast.t-mobile.com",
         "type": [
-          "internet"
-        ]
+          "internet",
+          "ia"
+        ],
+        "tags": "lte,5g"
       },
       {
         "name": "IoT",
@@ -14225,7 +14230,8 @@
         "type": [
           "internet",
           "ia"
-        ]
+        ],
+        "tags": "iot"
       }
     ]
   },
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH v2 11/14] ofono: Add support for ofono main.conf settings
  2024-04-03 16:05 [PATCH v2 01/14] simutil: Convert eons APIs to use ell Denis Kenzior
                   ` (8 preceding siblings ...)
  2024-04-03 16:05 ` [PATCH v2 10/14] data: Add tags for AT&T and T-Mobile contexts Denis Kenzior
@ 2024-04-03 16:05 ` Denis Kenzior
  2024-04-03 16:05 ` [PATCH v2 12/14] provision: Add support for provision filter tags Denis Kenzior
                   ` (3 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Denis Kenzior @ 2024-04-03 16:05 UTC (permalink / raw)
  To: ofono; +Cc: Denis Kenzior

It would be useful to support some oFono wide configuration settings
that can be configured for the system.  Introduce a new
__ofono_get_config() function that will obtain the parsed settings file
as a pointer to l_settings.  The settings will be parsed from the
configuration directory set using CONFIGURATION_DIRECTORY environment
variable, or the default CONFIGDIR variable set during
configuration/compilation.
---
 src/main.c  | 32 ++++++++++++++++++++++++++++++++
 src/ofono.h |  1 +
 2 files changed, 33 insertions(+)

diff --git a/src/main.c b/src/main.c
index 141853eef8ae..6dd073b4f31a 100644
--- a/src/main.c
+++ b/src/main.c
@@ -39,6 +39,12 @@
 #define SHUTDOWN_GRACE_SECONDS 10
 
 static GMainLoop *event_loop;
+static struct l_settings *ofono_config;
+
+const struct l_settings *__ofono_get_config(void)
+{
+	return ofono_config;
+}
 
 void __ofono_exit(void)
 {
@@ -204,6 +210,9 @@ int main(int argc, char **argv)
 	DBusError error;
 	guint signal;
 	struct ell_event_source *source;
+	const char *config_dir;
+	char **config_dirs;
+	unsigned int i;
 
 	context = g_option_context_new(NULL);
 	g_option_context_add_main_entries(context, options, NULL);
@@ -254,6 +263,27 @@ int main(int argc, char **argv)
 
 	__ofono_log_init(argv[0], option_debug, option_detach);
 
+	config_dir = getenv("CONFIGURATION_DIRECTORY");
+	if (!config_dir)
+		config_dir = CONFIGDIR;
+
+	l_debug("Using configuration directory: %s", config_dir);
+	config_dirs = l_strsplit(config_dir, ':');
+	ofono_config = l_settings_new();
+
+	for (i = 0; config_dirs[i]; i++) {
+		_auto_(l_free) char *path = l_strdup_printf("%s/main.conf",
+								config_dirs[i]);
+
+		if (!l_settings_load_from_file(ofono_config, path))
+			continue;
+
+		l_info("Loaded configuration from %s", path);
+		break;
+	}
+
+	l_strv_free(config_dirs);
+
 	dbus_error_init(&error);
 
 	conn = g_dbus_setup_bus(DBUS_BUS_SYSTEM, OFONO_SERVICE, &error);
@@ -291,6 +321,8 @@ fail_module_init:
 	__ofono_dbus_cleanup();
 	dbus_connection_unref(conn);
 
+	l_settings_free(ofono_config);
+
 cleanup:
 	g_source_remove(signal);
 
diff --git a/src/ofono.h b/src/ofono.h
index 294e90a37c23..80add8351ee7 100644
--- a/src/ofono.h
+++ b/src/ofono.h
@@ -26,6 +26,7 @@
 
 #include <ofono/types.h>
 
+const struct l_settings *__ofono_get_config(void);
 void __ofono_exit(void);
 
 int __ofono_handsfree_audio_manager_init(void);
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH v2 12/14] provision: Add support for provision filter tags
  2024-04-03 16:05 [PATCH v2 01/14] simutil: Convert eons APIs to use ell Denis Kenzior
                   ` (9 preceding siblings ...)
  2024-04-03 16:05 ` [PATCH v2 11/14] ofono: Add support for ofono main.conf settings Denis Kenzior
@ 2024-04-03 16:05 ` Denis Kenzior
  2024-04-03 16:05 ` [PATCH v2 13/14] examples: Fix use after free and resource leaks Denis Kenzior
                   ` (2 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Denis Kenzior @ 2024-04-03 16:05 UTC (permalink / raw)
  To: ofono; +Cc: Denis Kenzior

oFono main.conf configuration file can now contain an entry with group
'Provision' and key 'TagsFilter'.  This entry is treated as a comma
separated list of all tags that are accepted during context
auto-provisioning.  This can help to filter duplicate context entries
from the provisioning database such that context auto-provisioning is
successful without user intervention.
---
 src/provision.c | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/src/provision.c b/src/provision.c
index 22413d2ccde6..0530386f61c1 100644
--- a/src/provision.c
+++ b/src/provision.c
@@ -28,12 +28,17 @@ bool __ofono_provision_get_settings(const char *mcc,
 	int r;
 	size_t i;
 	uint32_t type;
+	_auto_(l_strv_free) char **tags_filter = NULL;
 
 	if (mcc == NULL || strlen(mcc) == 0 || mnc == NULL || strlen(mnc) == 0)
 		return false;
 
-	r = provision_db_lookup(pdb, mcc, mnc, spn, NULL,
-					&contexts, &n_contexts);
+	tags_filter = l_settings_get_string_list(__ofono_get_config(),
+							"Provision",
+							"TagsFilter", ',');
+
+	r = provision_db_lookup(pdb, mcc, mnc, spn, tags_filter,
+						&contexts, &n_contexts);
 	if (r < 0)
 		return false;
 
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH v2 13/14] examples: Fix use after free and resource leaks
  2024-04-03 16:05 [PATCH v2 01/14] simutil: Convert eons APIs to use ell Denis Kenzior
                   ` (10 preceding siblings ...)
  2024-04-03 16:05 ` [PATCH v2 12/14] provision: Add support for provision filter tags Denis Kenzior
@ 2024-04-03 16:05 ` Denis Kenzior
  2024-04-03 16:05 ` [PATCH v2 14/14] unit: Add test cases with tags_filter provided Denis Kenzior
  2024-04-03 17:00 ` [PATCH v2 01/14] simutil: Convert eons APIs to use ell patchwork-bot+ofono
  13 siblings, 0 replies; 15+ messages in thread
From: Denis Kenzior @ 2024-04-03 16:05 UTC (permalink / raw)
  To: ofono; +Cc: Denis Kenzior

The emulator example plugin does not track modem powered watches, and
thus leaks them.  Additionally, the plugin opens ports for both HFP and
DUN emulators.  However, only a single server watch is tracked, leading
to the other watch being leaked.

Since the modem powered watches are not tracked, they are never
unregistered.  This can lead to situations where emulator plugin is
destroyed (and thus all data associated with it is freed) before all
modems have been removed.  When modems are removed subsequently,
registered powered watches will be invoked.  This will result in
use-after-free errors being reported by valgrind.
---
 examples/emulator.c | 151 +++++++++++++++++++++++++++++++-------------
 1 file changed, 108 insertions(+), 43 deletions(-)

diff --git a/examples/emulator.c b/examples/emulator.c
index 5c92bd6659c4..927cf1fa8b0e 100644
--- a/examples/emulator.c
+++ b/examples/emulator.c
@@ -44,8 +44,48 @@
 #define HFP_PORT 12347
 
 static unsigned int modemwatch_id;
-guint server_watch;
-static GList *modems;
+static guint dun_watch;
+static guint hfp_watch;
+static struct l_queue *modem_infos;
+static unsigned int n_powered;
+
+struct modem_info {
+	struct ofono_modem *modem;
+	unsigned int watch_id;
+};
+
+static bool modem_matches(const void *data, const void *user_data)
+{
+	const struct modem_info *info = data;
+
+	return info->modem == user_data;
+}
+
+static void modem_info_free(struct modem_info *info)
+{
+	if (!info)
+		return;
+
+	if (info->watch_id)
+		__ofono_modem_remove_powered_watch(info->modem, info->watch_id);
+
+	l_free(info);
+}
+
+static struct ofono_modem *find_first_powered(void)
+{
+	const struct l_queue_entry *entry;
+
+	for (entry = l_queue_get_entries(modem_infos); entry;
+							entry = entry->next) {
+		struct ofono_modem *modem = entry->data;
+
+		if (ofono_modem_get_powered(modem))
+			return modem;
+	}
+
+	return NULL;
+}
 
 static gboolean on_socket_connected(GIOChannel *chan, GIOCondition cond,
 							gpointer user)
@@ -64,28 +104,35 @@ static gboolean on_socket_connected(GIOChannel *chan, GIOCondition cond,
 		return FALSE;
 
 	/* Pick the first powered modem */
-	modem = modems->data;
+	modem = find_first_powered();
+	if (!modem)
+		goto error;
+
 	DBG("Picked modem %p for emulator", modem);
 
 	em = ofono_emulator_create(modem, GPOINTER_TO_INT(user));
-	if (em == NULL)
-		close(fd);
-	else
-		ofono_emulator_register(em, fd);
+	if (!em)
+		goto error;
+
+	ofono_emulator_register(em, fd);
+	return TRUE;
 
+error:
+	close(fd);
 	return TRUE;
 }
 
-static gboolean create_tcp(short port, enum ofono_emulator_type type)
+static guint create_tcp(short port, enum ofono_emulator_type type)
 {
 	struct sockaddr_in addr;
 	int sk;
 	int reuseaddr = 1;
 	GIOChannel *server;
+	guint server_watch;
 
 	sk = socket(PF_INET, SOCK_STREAM, 0);
 	if (sk < 0)
-		return FALSE;
+		return 0;
 
 	memset(&addr, 0, sizeof(addr));
 
@@ -108,62 +155,77 @@ static gboolean create_tcp(short port, enum ofono_emulator_type type)
 				G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
 				on_socket_connected, GINT_TO_POINTER(type),
 				NULL);
-
 	g_io_channel_unref(server);
 
 	DBG("Created server_watch: %u", server_watch);
-
-	return TRUE;
+	return server_watch;
 
 err:
 	close(sk);
-	return FALSE;
+	return 0;
+}
+
+static void powered_watch_destroy(void *user)
+{
+	struct modem_info *info = user;
+
+	DBG("");
+
+	info->watch_id = 0;
 }
 
 static void powered_watch(struct ofono_modem *modem, gboolean powered,
 				void *user)
 {
+	DBG("powered: %d", powered);
+
 	if (powered == FALSE) {
-		DBG("Removing modem %p from the list", modem);
-		modems = g_list_remove(modems, modem);
-
-		if (modems == NULL && server_watch > 0) {
-			DBG("Removing server watch: %u", server_watch);
-			g_source_remove(server_watch);
-			server_watch = 0;
-		}
-	} else {
-		DBG("Adding modem %p to the list", modem);
-		modems = g_list_append(modems, modem);
-
-		if (modems->next == NULL) {
-			create_tcp(DUN_PORT, OFONO_EMULATOR_TYPE_DUN);
-			create_tcp(HFP_PORT, OFONO_EMULATOR_TYPE_HFP);
-		}
+		n_powered -= 1;
+
+		if (n_powered)
+			return;
+
+		g_source_remove(dun_watch);
+		dun_watch = 0;
+
+		g_source_remove(hfp_watch);
+		hfp_watch = 0;
+
+		return;
 	}
+
+	n_powered += 1;
+
+	if (!dun_watch)
+		dun_watch = create_tcp(DUN_PORT, OFONO_EMULATOR_TYPE_DUN);
+
+	if (!hfp_watch)
+		hfp_watch = create_tcp(HFP_PORT, OFONO_EMULATOR_TYPE_HFP);
 }
 
 static void modem_watch(struct ofono_modem *modem, gboolean added, void *user)
 {
+	struct modem_info *info;
+
 	DBG("modem: %p, added: %d", modem, added);
 
 	if (added == FALSE) {
-		DBG("Removing modem %p from the list", modem);
-		modems = g_list_remove(modems, modem);
+		info = l_queue_remove_if(modem_infos, modem_matches, modem);
+		DBG("Removing modem %p, info %p, from the list", modem, info);
+		modem_info_free(info);
 		return;
 	}
 
-	if (ofono_modem_get_powered(modem) == TRUE) {
-		DBG("Adding modem %p to the list", modem);
-		modems = g_list_append(modems, modem);
+	info = l_new(struct modem_info, 1);
+	info->modem = modem;
+	info->watch_id = __ofono_modem_add_powered_watch(modem, powered_watch,
+							info,
+							powered_watch_destroy);
 
-		if (modems->next == NULL) {
-			create_tcp(DUN_PORT, OFONO_EMULATOR_TYPE_DUN);
-			create_tcp(HFP_PORT, OFONO_EMULATOR_TYPE_HFP);
-		}
-	}
+	l_queue_push_tail(modem_infos, info);
 
-	__ofono_modem_add_powered_watch(modem, powered_watch, NULL, NULL);
+	if (ofono_modem_get_powered(modem) == TRUE)
+		powered_watch(modem, TRUE, NULL);
 }
 
 static void call_modemwatch(struct ofono_modem *modem, void *user)
@@ -175,6 +237,7 @@ static int example_emulator_init(void)
 {
 	DBG("");
 
+	modem_infos = l_queue_new();
 	modemwatch_id = __ofono_modemwatch_add(modem_watch, NULL, NULL);
 
 	__ofono_modem_foreach(call_modemwatch, NULL);
@@ -187,11 +250,13 @@ static void example_emulator_exit(void)
 	DBG("");
 
 	__ofono_modemwatch_remove(modemwatch_id);
+	l_queue_destroy(modem_infos, (l_queue_destroy_func_t) modem_info_free);
 
-	g_list_free(modems);
+	if (dun_watch)
+		g_source_remove(dun_watch);
 
-	if (server_watch)
-		g_source_remove(server_watch);
+	if (hfp_watch)
+		g_source_remove(hfp_watch);
 }
 
 OFONO_PLUGIN_DEFINE(example_emulator, "Example AT Modem Emulator Plugin",
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH v2 14/14] unit: Add test cases with tags_filter provided
  2024-04-03 16:05 [PATCH v2 01/14] simutil: Convert eons APIs to use ell Denis Kenzior
                   ` (11 preceding siblings ...)
  2024-04-03 16:05 ` [PATCH v2 13/14] examples: Fix use after free and resource leaks Denis Kenzior
@ 2024-04-03 16:05 ` Denis Kenzior
  2024-04-03 17:00 ` [PATCH v2 01/14] simutil: Convert eons APIs to use ell patchwork-bot+ofono
  13 siblings, 0 replies; 15+ messages in thread
From: Denis Kenzior @ 2024-04-03 16:05 UTC (permalink / raw)
  To: ofono; +Cc: Denis Kenzior

Replace the XYZ operator contexts with a set of two.  One tagged as
'lte' and one tagged as '5g'.  Add logic to the provision unit test to
support filter tags.
---
 unit/test-provision.c    | 37 +++++++++++++++++++++++++++++++------
 unit/test-provision.json | 10 +++++++++-
 2 files changed, 40 insertions(+), 7 deletions(-)

diff --git a/unit/test-provision.c b/unit/test-provision.c
index b80f4d80fa0e..d251f31b148c 100644
--- a/unit/test-provision.c
+++ b/unit/test-provision.c
@@ -57,6 +57,7 @@ struct provision_test {
 	const char *mcc;
 	const char *mnc;
 	const char *spn;
+	const char *tags;
 	int result;
 	size_t n_items;
 	const struct provision_db_entry *items;
@@ -114,7 +115,7 @@ static const struct provision_db_entry charlie_contexts[] = {
 	},
 };
 
-static const struct provision_db_entry xyz_contexts[] = {
+static const struct provision_db_entry xyz_lte_contexts[] = {
 	{
 		.type = OFONO_GPRS_CONTEXT_TYPE_INTERNET |
 			OFONO_GPRS_CONTEXT_TYPE_IA,
@@ -124,6 +125,16 @@ static const struct provision_db_entry xyz_contexts[] = {
 	}
 };
 
+static const struct provision_db_entry xyz_5g_contexts[] = {
+	{
+		.type = OFONO_GPRS_CONTEXT_TYPE_INTERNET |
+			OFONO_GPRS_CONTEXT_TYPE_IA,
+		.proto = OFONO_GPRS_PROTO_IPV4V6,
+		.apn = "xyz.5g",
+		.auth_method = OFONO_GPRS_AUTH_METHOD_CHAP,
+	}
+};
+
 /* Make sure mccmnc not in the database isn't found */
 static const struct provision_test unknown_mcc_mnc = {
 	.mcc = "994",
@@ -204,13 +215,25 @@ static const struct provision_test lookup_charlie = {
 };
 
 /* Successful lookup of XYZ (MVNO on Charlie) */
-static const struct provision_test lookup_xyz = {
+static const struct provision_test lookup_lte_xyz = {
+	.mcc = "999",
+	.mnc = "11",
+	.spn = "XYZ",
+	.tags = "lte,unused",
+	.result = 0,
+	.n_items = L_ARRAY_SIZE(xyz_lte_contexts),
+	.items = xyz_lte_contexts,
+};
+
+/* Successful lookup of XYZ (MVNO on Charlie) */
+static const struct provision_test lookup_5g_xyz = {
 	.mcc = "999",
 	.mnc = "11",
 	.spn = "XYZ",
+	.tags = "5g",
 	.result = 0,
-	.n_items = L_ARRAY_SIZE(xyz_contexts),
-	.items = xyz_contexts,
+	.n_items = L_ARRAY_SIZE(xyz_5g_contexts),
+	.items = xyz_5g_contexts,
 };
 
 /* No match with for an MCC/MNC present in the DB, but no wildcard entry */
@@ -224,11 +247,12 @@ static void provision_lookup(const void *data)
 {
 	const struct provision_test *test = data;
 	struct provision_db_entry *items;
+	_auto_(l_strv_free) char **tags = l_strsplit(test->tags, ',');
 	size_t n_items;
 	size_t i;
 	int r;
 
-	r = provision_db_lookup(pdb, test->mcc, test->mnc, test->spn, NULL,
+	r = provision_db_lookup(pdb, test->mcc, test->mnc, test->spn, tags,
 					&items, &n_items);
 	assert(r == test->result);
 
@@ -270,7 +294,8 @@ int main(int argc, char **argv)
 	l_test_add("Successful lookup (Alpha)", provision_lookup, &lookup_alpha);
 	l_test_add("Successful lookup (ZYX)", provision_lookup, &lookup_zyx);
 	l_test_add("Exact match (Charlie)", provision_lookup, &lookup_charlie);
-	l_test_add("Exact match (XYZ)", provision_lookup, &lookup_xyz);
+	l_test_add("Exact match (XYZ)", provision_lookup, &lookup_lte_xyz);
+	l_test_add("Exact match (XYZ 5G)", provision_lookup, &lookup_5g_xyz);
 	l_test_add("Exact math (no match)", provision_lookup, &lookup_no_match);
 
 	pdb = provision_db_new(UNITDIR "test-provision.db");
diff --git a/unit/test-provision.json b/unit/test-provision.json
index 61d060ad4def..fcf82a67bb67 100644
--- a/unit/test-provision.json
+++ b/unit/test-provision.json
@@ -85,7 +85,15 @@
         "apn": "xyz",
         "type": [
           "internet", "ia"
-        ]
+        ],
+	"tags": "lte"
+      },
+      {
+        "apn": "xyz.5g",
+        "type": [
+          "internet", "ia"
+        ],
+	"tags": "5g"
       }
     ]
   }
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* Re: [PATCH v2 01/14] simutil: Convert eons APIs to use ell
  2024-04-03 16:05 [PATCH v2 01/14] simutil: Convert eons APIs to use ell Denis Kenzior
                   ` (12 preceding siblings ...)
  2024-04-03 16:05 ` [PATCH v2 14/14] unit: Add test cases with tags_filter provided Denis Kenzior
@ 2024-04-03 17:00 ` patchwork-bot+ofono
  13 siblings, 0 replies; 15+ messages in thread
From: patchwork-bot+ofono @ 2024-04-03 17:00 UTC (permalink / raw)
  To: Denis Kenzior; +Cc: ofono

Hello:

This series was applied to ofono.git (master)
by Denis Kenzior <denkenz@gmail.com>:

On Wed,  3 Apr 2024 11:05:24 -0500 you wrote:
> While here, also remove sim_eons_optimize() as it is no longer needed.
> The ell queue implementation natively supports pushing to the back of a
> linked list.  Also tighten up some length checks and make 'length'
> arguments unsigned.
> ---
>  src/network.c       |   2 -
>  src/simutil.c       | 116 +++++++++++++++++++++-----------------------
>  src/simutil.h       |  15 +++---
>  unit/test-simutil.c |   1 -
>  4 files changed, 63 insertions(+), 71 deletions(-)

Here is the summary with links:
  - [v2,01/14] simutil: Convert eons APIs to use ell
    https://git.kernel.org/pub/scm/network/ofono/ofono.git/?id=9850e63ef1da
  - [v2,02/14] sim: Simplify SPN management logic
    https://git.kernel.org/pub/scm/network/ofono/ofono.git/?id=4a6c0786bea2
  - [v2,03/14] data: Remove AweSIM entry
    https://git.kernel.org/pub/scm/network/ofono/ofono.git/?id=ec4946390408
  - [v2,04/14] data: Mark some MVNOs via the "spn" attribute
    https://git.kernel.org/pub/scm/network/ofono/ofono.git/?id=b37e70242b4e
  - [v2,05/14] data: Remove outdated T-mobile settings
    https://git.kernel.org/pub/scm/network/ofono/ofono.git/?id=5594561c1f4f
  - [v2,06/14] data: Remove RESELLER settings from AT&T
    https://git.kernel.org/pub/scm/network/ofono/ofono.git/?id=c496380af19e
  - [v2,07/14] provisiontool: Add support for context tags
    https://git.kernel.org/pub/scm/network/ofono/ofono.git/?id=407309cf47f0
  - [v2,08/14] provisiondb: Add tags_filter support
    https://git.kernel.org/pub/scm/network/ofono/ofono.git/?id=61fbfea7e46d
  - [v2,09/14] tools: lookup-apn: add support for optional tags filter
    https://git.kernel.org/pub/scm/network/ofono/ofono.git/?id=bf76c826774f
  - [v2,10/14] data: Add tags for AT&T and T-Mobile contexts
    https://git.kernel.org/pub/scm/network/ofono/ofono.git/?id=5072741ab979
  - [v2,11/14] ofono: Add support for ofono main.conf settings
    (no matching commit)
  - [v2,12/14] provision: Add support for provision filter tags
    https://git.kernel.org/pub/scm/network/ofono/ofono.git/?id=00cc10773680
  - [v2,13/14] examples: Fix use after free and resource leaks
    https://git.kernel.org/pub/scm/network/ofono/ofono.git/?id=64e2380f4b37
  - [v2,14/14] unit: Add test cases with tags_filter provided
    https://git.kernel.org/pub/scm/network/ofono/ofono.git/?id=393b6cc3dcbe

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html



^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2024-04-03 17:00 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-04-03 16:05 [PATCH v2 01/14] simutil: Convert eons APIs to use ell Denis Kenzior
2024-04-03 16:05 ` [PATCH v2 02/14] sim: Simplify SPN management logic Denis Kenzior
2024-04-03 16:05 ` [PATCH v2 03/14] data: Remove AweSIM entry Denis Kenzior
2024-04-03 16:05 ` [PATCH v2 04/14] data: Mark some MVNOs via the "spn" attribute Denis Kenzior
2024-04-03 16:05 ` [PATCH v2 05/14] data: Remove outdated T-mobile settings Denis Kenzior
2024-04-03 16:05 ` [PATCH v2 06/14] data: Remove RESELLER settings from AT&T Denis Kenzior
2024-04-03 16:05 ` [PATCH v2 07/14] provisiontool: Add support for context tags Denis Kenzior
2024-04-03 16:05 ` [PATCH v2 08/14] provisiondb: Add tags_filter support Denis Kenzior
2024-04-03 16:05 ` [PATCH v2 09/14] tools: lookup-apn: add support for optional tags filter Denis Kenzior
2024-04-03 16:05 ` [PATCH v2 10/14] data: Add tags for AT&T and T-Mobile contexts Denis Kenzior
2024-04-03 16:05 ` [PATCH v2 11/14] ofono: Add support for ofono main.conf settings Denis Kenzior
2024-04-03 16:05 ` [PATCH v2 12/14] provision: Add support for provision filter tags Denis Kenzior
2024-04-03 16:05 ` [PATCH v2 13/14] examples: Fix use after free and resource leaks Denis Kenzior
2024-04-03 16:05 ` [PATCH v2 14/14] unit: Add test cases with tags_filter provided Denis Kenzior
2024-04-03 17:00 ` [PATCH v2 01/14] simutil: Convert eons APIs to use ell patchwork-bot+ofono

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).