introduce ue_context management
We keep one 'ue_context' structure for every UE that we see a UE REGISTER REQUEST for.
This commit is contained in:
parent
e2e5d4dd53
commit
b534e5c085
61
src/hnbgw.c
61
src/hnbgw.c
|
@ -26,6 +26,7 @@
|
||||||
#include "hnbgw_rua.h"
|
#include "hnbgw_rua.h"
|
||||||
|
|
||||||
static void *tall_hnb_ctx;
|
static void *tall_hnb_ctx;
|
||||||
|
static void *tall_ue_ctx;
|
||||||
void *talloc_asn1_ctx;
|
void *talloc_asn1_ctx;
|
||||||
|
|
||||||
struct hnb_gw g_hnb_gw = {
|
struct hnb_gw g_hnb_gw = {
|
||||||
|
@ -34,6 +35,64 @@ struct hnb_gw g_hnb_gw = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct ue_context *ue_context_by_id(uint32_t id)
|
||||||
|
{
|
||||||
|
struct ue_context *ue;
|
||||||
|
|
||||||
|
llist_for_each_entry(ue, &g_hnb_gw.ue_list, list) {
|
||||||
|
if (ue->context_id == id)
|
||||||
|
return ue;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ue_context *ue_context_by_imsi(const char *imsi)
|
||||||
|
{
|
||||||
|
struct ue_context *ue;
|
||||||
|
|
||||||
|
llist_for_each_entry(ue, &g_hnb_gw.ue_list, list) {
|
||||||
|
if (!strcmp(ue->imsi, imsi))
|
||||||
|
return ue;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t get_next_ue_ctx_id(void)
|
||||||
|
{
|
||||||
|
uint32_t id;
|
||||||
|
|
||||||
|
do {
|
||||||
|
id = g_hnb_gw.next_ue_ctx_id++;
|
||||||
|
} while (ue_context_by_id(id));
|
||||||
|
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ue_context *ue_context_alloc(struct hnb_context *hnb, const char *imsi)
|
||||||
|
{
|
||||||
|
struct ue_context *ue;
|
||||||
|
|
||||||
|
ue = talloc_zero(tall_hnb_ctx, struct ue_context);
|
||||||
|
if (!ue)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
ue->hnb = hnb;
|
||||||
|
strncpy(ue->imsi, imsi, sizeof(ue->imsi));
|
||||||
|
ue->context_id = get_next_ue_ctx_id();
|
||||||
|
llist_add_tail(&g_hnb_gw.ue_list, &ue->list);
|
||||||
|
|
||||||
|
return ue;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ue_context_free(struct ue_context *ue)
|
||||||
|
{
|
||||||
|
llist_del(&ue->list);
|
||||||
|
talloc_free(ue);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static int hnb_read_cb(struct osmo_fd *fd)
|
static int hnb_read_cb(struct osmo_fd *fd)
|
||||||
{
|
{
|
||||||
struct hnb_context *hnb = fd->data;
|
struct hnb_context *hnb = fd->data;
|
||||||
|
@ -180,12 +239,14 @@ int main(int argc, char **argv)
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
tall_hnb_ctx = talloc_named_const(NULL, 0, "hnb_context");
|
tall_hnb_ctx = talloc_named_const(NULL, 0, "hnb_context");
|
||||||
|
tall_ue_ctx = talloc_named_const(NULL, 0, "ue_context");
|
||||||
talloc_asn1_ctx = talloc_named_const(NULL, 0, "asn1_context");
|
talloc_asn1_ctx = talloc_named_const(NULL, 0, "asn1_context");
|
||||||
|
|
||||||
g_hnb_gw.listen_fd.cb = listen_fd_cb;
|
g_hnb_gw.listen_fd.cb = listen_fd_cb;
|
||||||
g_hnb_gw.listen_fd.when = BSC_FD_READ;
|
g_hnb_gw.listen_fd.when = BSC_FD_READ;
|
||||||
g_hnb_gw.listen_fd.data = &g_hnb_gw;
|
g_hnb_gw.listen_fd.data = &g_hnb_gw;
|
||||||
INIT_LLIST_HEAD(&g_hnb_gw.hnb_list);
|
INIT_LLIST_HEAD(&g_hnb_gw.hnb_list);
|
||||||
|
INIT_LLIST_HEAD(&g_hnb_gw.ue_list);
|
||||||
|
|
||||||
rc = osmo_init_logging(&hnbgw_log_info);
|
rc = osmo_init_logging(&hnbgw_log_info);
|
||||||
if (rc < 0)
|
if (rc < 0)
|
||||||
|
|
|
@ -60,6 +60,7 @@ struct ue_context {
|
||||||
struct llist_head list;
|
struct llist_head list;
|
||||||
/*! Unique Context ID for this UE */
|
/*! Unique Context ID for this UE */
|
||||||
uint32_t context_id;
|
uint32_t context_id;
|
||||||
|
char imsi[16+1];
|
||||||
/*! UE is serviced via this HNB */
|
/*! UE is serviced via this HNB */
|
||||||
struct hnb_context *hnb;
|
struct hnb_context *hnb;
|
||||||
};
|
};
|
||||||
|
@ -76,6 +77,13 @@ struct hnb_gw {
|
||||||
/*! SCTP listen socket for incoming connections */
|
/*! SCTP listen socket for incoming connections */
|
||||||
struct osmo_fd listen_fd;
|
struct osmo_fd listen_fd;
|
||||||
struct llist_head hnb_list;
|
struct llist_head hnb_list;
|
||||||
|
struct llist_head ue_list;
|
||||||
|
uint32_t next_ue_ctx_id;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern struct hnb_gw g_hnb_gw;
|
extern struct hnb_gw g_hnb_gw;
|
||||||
|
|
||||||
|
struct ue_context *ue_context_by_id(uint32_t id);
|
||||||
|
struct ue_context *ue_context_by_imsi(const char *imsi);
|
||||||
|
struct ue_context *ue_context_alloc(struct hnb_context *hnb, const char *imsi);
|
||||||
|
void ue_context_free(struct ue_context *ue);
|
||||||
|
|
|
@ -23,6 +23,7 @@ static int hnbgw_hnbap_tx(struct hnb_context *ctx, struct msgb *msg)
|
||||||
return osmo_wqueue_enqueue(&ctx->wqueue, msg);
|
return osmo_wqueue_enqueue(&ctx->wqueue, msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int hnbgw_tx_hnb_register_acc(struct hnb_context *ctx)
|
static int hnbgw_tx_hnb_register_acc(struct hnb_context *ctx)
|
||||||
{
|
{
|
||||||
HNBRegisterAccept_t accept_out;
|
HNBRegisterAccept_t accept_out;
|
||||||
|
@ -110,11 +111,14 @@ static int hnbgw_rx_ue_register_req(struct hnb_context *ctx, ANY_t *in)
|
||||||
if (rc < 0)
|
if (rc < 0)
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
|
/* FIXME: convert UE identity into a more palatable format */
|
||||||
|
ue = ue_context_by_imsi("123");
|
||||||
|
if (!ue)
|
||||||
|
ue = ue_context_alloc(ctx, "123");
|
||||||
|
|
||||||
DEBUGP(DMAIN, "UE-REGSITER-REQ ID_type=%d cause=%ld\n",
|
DEBUGP(DMAIN, "UE-REGSITER-REQ ID_type=%d cause=%ld\n",
|
||||||
ies.uE_Identity.present, ies.registration_Cause);
|
ies.uE_Identity.present, ies.registration_Cause);
|
||||||
|
|
||||||
/* FIXME: convert UE identity into a more palatable format */
|
|
||||||
|
|
||||||
/* Send UERegisterAccept */
|
/* Send UERegisterAccept */
|
||||||
return hnbgw_tx_ue_register_acc(ue);
|
return hnbgw_tx_ue_register_acc(ue);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue