generalize slotmap to make use of it outside of bankd
Change-Id: I0ca7feaa38dfd0468814ef5a1eff997ce854cedf
diff --git a/src/Makefile.am b/src/Makefile.am
index 5f0d846..a44906b 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -12,7 +12,7 @@
rspro/libosmo-asn1-rspro.la
libosmo_rspro_la_SOURCES = rspro_util.c
-noinst_HEADERS = debug.h bankd.h client.h internal.h rspro_util.h \
+noinst_HEADERS = debug.h bankd.h client.h internal.h rspro_util.h slotmap.h \
simtrace2/apdu_dispatch.h \
simtrace2/libusb_util.h \
simtrace2/simtrace2-discovery.h \
@@ -25,7 +25,7 @@
pcsc_test_LDADD = $(OSMOCORE_LIBS) \
$(PCSC_LIBS) libosmo-rspro.la
-remsim_bankd_SOURCES = bankd_slotmap.c bankd_main.c bankd_pcsc.c debug.c
+remsim_bankd_SOURCES = slotmap.c bankd_main.c bankd_pcsc.c debug.c
remsim_bankd_LDADD = $(OSMOCORE_LIBS) $(OSMOGSM_LIBS) \
$(PCSC_LIBS) libosmo-rspro.la -lcsv
diff --git a/src/bankd.h b/src/bankd.h
index 86b75cc..cd97772 100644
--- a/src/bankd.h
+++ b/src/bankd.h
@@ -13,60 +13,11 @@
#include <osmocom/core/linuxlist.h>
#include "rspro_util.h"
+#include "slotmap.h"
#include "debug.h"
struct bankd;
-struct bank_slot {
- uint16_t bank_id;
- uint16_t slot_nr;
-};
-
-static inline bool bank_slot_equals(const struct bank_slot *a, const struct bank_slot *b)
-{
- if (a->bank_id == b->bank_id && a->slot_nr == b->slot_nr)
- return true;
- else
- return false;
-}
-
-struct client_slot {
- uint16_t client_id;
- uint16_t slot_nr;
-};
-
-static inline bool client_slot_equals(const struct client_slot *a, const struct client_slot *b)
-{
- if (a->client_id == b->client_id && a->slot_nr == b->slot_nr)
- return true;
- else
- return false;
-}
-
-/* slot mappings are created / removed by the server */
-struct bankd_slot_mapping {
- /* global lits of bankd slot mappings */
- struct llist_head list;
- /* slot on bank side */
- struct bank_slot bank;
- /* slot on client side */
- struct client_slot client;
-};
-
-/* thread-safe lookup of map by client:slot */
-struct bankd_slot_mapping *bankd_slotmap_by_client(struct bankd *bankd,
- const struct client_slot *client);
-
-/* thread-safe lookup of map by bank:slot */
-struct bankd_slot_mapping *bankd_slotmap_by_bank(struct bankd *bankd, const struct bank_slot *bank);
-
-/* thread-safe creating of a new bank<->client map */
-int bankd_slotmap_add(struct bankd *bankd, const struct bank_slot *bank,
- const struct client_slot *client);
-
-/* thread-safe removal of a bank<->client map */
-void bankd_slotmap_del(struct bankd *bankd, struct bankd_slot_mapping *map);
-
enum bankd_worker_state {
/* just started*/
BW_ST_INIT,
@@ -138,9 +89,8 @@
/* TCP socket at which we are listening */
int accept_fd;
- /* list of slit mappings. only ever modified in main thread! */
- struct llist_head slot_mappings;
- pthread_rwlock_t slot_mappings_rwlock;
+ /* list of slot mappings. only ever modified in main thread! */
+ struct slotmaps *slotmaps;
/* list of bankd_workers. accessed/modified by multiple threads; protected by mutex */
struct llist_head workers;
diff --git a/src/bankd_main.c b/src/bankd_main.c
index fde03cd..ed225a9 100644
--- a/src/bankd_main.c
+++ b/src/bankd_main.c
@@ -47,8 +47,7 @@
asn_debug = 0;
/* intialize members of 'bankd' */
- INIT_LLIST_HEAD(&bankd->slot_mappings);
- pthread_rwlock_init(&bankd->slot_mappings_rwlock, NULL);
+ bankd->slotmaps = slotmap_init(bankd);
INIT_LLIST_HEAD(&bankd->workers);
pthread_mutex_init(&bankd->workers_mutex, NULL);
@@ -71,7 +70,7 @@
int i;
for (i = 0; i < 5; i++) {
bs.slot_nr = cs.slot_nr = i;
- bankd_slotmap_add(bankd, &bs, &cs);
+ slotmap_add(bankd->slotmaps, &bs, &cs);
}
}
}
@@ -304,9 +303,9 @@
/* attempt to obtain slot-map */
static int worker_try_slotmap(struct bankd_worker *worker)
{
- struct bankd_slot_mapping *slmap;
+ struct slot_mapping *slmap;
- slmap = bankd_slotmap_by_client(worker->bankd, &worker->client.clslot);
+ slmap = slotmap_by_client(worker->bankd->slotmaps, &worker->client.clslot);
if (!slmap) {
LOGW(worker, "No slotmap (yet) for client C(%u:%u)\n",
worker->client.clslot.client_id, worker->client.clslot.slot_nr);
diff --git a/src/bankd_slotmap.c b/src/bankd_slotmap.c
deleted file mode 100644
index 116fd69..0000000
--- a/src/bankd_slotmap.c
+++ /dev/null
@@ -1,100 +0,0 @@
-
-#include <stdint.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <errno.h>
-
-#include <pthread.h>
-
-#include <talloc.h>
-
-#include <osmocom/core/linuxlist.h>
-
-#include "bankd.h"
-
-/* thread-safe lookup of map by client:slot */
-struct bankd_slot_mapping *bankd_slotmap_by_client(struct bankd *bankd, const struct client_slot *client)
-{
- struct bankd_slot_mapping *map;
-
- pthread_rwlock_rdlock(&bankd->slot_mappings_rwlock);
- llist_for_each_entry(map, &bankd->slot_mappings, list) {
- if (client_slot_equals(&map->client, client)) {
- pthread_rwlock_unlock(&bankd->slot_mappings_rwlock);
- return map;
- }
- }
- pthread_rwlock_unlock(&bankd->slot_mappings_rwlock);
- return NULL;
-}
-
-/* thread-safe lookup of map by bank:slot */
-struct bankd_slot_mapping *bankd_slotmap_by_bank(struct bankd *bankd, const struct bank_slot *bank)
-{
- struct bankd_slot_mapping *map;
-
- pthread_rwlock_rdlock(&bankd->slot_mappings_rwlock);
- llist_for_each_entry(map, &bankd->slot_mappings, list) {
- if (bank_slot_equals(&map->bank, bank)) {
- pthread_rwlock_unlock(&bankd->slot_mappings_rwlock);
- return map;
- }
- }
- pthread_rwlock_unlock(&bankd->slot_mappings_rwlock);
- return NULL;
-
-}
-
-/* thread-safe creating of a new bank<->client map */
-int bankd_slotmap_add(struct bankd *bankd, const struct bank_slot *bank, const struct client_slot *client)
-{
- struct bankd_slot_mapping *map;
-
- /* We assume a single thread (main thread) will ever update the mappings,
- * and hence we don't have any races by first grabbing + releasing the read
- * lock twice before grabbing the writelock below */
-
- map = bankd_slotmap_by_bank(bankd, bank);
- if (map) {
- fprintf(stderr, "BANKD %u:%u already in use, cannot add new map\n",
- bank->bank_id, bank->slot_nr);
- return -EBUSY;
- }
-
- map = bankd_slotmap_by_client(bankd, client);
- if (map) {
- fprintf(stderr, "CLIENT %u:%u already in use, cannot add new map\n",
- client->client_id, client->slot_nr);
- return -EBUSY;
- }
-
- /* allocate new mapping and add to list of mappings */
- map = talloc_zero(bankd, struct bankd_slot_mapping);
- if (!map)
- return -ENOMEM;
-
- map->bank = *bank;
- map->client = *client;
-
- pthread_rwlock_wrlock(&bankd->slot_mappings_rwlock);
- llist_add_tail(&map->list, &bankd->slot_mappings);
- pthread_rwlock_unlock(&bankd->slot_mappings_rwlock);
-
- printf("Added Slot Map C(%u:%u) <-> B(%u:%u)\n",
- map->client.client_id, map->client.slot_nr, map->bank.bank_id, map->bank.slot_nr);
-
- return 0;
-}
-
-/* thread-safe removal of a bank<->client map */
-void bankd_slotmap_del(struct bankd *bankd, struct bankd_slot_mapping *map)
-{
- printf("Deleting Slot Map C(%u:%u) <-> B(%u:%u)\n",
- map->client.client_id, map->client.slot_nr, map->bank.bank_id, map->bank.slot_nr);
-
- pthread_rwlock_wrlock(&bankd->slot_mappings_rwlock);
- llist_del(&map->list);
- pthread_rwlock_unlock(&bankd->slot_mappings_rwlock);
-
- talloc_free(map);
-}
diff --git a/src/slotmap.c b/src/slotmap.c
new file mode 100644
index 0000000..303f5fd
--- /dev/null
+++ b/src/slotmap.c
@@ -0,0 +1,110 @@
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <errno.h>
+
+#include <pthread.h>
+
+#include <talloc.h>
+
+#include <osmocom/core/linuxlist.h>
+
+#include "slotmap.h"
+
+/* thread-safe lookup of map by client:slot */
+struct slot_mapping *slotmap_by_client(struct slotmaps *maps, const struct client_slot *client)
+{
+ struct slot_mapping *map;
+
+ pthread_rwlock_rdlock(&maps->rwlock);
+ llist_for_each_entry(map, &maps->mappings, list) {
+ if (client_slot_equals(&map->client, client)) {
+ pthread_rwlock_unlock(&maps->rwlock);
+ return map;
+ }
+ }
+ pthread_rwlock_unlock(&maps->rwlock);
+ return NULL;
+}
+
+/* thread-safe lookup of map by bank:slot */
+struct slot_mapping *slotmap_by_bank(struct slotmaps *maps, const struct bank_slot *bank)
+{
+ struct slot_mapping *map;
+
+ pthread_rwlock_rdlock(&maps->rwlock);
+ llist_for_each_entry(map, &maps->mappings, list) {
+ if (bank_slot_equals(&map->bank, bank)) {
+ pthread_rwlock_unlock(&maps->rwlock);
+ return map;
+ }
+ }
+ pthread_rwlock_unlock(&maps->rwlock);
+ return NULL;
+
+}
+
+/* thread-safe creating of a new bank<->client map */
+int slotmap_add(struct slotmaps *maps, const struct bank_slot *bank, const struct client_slot *client)
+{
+ struct slot_mapping *map;
+
+ /* We assume a single thread (main thread) will ever update the mappings,
+ * and hence we don't have any races by first grabbing + releasing the read
+ * lock twice before grabbing the writelock below */
+
+ map = slotmap_by_bank(maps, bank);
+ if (map) {
+ fprintf(stderr, "BANKD %u:%u already in use, cannot add new map\n",
+ bank->bank_id, bank->slot_nr);
+ return -EBUSY;
+ }
+
+ map = slotmap_by_client(maps, client);
+ if (map) {
+ fprintf(stderr, "CLIENT %u:%u already in use, cannot add new map\n",
+ client->client_id, client->slot_nr);
+ return -EBUSY;
+ }
+
+ /* allocate new mapping and add to list of mappings */
+ map = talloc_zero(maps, struct slot_mapping);
+ if (!map)
+ return -ENOMEM;
+
+ map->bank = *bank;
+ map->client = *client;
+
+ pthread_rwlock_wrlock(&maps->rwlock);
+ llist_add_tail(&map->list, &maps->mappings);
+ pthread_rwlock_unlock(&maps->rwlock);
+
+ printf("Added Slot Map C(%u:%u) <-> B(%u:%u)\n",
+ map->client.client_id, map->client.slot_nr, map->bank.bank_id, map->bank.slot_nr);
+
+ return 0;
+}
+
+/* thread-safe removal of a bank<->client map */
+void slotmap_del(struct slotmaps *maps, struct slot_mapping *map)
+{
+ printf("Deleting Slot Map C(%u:%u) <-> B(%u:%u)\n",
+ map->client.client_id, map->client.slot_nr, map->bank.bank_id, map->bank.slot_nr);
+
+ pthread_rwlock_wrlock(&maps->rwlock);
+ llist_del(&map->list);
+ pthread_rwlock_unlock(&maps->rwlock);
+
+ talloc_free(map);
+}
+
+struct slotmaps *slotmap_init(void *ctx)
+{
+ struct slotmaps *sm = talloc_zero(ctx, struct slotmaps);
+
+ INIT_LLIST_HEAD(&sm->mappings);
+ pthread_rwlock_init(&sm->rwlock, NULL);
+
+ return sm;
+}
diff --git a/src/slotmap.h b/src/slotmap.h
new file mode 100644
index 0000000..92eb6f4
--- /dev/null
+++ b/src/slotmap.h
@@ -0,0 +1,62 @@
+#pragma once
+#include <stdint.h>
+#include <stdbool.h>
+#include <pthread.h>
+#include <osmocom/core/linuxlist.h>
+
+struct bank_slot {
+ uint16_t bank_id;
+ uint16_t slot_nr;
+};
+
+static inline bool bank_slot_equals(const struct bank_slot *a, const struct bank_slot *b)
+{
+ if (a->bank_id == b->bank_id && a->slot_nr == b->slot_nr)
+ return true;
+ else
+ return false;
+}
+
+struct client_slot {
+ uint16_t client_id;
+ uint16_t slot_nr;
+};
+
+static inline bool client_slot_equals(const struct client_slot *a, const struct client_slot *b)
+{
+ if (a->client_id == b->client_id && a->slot_nr == b->slot_nr)
+ return true;
+ else
+ return false;
+}
+
+/* slot mappings are created / removed by the server */
+struct slot_mapping {
+ /* global lits of bankd slot mappings */
+ struct llist_head list;
+ /* slot on bank side */
+ struct bank_slot bank;
+ /* slot on client side */
+ struct client_slot client;
+};
+
+/* collection of slot mappings */
+struct slotmaps {
+ struct llist_head mappings;
+ pthread_rwlock_t rwlock;
+};
+
+/* thread-safe lookup of map by client:slot */
+struct slot_mapping *slotmap_by_client(struct slotmaps *maps, const struct client_slot *client);
+
+/* thread-safe lookup of map by bank:slot */
+struct slot_mapping *slotmap_by_bank(struct slotmaps *maps, const struct bank_slot *bank);
+
+/* thread-safe creating of a new bank<->client map */
+int slotmap_add(struct slotmaps *maps, const struct bank_slot *bank, const struct client_slot *client);
+
+/* thread-safe removal of a bank<->client map */
+void slotmap_del(struct slotmaps *maps, struct slot_mapping *map);
+
+/* initialize the entire map collection */
+struct slotmaps *slotmap_init(void *ctx);