@@ -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;
@@ -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);
}
@@ -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);
@@ -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));
@@ -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);