generalize slotmap to make use of it outside of bankd
Change-Id: I0ca7feaa38dfd0468814ef5a1eff997ce854cedf
This commit is contained in:
parent
61d98e9f3e
commit
cbd18960e7
|
@ -12,7 +12,7 @@ libosmo_rspro_la_LIBADD = $(OSMOCORE_LIBS) $(OSMOGSM_LIBS) $(OSMOABIS_LIBS) \
|
|||
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_SOURCES = driver_core.c driver_pcsc.c main.c
|
|||
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
|
||||
|
||||
|
|
56
src/bankd.h
56
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 @@ struct bankd {
|
|||
/* 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;
|
||||
|
|
|
@ -47,8 +47,7 @@ static void bankd_init(struct bankd *bankd)
|
|||
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 @@ static void bankd_init(struct bankd *bankd)
|
|||
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 @@ static int worker_send_rspro(struct bankd_worker *worker, RsproPDU_t *pdu)
|
|||
/* 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);
|
||||
|
|
|
@ -10,58 +10,58 @@
|
|||
|
||||
#include <osmocom/core/linuxlist.h>
|
||||
|
||||
#include "bankd.h"
|
||||
#include "slotmap.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 slot_mapping *slotmap_by_client(struct slotmaps *maps, const struct client_slot *client)
|
||||
{
|
||||
struct bankd_slot_mapping *map;
|
||||
struct slot_mapping *map;
|
||||
|
||||
pthread_rwlock_rdlock(&bankd->slot_mappings_rwlock);
|
||||
llist_for_each_entry(map, &bankd->slot_mappings, list) {
|
||||
pthread_rwlock_rdlock(&maps->rwlock);
|
||||
llist_for_each_entry(map, &maps->mappings, list) {
|
||||
if (client_slot_equals(&map->client, client)) {
|
||||
pthread_rwlock_unlock(&bankd->slot_mappings_rwlock);
|
||||
pthread_rwlock_unlock(&maps->rwlock);
|
||||
return map;
|
||||
}
|
||||
}
|
||||
pthread_rwlock_unlock(&bankd->slot_mappings_rwlock);
|
||||
pthread_rwlock_unlock(&maps->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 slot_mapping *slotmap_by_bank(struct slotmaps *maps, const struct bank_slot *bank)
|
||||
{
|
||||
struct bankd_slot_mapping *map;
|
||||
struct slot_mapping *map;
|
||||
|
||||
pthread_rwlock_rdlock(&bankd->slot_mappings_rwlock);
|
||||
llist_for_each_entry(map, &bankd->slot_mappings, list) {
|
||||
pthread_rwlock_rdlock(&maps->rwlock);
|
||||
llist_for_each_entry(map, &maps->mappings, list) {
|
||||
if (bank_slot_equals(&map->bank, bank)) {
|
||||
pthread_rwlock_unlock(&bankd->slot_mappings_rwlock);
|
||||
pthread_rwlock_unlock(&maps->rwlock);
|
||||
return map;
|
||||
}
|
||||
}
|
||||
pthread_rwlock_unlock(&bankd->slot_mappings_rwlock);
|
||||
pthread_rwlock_unlock(&maps->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)
|
||||
int slotmap_add(struct slotmaps *maps, const struct bank_slot *bank, const struct client_slot *client)
|
||||
{
|
||||
struct bankd_slot_mapping *map;
|
||||
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 = bankd_slotmap_by_bank(bankd, bank);
|
||||
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 = bankd_slotmap_by_client(bankd, client);
|
||||
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);
|
||||
|
@ -69,16 +69,16 @@ int bankd_slotmap_add(struct bankd *bankd, const struct bank_slot *bank, const s
|
|||
}
|
||||
|
||||
/* allocate new mapping and add to list of mappings */
|
||||
map = talloc_zero(bankd, struct bankd_slot_mapping);
|
||||
map = talloc_zero(maps, struct 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);
|
||||
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);
|
||||
|
@ -87,14 +87,24 @@ int bankd_slotmap_add(struct bankd *bankd, const struct bank_slot *bank, const s
|
|||
}
|
||||
|
||||
/* thread-safe removal of a bank<->client map */
|
||||
void bankd_slotmap_del(struct bankd *bankd, struct bankd_slot_mapping *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(&bankd->slot_mappings_rwlock);
|
||||
pthread_rwlock_wrlock(&maps->rwlock);
|
||||
llist_del(&map->list);
|
||||
pthread_rwlock_unlock(&bankd->slot_mappings_rwlock);
|
||||
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;
|
||||
}
|
|
@ -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);
|
Loading…
Reference in New Issue