first compiling code (untested)
diff --git a/src/Makefile b/src/Makefile
new file mode 100644
index 0000000..18ec5bb
--- /dev/null
+++ b/src/Makefile
@@ -0,0 +1,15 @@
+LIBFFASN1_DIR=../../../kommerz/sysmocom/git/admin/ffasn1c/libffasn1
+
+CFLAGS=-g -Wall `pkg-config --cflags libosmocore libosmovty libosmogsm` -I$(LIBFFASN1_DIR)
+LDFLAGS=`pkg-config --libs libosmocore libosmovty libosmogsm` -lsctp -L$(LIBFFASN1_DIR) -lffasn1
+
+all: hnbgw
+
+hnbgw: hnbgw.o hnbgw_hnbap.o hnbap.o
+ $(CC) $(LDFLAGS) -o $@ $^
+
+%.o: %.c
+ $(CC) $(CFLAGS) -o $@ -c $^
+
+clean:
+ @rm -f hmbgw *.o
diff --git a/src/hnbap.c b/src/hnbap.c
new file mode 120000
index 0000000..9373ccc
--- /dev/null
+++ b/src/hnbap.c
@@ -0,0 +1 @@
+../asn1/hnbap/ffasn1c/hnbap.c
\ No newline at end of file
diff --git a/src/hnbap.h b/src/hnbap.h
new file mode 120000
index 0000000..6b16029
--- /dev/null
+++ b/src/hnbap.h
@@ -0,0 +1 @@
+../asn1/hnbap/ffasn1c/hnbap.h
\ No newline at end of file
diff --git a/src/hnbap_const.h b/src/hnbap_const.h
index 7d3dfa3..36c5422 100644
--- a/src/hnbap_const.h
+++ b/src/hnbap_const.h
@@ -50,6 +50,5 @@
HNBAP_IEI_HNB_Tunnel_Information = 41,
HNBAP_IEI_CELL_FACHMobilitySupport = 42,
HNBAP_IEI_S_RNTIPrefix = 43,
- HNBAP_IEI_S_RNTIPrefix = 43,
/* FIXME */
};
diff --git a/src/hnbgw.c b/src/hnbgw.c
index fc26d0d..a5015ae 100644
--- a/src/hnbgw.c
+++ b/src/hnbgw.c
@@ -1,9 +1,29 @@
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <getopt.h>
+#include <errno.h>
+#include <signal.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/sctp.h>
+
+#include <osmocom/core/application.h>
+#include <osmocom/core/talloc.h>
#include <osmocom/core/select.h>
+#include <osmocom/core/logging.h>
#include <osmocom/core/socket.h>
-#include <osmocom/core/linuxlist.h>
+#include <osmocom/core/msgb.h>
+
+#include <osmocom/vty/telnet_interface.h>
+#include <osmocom/vty/logging.h>
#include "hnbgw.h"
+#include "hnbgw_hnbap.h"
+
+static void *tall_hnb_ctx;
struct hnb_gw g_hnb_gw = {
.config = {
@@ -35,7 +55,7 @@
rc = hnbgw_hnbap_rx(hnb, msg);
break;
case IUH_PPI_RUA:
- rc = hnbgw_rua_rx(hnb, msg);
+ //rc = hnbgw_rua_rx(hnb, msg);
break;
case IUH_PPI_SABP:
case IUH_PPI_RNA:
@@ -58,8 +78,8 @@
static int listen_fd_cb(struct osmo_fd *fd, unsigned int what)
{
struct hnb_gw *gw = fd->data;
- struct hmb_context *ctx;
- struct sokaddr_storage sockaddr;
+ struct hnb_context *ctx;
+ struct sockaddr_storage sockaddr;
socklen_t len = sizeof(sockaddr);
int new_fd = accept(fd->fd, (struct sockaddr *)&sockaddr, &len);
@@ -79,19 +99,77 @@
ctx->socket.fd = new_fd;
ctx->socket.when = BSC_FD_READ;
ctx->socket.cb = hnb_socket_cb;
- osmo_fd_register(&cttx->socket);
+ osmo_fd_register(&ctx->socket);
+
+ llist_add_tail(&ctx->list, &gw->hnb_list);
return 0;
}
+static const struct log_info_cat log_cat[] = {
+ [DMAIN] = {
+ .name = "DMAIN", .loglevel = LOGL_DEBUG, .enabled = 1,
+ .color = "",
+ .description = "Main program",
+ },
+};
+static const struct log_info hnbgw_log_info = {
+ .cat = log_cat,
+ .num_cat = ARRAY_SIZE(log_cat),
+};
+static struct vty_app_info vty_info = {
+ .name = "OsmoHNBGW",
+ .version = "0",
+};
+
+static int daemonize = 0;
+
+int main(int argc, char **argv)
{
+ int rc;
+
+ tall_hnb_ctx = talloc_named_const(NULL, 0, "hnb_context");
+
g_hnb_gw.listen_fd.cb = listen_fd_cb;
g_hnb_gw.listen_fd.when = BSC_FD_READ;
g_hnb_gw.listen_fd.data = &g_hnb_gw;
- osmo_sock_init_ofd(&g_hnb_gw.listen_fd, AF_INET, SOCK_STREAM,
+ rc = osmo_init_logging(&hnbgw_log_info);
+ if (rc < 0)
+ exit(1);
+
+ vty_init(&vty_info);
+
+ rc = telnet_init(NULL, &g_hnb_gw, 2323);
+ if (rc < 0) {
+ perror("Error binding VTY port");
+ exit(1);
+ }
+
+ rc = osmo_sock_init_ofd(&g_hnb_gw.listen_fd, AF_INET, SOCK_STREAM,
IPPROTO_SCTP, "127.0.0.1",
g_hnb_gw.config.iuh_listen_port, OSMO_SOCK_F_BIND);
+ if (rc < 0) {
+ perror("Error binding Iuh port");
+ exit(1);
+ }
+
+ if (daemonize) {
+ rc = osmo_daemonize();
+ if (rc < 0) {
+ perror("Error during daemonize");
+ exit(1);
+ }
+ }
+
+ while (1) {
+ rc = osmo_select_main(0);
+ if (rc < 0)
+ exit(3);
+ }
+
+ /* not reached */
+ exit(0);
}
diff --git a/src/hnbgw.h b/src/hnbgw.h
index 7b69a10..ab8c103 100644
--- a/src/hnbgw.h
+++ b/src/hnbgw.h
@@ -3,6 +3,14 @@
#include <osmocom/core/select.h>
#include <osmocom/core/linuxlist.h>
+#define DEBUG
+#include <osmocom/core/logging.h>
+
+enum {
+ DMAIN,
+};
+
+
/* 25.467 Section 7.1 */
#define IUH_DEFAULT_SCTP_PORT 29169
#define RNA_DEFAULT_SCTP_PORT 25471
@@ -13,7 +21,7 @@
#define IUH_PPI_RNA 42
#define IUH_PPI_PUA 55
-#define IHU_MSGB_SIZE 2048
+#define IUH_MSGB_SIZE 2048
struct umts_cell_id {
uint16_t mcc; /*!< Mobile Country Code */
diff --git a/src/hnbgw_hnbap.c b/src/hnbgw_hnbap.c
index ce41222..fd3a328 100644
--- a/src/hnbgw_hnbap.c
+++ b/src/hnbgw_hnbap.c
@@ -1,8 +1,14 @@
#include <osmocom/core/msgb.h>
+#include <osmocom/core/utils.h>
+#include <unistd.h>
+#include <string.h>
+
+#include "hnbap.h"
#include "hnbgw.h"
#include "hnbap_const.h"
+
static int hnbgw_hnbap_tx(struct HNBAP_PDU *pdu)
{
/* FIXME */
@@ -20,11 +26,19 @@
/* Single required response IE: RNC-ID */
}
-struct ProtocolIE_Field_1 *find_ie(const struct ProtocolIE_Container_1 *cont, ProtocolIE_ID id)
+#define FIND_IE(cont, id) find_ie((const struct ProtocolIE_Container_1 *)cont, id)
+
+static void *find_ie(const struct ProtocolIE_Container_1 *cont, ProtocolIE_ID id)
{
+ int i;
+
for (i = 0; i < cont->count; i++) {
- if (cont->tab[i].id == id)
- return &cont->tab[i];
+ ProtocolIE_Field_1 *field = &cont->tab[i];
+ if (field->id == id) {
+ OSMO_ASSERT(field->value.type);
+ /* FIXME: we shoudl check if it is the correct type, not just any type */
+ return field->value.u.data;
+ }
}
return NULL;
}
@@ -56,29 +70,30 @@
static int hnbgw_rx_hnb_register_req(struct hnb_context *ctx, struct HNBRegisterRequest *req)
{
HNB_Identity *identity =
- FIND_IE(req->protocolIEs, HNBAP_IEI_HNB_Identity);
+ FIND_IE(&req->protocolIEs, HNBAP_IEI_HNB_Identity);
HNB_Location_Information *loc =
- FIND_IE(req->protocolIEs, HNBAP_IEI_HNB_Location_Information);
+ FIND_IE(&req->protocolIEs, HNBAP_IEI_HNB_Location_Information);
PLMNidentity *plmn_id =
- FIND_IE(req->protocolIEs, HNBAP_IEI_PLMNidentity);
+ FIND_IE(&req->protocolIEs, HNBAP_IEI_PLMNidentity);
CellIdentity *cell_id =
- FIND_IE(req->protocolIEs, HNBAP_IEI_CellIdentity);
- LAC *lac = FIND_IE(req->protocolIEs, HNBAP_IEI_LAC);
- RAC *rac = FIND_IE(req->protocolIEs, HNBAP_IEI_RAC);
- SAC *sac = FIND_IE(req->protocolIEs, HNBAP_IEI_SAC);
+ FIND_IE(&req->protocolIEs, HNBAP_IEI_CellIdentity);
+ LAC *lac = FIND_IE(&req->protocolIEs, HNBAP_IEI_LAC);
+ RAC *rac = FIND_IE(&req->protocolIEs, HNBAP_IEI_RAC);
+ SAC *sac = FIND_IE(&req->protocolIEs, HNBAP_IEI_SAC);
/* Optional: CSG-ID */
if(!identity || !loc || !plmn_id || !cell_id || !lac || !rac || !sac)
return -1;
/* copy all identity parameters from the message to ctx */
- strncpy(ctx->identity_info, sizeof(ctx->identity_info, identity_info->buf);
+ strncpy(ctx->identity_info, (const char *) identity->hNB_Identity_Info.buf,
+ sizeof(ctx->identity_info));
ctx->id.lac = asn1str_to_u16(lac);
ctx->id.sac = asn1str_to_u16(sac);
ctx->id.rac = asn1str_to_u8(rac);
ctx->id.cid = asn1bitstr_to_u32(cell_id);
- ctx->id.mcc FIXME
- ctx->id.mnc FIXME
+ //ctx->id.mcc FIXME
+ //ctx->id.mnc FIXME
/* FIXME: Send HNBRegisterAccept */
}
@@ -86,11 +101,11 @@
static int hnbgw_rx_ue_register_req(struct hnb_context *ctx, struct UERegisterRequest *req)
{
UE_Identity *id =
- FIND_IE(req->protocolIEs, HNBAP_IEI_UE_Identity);
+ FIND_IE(&req->protocolIEs, HNBAP_IEI_UE_Identity);
Registration_Cause *reg_cause =
- FIND_IE(req->protocolIEs, HNBAP_IEI_RegistrationCause);
+ FIND_IE(&req->protocolIEs, HNBAP_IEI_RegistrationCause);
UE_Capabilities *ue_cap =
- FIND_IE(req->protocolIEs, HNBAP_IEI_UE_Capabilities);
+ FIND_IE(&req->protocolIEs, HNBAP_IEI_UE_Capabilities);
if (!id || !reg_cause || !ue_cap)
return -1;
@@ -98,22 +113,22 @@
/* FIXME: Send UERegisterAccept */
}
-static int hnbgw_rx_initiating_msg(struct hnb_context *hnb, struct InitiatingMessage *msg)
+static int hnbgw_rx_initiating_msg(struct hnb_context *hnb, struct InitiatingMessage *imsg)
{
int rc;
- switch (msg->procedureCode) {
+ switch (imsg->procedureCode) {
case HNBAP_PC_HNBRegister: /* 8.2 */
- if (msg->value.type != asn1_type_HNBRegisterRequest)
+ if (imsg->value.type != asn1_type_HNBRegisterRequest)
return -1;
- rc = hnbgw_rx_hnb_register_req(hnb, FIXME);
+ rc = hnbgw_rx_hnb_register_req(hnb, imsg->value.u.data);
break;
case HNBAP_PC_HNBDe_Register: /* 8.3 */
break;
case HNBAP_PC_UERegister: /* 8.4 */
- if (msg->value.type != asn1_type_UERegisterRequest)
+ if (imsg->value.type != asn1_type_UERegisterRequest)
return -1;
- rc = hnbgw_rx_ue_register_req(hnb, FIXME);
+ rc = hnbgw_rx_ue_register_req(hnb, imsg->value.u.data);
break;
case HNBAP_PC_UEDe_Register: /* 8.5 */
break;
@@ -129,12 +144,12 @@
}
}
-static int hnbgw_rx_successful_outcome_msg(struct SuccessfulOutcome *msg)
+static int hnbgw_rx_successful_outcome_msg(struct hnb_context *hnb, struct SuccessfulOutcome *msg)
{
}
-static int hnbgw_rx_unsuccessful_outcome_msg(struct UnsuccessfulOutcome *msg)
+static int hnbgw_rx_unsuccessful_outcome_msg(struct hnb_context *hnb, struct UnsuccessfulOutcome *msg)
{
}
@@ -142,17 +157,19 @@
static int _hnbgw_hnbap_rx(struct hnb_context *hnb, struct HNBAP_PDU *pdu)
{
+ int rc;
+
/* it's a bit odd that we can't dispatch on procedure code, but
* that's not possible */
switch (pdu->choice) {
case HNBAP_PDU_initiatingMessage:
- rc = hnbgw_rx_initiating_msg(&pdu->u.initiatingMessage);
+ rc = hnbgw_rx_initiating_msg(hnb, &pdu->u.initiatingMessage);
break;
case HNBAP_PDU_successfulOutcome:
- rc = hnbgw_rx_successful_outcome_msg(&pdu->u.successfulOutcome);
+ rc = hnbgw_rx_successful_outcome_msg(hnb, &pdu->u.successfulOutcome);
break;
case HNBAP_PDU_unsuccessfulOutcome:
- rc = hnbgw_rx_unsuccessful_outcome_msg(&pdu->u.unsuccessfulOutcome);
+ rc = hnbgw_rx_unsuccessful_outcome_msg(hnb, &pdu->u.unsuccessfulOutcome);
break;
default:
return -1;
diff --git a/src/hnbgw_hnbap.h b/src/hnbgw_hnbap.h
new file mode 100644
index 0000000..955e0aa
--- /dev/null
+++ b/src/hnbgw_hnbap.h
@@ -0,0 +1,6 @@
+#pragma once
+
+#include "hnbgw.h"
+
+int hnbgw_hnbap_rx(struct hnb_context *hnb, struct msgb *msg);
+int hnbgw_hnbap_init(void);