2019-03-03 18:02:38 +00:00
|
|
|
#pragma once
|
|
|
|
#include <stdint.h>
|
|
|
|
#include <stdbool.h>
|
|
|
|
#include <pthread.h>
|
|
|
|
#include <osmocom/core/linuxlist.h>
|
|
|
|
|
2019-03-03 19:56:06 +00:00
|
|
|
#define REMSIM_SERVER 1
|
|
|
|
|
2019-03-03 18:02:38 +00:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2019-03-03 19:56:06 +00:00
|
|
|
enum slot_mapping_state {
|
|
|
|
SLMAP_S_NEW, /* created; not yet sent to bankd */
|
|
|
|
SLMAP_S_UNACKNOWLEDGED, /* created + sent to bankd but not yet acknowledge by bankd */
|
|
|
|
SLMAP_S_ACTIVE, /* fully active map; acknowledged by bankd */
|
2019-03-06 15:05:20 +00:00
|
|
|
SLMAP_S_DELETE_REQ, /* fully active map; REST has requested deletion */
|
|
|
|
SLMAP_S_DELETING, /* RSPRO has issued Remove to bankd, but bankd hasn't confirmed yet */
|
2019-03-03 19:56:06 +00:00
|
|
|
};
|
|
|
|
extern const struct value_string slot_map_state_name[];
|
|
|
|
static inline const char *slotmap_state_name(enum slot_mapping_state st)
|
|
|
|
{
|
|
|
|
return get_value_string(slot_map_state_name, st);
|
|
|
|
}
|
|
|
|
|
2019-03-03 18:02:38 +00:00
|
|
|
/* slot mappings are created / removed by the server */
|
|
|
|
struct slot_mapping {
|
|
|
|
/* global lits of bankd slot mappings */
|
|
|
|
struct llist_head list;
|
2019-03-03 19:56:06 +00:00
|
|
|
struct slotmaps *maps;
|
|
|
|
|
2019-03-03 18:02:38 +00:00
|
|
|
/* slot on bank side */
|
|
|
|
struct bank_slot bank;
|
|
|
|
/* slot on client side */
|
|
|
|
struct client_slot client;
|
2019-03-03 19:56:06 +00:00
|
|
|
|
|
|
|
#ifdef REMSIM_SERVER
|
|
|
|
struct llist_head bank_list;
|
|
|
|
enum slot_mapping_state state;
|
|
|
|
#endif
|
2019-03-03 18:02:38 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/* collection of slot mappings */
|
|
|
|
struct slotmaps {
|
|
|
|
struct llist_head mappings;
|
|
|
|
pthread_rwlock_t rwlock;
|
|
|
|
};
|
|
|
|
|
2019-03-06 15:05:42 +00:00
|
|
|
uint32_t slotmap_get_id(const struct slot_mapping *map);
|
|
|
|
|
2019-03-03 18:02:38 +00:00
|
|
|
/* 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 */
|
2019-03-03 20:54:52 +00:00
|
|
|
struct slot_mapping *slotmap_add(struct slotmaps *maps, const struct bank_slot *bank, const struct client_slot *client);
|
2019-03-03 18:02:38 +00:00
|
|
|
|
|
|
|
/* thread-safe removal of a bank<->client map */
|
|
|
|
void slotmap_del(struct slotmaps *maps, struct slot_mapping *map);
|
2019-03-07 09:08:25 +00:00
|
|
|
void _slotmap_del(struct slotmaps *maps, struct slot_mapping *map);
|
2019-03-03 18:02:38 +00:00
|
|
|
|
2019-12-04 18:51:32 +00:00
|
|
|
/* thread-safe removal of all bank<->client maps */
|
|
|
|
void slotmap_del_all(struct slotmaps *maps);
|
|
|
|
|
2019-03-03 18:02:38 +00:00
|
|
|
/* initialize the entire map collection */
|
|
|
|
struct slotmaps *slotmap_init(void *ctx);
|
2019-03-03 19:56:06 +00:00
|
|
|
|
2019-03-31 13:13:29 +00:00
|
|
|
#ifdef SLOTMAP_DEBUG
|
2019-03-07 20:14:47 +00:00
|
|
|
#define slotmaps_rdlock(maps) do { \
|
|
|
|
printf("%s:%u = slotmap_rdlock()\n", __FILE__, __LINE__); \
|
|
|
|
pthread_rwlock_rdlock(&(maps)->rwlock); \
|
|
|
|
} while (0)
|
|
|
|
|
|
|
|
#define slotmaps_wrlock(maps) do { \
|
|
|
|
printf("%s:%u = slotmap_wrlock()\n", __FILE__, __LINE__); \
|
|
|
|
pthread_rwlock_wrlock(&(maps)->rwlock); \
|
|
|
|
} while (0)
|
|
|
|
|
|
|
|
#define slotmaps_unlock(maps) do { \
|
|
|
|
printf("%s:%u = slotmap_unlock()\n", __FILE__, __LINE__); \
|
|
|
|
pthread_rwlock_unlock(&(maps)->rwlock); \
|
|
|
|
} while (0)
|
2019-03-31 13:13:29 +00:00
|
|
|
#else
|
|
|
|
#define slotmaps_rdlock(maps) pthread_rwlock_rdlock(&(maps)->rwlock)
|
|
|
|
#define slotmaps_wrlock(maps) pthread_rwlock_wrlock(&(maps)->rwlock)
|
|
|
|
#define slotmaps_unlock(maps) pthread_rwlock_unlock(&(maps)->rwlock)
|
|
|
|
#endif
|
2019-03-07 20:14:47 +00:00
|
|
|
|
|
|
|
|
2019-03-03 19:56:06 +00:00
|
|
|
#ifdef REMSIM_SERVER
|
2019-03-07 20:01:38 +00:00
|
|
|
void _Slotmap_state_change(struct slot_mapping *map, enum slot_mapping_state new_state,
|
|
|
|
struct llist_head *new_bank_list, const char *file, int line);
|
2019-03-03 19:56:06 +00:00
|
|
|
/* thread-safe way to change the state of given slot map */
|
2019-03-07 20:01:38 +00:00
|
|
|
void Slotmap_state_change(struct slot_mapping *map, enum slot_mapping_state new_state,
|
|
|
|
struct llist_head *new_bank_list, const char *file, int line);
|
|
|
|
#define _slotmap_state_change(map, state, list) \
|
|
|
|
_Slotmap_state_change(map, state, list, __FILE__, __LINE__)
|
|
|
|
#define slotmap_state_change(map, state, list) \
|
|
|
|
Slotmap_state_change(map, state, list, __FILE__, __LINE__)
|
2019-03-03 19:56:06 +00:00
|
|
|
#endif
|