mirror of
				https://gitea.osmocom.org/cellular-infrastructure/osmo-hnodeb.git
				synced 2025-11-04 06:03:31 +00:00 
			
		
		
		
	Move Iuh code to its own module
The Iuh code will be further extended next to properly support reconnect, and hnb will also gain proper shutdown support soon. Change-Id: I6e94210ab06a34b70c61bb074c58d7b0f4ee75de
This commit is contained in:
		@@ -1,6 +1,7 @@
 | 
				
			|||||||
noinst_HEADERS = \
 | 
					noinst_HEADERS = \
 | 
				
			||||||
	hnbap.h \
 | 
						hnbap.h \
 | 
				
			||||||
	hnodeb.h \
 | 
						hnodeb.h \
 | 
				
			||||||
 | 
						iuh.h \
 | 
				
			||||||
	nas.h \
 | 
						nas.h \
 | 
				
			||||||
	ranap.h \
 | 
						ranap.h \
 | 
				
			||||||
	rua.h \
 | 
						rua.h \
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -36,18 +36,6 @@ enum {
 | 
				
			|||||||
};
 | 
					};
 | 
				
			||||||
extern const struct log_info hnb_log_info;
 | 
					extern const struct log_info hnb_log_info;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* 25.467 Section 7.1 */
 | 
					 | 
				
			||||||
#define IUH_DEFAULT_SCTP_PORT	29169
 | 
					 | 
				
			||||||
#define RNA_DEFAULT_SCTP_PORT	25471
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define IUH_PPI_RUA		19
 | 
					 | 
				
			||||||
#define IUH_PPI_HNBAP		20
 | 
					 | 
				
			||||||
#define IUH_PPI_SABP		31
 | 
					 | 
				
			||||||
#define IUH_PPI_RNA		42
 | 
					 | 
				
			||||||
#define IUH_PPI_PUA		55
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define IUH_MSGB_SIZE	2048
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct hnb_chan {
 | 
					struct hnb_chan {
 | 
				
			||||||
	int is_ps;
 | 
						int is_ps;
 | 
				
			||||||
	uint32_t conn_id;
 | 
						uint32_t conn_id;
 | 
				
			||||||
@@ -77,11 +65,9 @@ struct hnb {
 | 
				
			|||||||
		struct hnb_chan *chan;
 | 
							struct hnb_chan *chan;
 | 
				
			||||||
	} cs;
 | 
						} cs;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct hnb *hnb_alloc(void *tall_ctx);
 | 
					struct hnb *hnb_alloc(void *tall_ctx);
 | 
				
			||||||
void hnb_free(struct hnb *hnb);
 | 
					void hnb_free(struct hnb *hnb);
 | 
				
			||||||
int hnb_connect(struct hnb *hnb);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int hnb_iuh_send(struct hnb *hnb, struct msgb *msg);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
extern void *tall_hnb_ctx;
 | 
					extern void *tall_hnb_ctx;
 | 
				
			||||||
extern struct hnb *g_hnb;
 | 
					extern struct hnb *g_hnb;
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										41
									
								
								include/osmocom/hnodeb/iuh.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								include/osmocom/hnodeb/iuh.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,41 @@
 | 
				
			|||||||
 | 
					/* (C) 2015 by Daniel Willmann <dwillmann@sysmocom.de>
 | 
				
			||||||
 | 
					 * (C) 2021 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
 | 
				
			||||||
 | 
					 * Author: Pau Espin Pedrol <pespin@sysmocom.de>
 | 
				
			||||||
 | 
					 * All Rights Reserved
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This program is free software; you can redistribute it and/or modify
 | 
				
			||||||
 | 
					 * it under the terms of the GNU Affero General Public License as published by
 | 
				
			||||||
 | 
					 * the Free Software Foundation; either version 3 of the License, or
 | 
				
			||||||
 | 
					 * (at your option) any later version.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This program is distributed in the hope that it will be useful,
 | 
				
			||||||
 | 
					 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
 | 
					 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
				
			||||||
 | 
					 * GNU Affero General Public License for more details.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * You should have received a copy of the GNU Affero General Public License
 | 
				
			||||||
 | 
					 * along with this program.  If not, see <http://www.gnu.org/lienses/>.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <osmocom/core/msgb.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* 25.467 Section 7.1 */
 | 
				
			||||||
 | 
					#define IUH_DEFAULT_SCTP_PORT	29169
 | 
				
			||||||
 | 
					#define RNA_DEFAULT_SCTP_PORT	25471
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define IUH_PPI_RUA		19
 | 
				
			||||||
 | 
					#define IUH_PPI_HNBAP		20
 | 
				
			||||||
 | 
					#define IUH_PPI_SABP		31
 | 
				
			||||||
 | 
					#define IUH_PPI_RNA		42
 | 
				
			||||||
 | 
					#define IUH_PPI_PUA		55
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define IUH_MSGB_SIZE	2048
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct hnb;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void hnb_iuh_alloc(struct hnb *hnb);
 | 
				
			||||||
 | 
					void hnb_iuh_free(struct hnb *hnb);
 | 
				
			||||||
 | 
					int hnb_iuh_connect(struct hnb *hnb);
 | 
				
			||||||
 | 
					int hnb_iuh_send(struct hnb *hnb, struct msgb *msg);
 | 
				
			||||||
@@ -33,6 +33,7 @@ osmo_hnodeb_SOURCES = \
 | 
				
			|||||||
	debug.c \
 | 
						debug.c \
 | 
				
			||||||
	hnbap.c \
 | 
						hnbap.c \
 | 
				
			||||||
	hnb.c \
 | 
						hnb.c \
 | 
				
			||||||
 | 
						iuh.c \
 | 
				
			||||||
	nas.c \
 | 
						nas.c \
 | 
				
			||||||
	ranap.c \
 | 
						ranap.c \
 | 
				
			||||||
	rua.c \
 | 
						rua.c \
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -20,99 +20,17 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include "config.h"
 | 
					#include "config.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <errno.h>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <sys/types.h>
 | 
					 | 
				
			||||||
#include <sys/socket.h>
 | 
					 | 
				
			||||||
#include <netinet/in.h>
 | 
					 | 
				
			||||||
#include <netinet/sctp.h>
 | 
					 | 
				
			||||||
#include <arpa/inet.h>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <osmocom/core/socket.h>
 | 
					#include <osmocom/core/socket.h>
 | 
				
			||||||
#include <osmocom/core/talloc.h>
 | 
					#include <osmocom/core/talloc.h>
 | 
				
			||||||
#include <osmocom/netif/stream.h>
 | 
					#include <osmocom/netif/stream.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <osmocom/hnodeb/hnbap.h>
 | 
					 | 
				
			||||||
#include <osmocom/hnodeb/rua.h>
 | 
					 | 
				
			||||||
#include <osmocom/hnodeb/hnodeb.h>
 | 
					#include <osmocom/hnodeb/hnodeb.h>
 | 
				
			||||||
 | 
					#include <osmocom/hnodeb/iuh.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int hnb_iuh_read_cb(struct osmo_stream_cli *conn)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct osmo_fd *fd = osmo_stream_cli_get_ofd(conn);
 | 
					 | 
				
			||||||
	struct hnb *hnb = osmo_stream_cli_get_data(conn);
 | 
					 | 
				
			||||||
	struct sctp_sndrcvinfo sinfo;
 | 
					 | 
				
			||||||
	struct msgb *msg = msgb_alloc(IUH_MSGB_SIZE, "Iuh rx");
 | 
					 | 
				
			||||||
	int flags = 0;
 | 
					 | 
				
			||||||
	int rc;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (!msg)
 | 
					 | 
				
			||||||
		return -ENOMEM;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	rc = sctp_recvmsg(fd->fd, msgb_data(msg), msgb_tailroom(msg),
 | 
					 | 
				
			||||||
			  NULL, NULL, &sinfo, &flags);
 | 
					 | 
				
			||||||
	if (rc < 0) {
 | 
					 | 
				
			||||||
		LOGP(DMAIN, LOGL_ERROR, "Error during sctp_recvmsg()\n");
 | 
					 | 
				
			||||||
		/* FIXME: clean up after disappeared HNB */
 | 
					 | 
				
			||||||
		osmo_stream_cli_close(conn);
 | 
					 | 
				
			||||||
		goto free_ret;
 | 
					 | 
				
			||||||
	} else if (rc == 0) {
 | 
					 | 
				
			||||||
		LOGP(DMAIN, LOGL_INFO, "Connection to HNB closed\n");
 | 
					 | 
				
			||||||
		osmo_stream_cli_close(conn);
 | 
					 | 
				
			||||||
		rc = -1;
 | 
					 | 
				
			||||||
		goto free_ret;
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		msgb_put(msg, rc);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (flags & MSG_NOTIFICATION) {
 | 
					 | 
				
			||||||
		LOGP(DMAIN, LOGL_DEBUG, "Ignoring SCTP notification\n");
 | 
					 | 
				
			||||||
		rc = 0;
 | 
					 | 
				
			||||||
		goto free_ret;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	sinfo.sinfo_ppid = ntohl(sinfo.sinfo_ppid);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	switch (sinfo.sinfo_ppid) {
 | 
					 | 
				
			||||||
	case IUH_PPI_HNBAP:
 | 
					 | 
				
			||||||
		LOGP(DHNBAP, LOGL_INFO, "HNBAP message received\n");
 | 
					 | 
				
			||||||
		rc = hnb_hnbap_rx(hnb, msg);
 | 
					 | 
				
			||||||
		break;
 | 
					 | 
				
			||||||
	case IUH_PPI_RUA:
 | 
					 | 
				
			||||||
		LOGP(DRUA, LOGL_INFO, "RUA message received\n");
 | 
					 | 
				
			||||||
		rc = hnb_rua_rx(hnb, msg);
 | 
					 | 
				
			||||||
		break;
 | 
					 | 
				
			||||||
	case IUH_PPI_SABP:
 | 
					 | 
				
			||||||
	case IUH_PPI_RNA:
 | 
					 | 
				
			||||||
	case IUH_PPI_PUA:
 | 
					 | 
				
			||||||
		LOGP(DMAIN, LOGL_ERROR, "Unimplemented SCTP PPID=%u received\n",
 | 
					 | 
				
			||||||
		     sinfo.sinfo_ppid);
 | 
					 | 
				
			||||||
		rc = 0;
 | 
					 | 
				
			||||||
		break;
 | 
					 | 
				
			||||||
	default:
 | 
					 | 
				
			||||||
		LOGP(DMAIN, LOGL_ERROR, "Unknown SCTP PPID=%u received\n",
 | 
					 | 
				
			||||||
		     sinfo.sinfo_ppid);
 | 
					 | 
				
			||||||
		rc = 0;
 | 
					 | 
				
			||||||
		break;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
free_ret:
 | 
					 | 
				
			||||||
	msgb_free(msg);
 | 
					 | 
				
			||||||
	return rc;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static int hnb_iuh_connect_cb(struct osmo_stream_cli *conn)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	LOGP(DMAIN, LOGL_NOTICE, "Iuh connected to HNBGW\n");
 | 
					 | 
				
			||||||
	struct hnb *hnb = osmo_stream_cli_get_data(conn);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	hnb_send_register_req(hnb);
 | 
					 | 
				
			||||||
	return 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct hnb *hnb_alloc(void *tall_ctx)
 | 
					struct hnb *hnb_alloc(void *tall_ctx)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct hnb *hnb;
 | 
						struct hnb *hnb;
 | 
				
			||||||
	struct osmo_stream_cli *cli;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	hnb = talloc_zero(tall_ctx, struct hnb);
 | 
						hnb = talloc_zero(tall_ctx, struct hnb);
 | 
				
			||||||
	if (!hnb)
 | 
						if (!hnb)
 | 
				
			||||||
@@ -123,58 +41,13 @@ struct hnb *hnb_alloc(void *tall_ctx)
 | 
				
			|||||||
		.mcc = 1,
 | 
							.mcc = 1,
 | 
				
			||||||
		.mnc = 1,
 | 
							.mnc = 1,
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
						hnb_iuh_alloc(hnb);
 | 
				
			||||||
	hnb->iuh.local_addr = talloc_strdup(hnb, "0.0.0.0");
 | 
					 | 
				
			||||||
	hnb->iuh.local_port = 0;
 | 
					 | 
				
			||||||
	hnb->iuh.remote_addr = talloc_strdup(hnb, "127.0.0.1");
 | 
					 | 
				
			||||||
	hnb->iuh.remote_port = IUH_DEFAULT_SCTP_PORT;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	cli = osmo_stream_cli_create(hnb);
 | 
					 | 
				
			||||||
	OSMO_ASSERT(cli);
 | 
					 | 
				
			||||||
	hnb->iuh.client = cli;
 | 
					 | 
				
			||||||
	osmo_stream_cli_set_nodelay(cli, true);
 | 
					 | 
				
			||||||
	osmo_stream_cli_set_proto(cli, IPPROTO_SCTP);
 | 
					 | 
				
			||||||
	osmo_stream_cli_set_reconnect_timeout(cli, 5);
 | 
					 | 
				
			||||||
	osmo_stream_cli_set_connect_cb(cli, hnb_iuh_connect_cb);
 | 
					 | 
				
			||||||
	osmo_stream_cli_set_read_cb(cli, hnb_iuh_read_cb);
 | 
					 | 
				
			||||||
	osmo_stream_cli_set_data(cli, hnb);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return hnb;
 | 
						return hnb;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void hnb_free(struct hnb *hnb)
 | 
					void hnb_free(struct hnb *hnb)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if (hnb->iuh.client) {
 | 
						hnb_iuh_free(hnb);
 | 
				
			||||||
		osmo_stream_cli_destroy(hnb->iuh.client);
 | 
					 | 
				
			||||||
		hnb->iuh.client = NULL;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	talloc_free(hnb);
 | 
						talloc_free(hnb);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					 | 
				
			||||||
int hnb_connect(struct hnb *hnb)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	int rc;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	LOGP(DMAIN, LOGL_INFO, "Iuh Connect: %s[:%u] => %s[:%u]\n",
 | 
					 | 
				
			||||||
	     hnb->iuh.local_addr, hnb->iuh.local_port, hnb->iuh.remote_addr, hnb->iuh.remote_port);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	osmo_stream_cli_set_addrs(hnb->iuh.client, (const char**)&hnb->iuh.remote_addr, 1);
 | 
					 | 
				
			||||||
	osmo_stream_cli_set_port(hnb->iuh.client, hnb->iuh.remote_port);
 | 
					 | 
				
			||||||
	osmo_stream_cli_set_local_addrs(hnb->iuh.client, (const char**)&hnb->iuh.local_addr, 1);
 | 
					 | 
				
			||||||
	osmo_stream_cli_set_local_port(hnb->iuh.client, hnb->iuh.local_port);
 | 
					 | 
				
			||||||
	rc = osmo_stream_cli_open(hnb->iuh.client);
 | 
					 | 
				
			||||||
	if (rc < 0) {
 | 
					 | 
				
			||||||
		LOGP(DMAIN, LOGL_ERROR, "Unable to open stream client for Iuh %s[:%u] => %s[:%u]\n",
 | 
					 | 
				
			||||||
		     hnb->iuh.local_addr, hnb->iuh.local_port, hnb->iuh.remote_addr, hnb->iuh.remote_port);
 | 
					 | 
				
			||||||
		/* we don't return error in here because osmo_stream_cli_open()
 | 
					 | 
				
			||||||
		   will continue to retry (due to timeout being explicitly set with
 | 
					 | 
				
			||||||
		   osmo_stream_cli_set_reconnect_timeout() above) to connect so the error is transient */
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int hnb_iuh_send(struct hnb *hnb, struct msgb *msg)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	osmo_stream_cli_send(hnb->iuh.client, msg);
 | 
					 | 
				
			||||||
	return 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
@@ -32,6 +32,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include <osmocom/hnodeb/hnbap.h>
 | 
					#include <osmocom/hnodeb/hnbap.h>
 | 
				
			||||||
#include <osmocom/hnodeb/hnodeb.h>
 | 
					#include <osmocom/hnodeb/hnodeb.h>
 | 
				
			||||||
 | 
					#include <osmocom/hnodeb/iuh.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int hnb_rx_hnb_register_acc(struct hnb *hnb, ANY_t *in)
 | 
					static int hnb_rx_hnb_register_acc(struct hnb *hnb, ANY_t *in)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										167
									
								
								src/osmo-hnodeb/iuh.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										167
									
								
								src/osmo-hnodeb/iuh.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,167 @@
 | 
				
			|||||||
 | 
					/* (C) 2015 by Daniel Willmann <dwillmann@sysmocom.de>
 | 
				
			||||||
 | 
					 * (C) 2021 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
 | 
				
			||||||
 | 
					 * Author: Pau Espin Pedrol <pespin@sysmocom.de>
 | 
				
			||||||
 | 
					 * All Rights Reserved
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This program is free software; you can redistribute it and/or modify
 | 
				
			||||||
 | 
					 * it under the terms of the GNU Affero General Public License as published by
 | 
				
			||||||
 | 
					 * the Free Software Foundation; either version 3 of the License, or
 | 
				
			||||||
 | 
					 * (at your option) any later version.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This program is distributed in the hope that it will be useful,
 | 
				
			||||||
 | 
					 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
 | 
					 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
				
			||||||
 | 
					 * GNU Affero General Public License for more details.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * You should have received a copy of the GNU Affero General Public License
 | 
				
			||||||
 | 
					 * along with this program.  If not, see <http://www.gnu.org/lienses/>.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "config.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <errno.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <sys/types.h>
 | 
				
			||||||
 | 
					#include <sys/socket.h>
 | 
				
			||||||
 | 
					#include <netinet/in.h>
 | 
				
			||||||
 | 
					#include <netinet/sctp.h>
 | 
				
			||||||
 | 
					#include <arpa/inet.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <osmocom/core/socket.h>
 | 
				
			||||||
 | 
					#include <osmocom/core/talloc.h>
 | 
				
			||||||
 | 
					#include <osmocom/netif/stream.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <osmocom/hnodeb/iuh.h>
 | 
				
			||||||
 | 
					#include <osmocom/hnodeb/hnbap.h>
 | 
				
			||||||
 | 
					#include <osmocom/hnodeb/rua.h>
 | 
				
			||||||
 | 
					#include <osmocom/hnodeb/hnodeb.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int hnb_iuh_read_cb(struct osmo_stream_cli *conn)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct osmo_fd *fd = osmo_stream_cli_get_ofd(conn);
 | 
				
			||||||
 | 
						struct hnb *hnb = osmo_stream_cli_get_data(conn);
 | 
				
			||||||
 | 
						struct sctp_sndrcvinfo sinfo;
 | 
				
			||||||
 | 
						struct msgb *msg = msgb_alloc(IUH_MSGB_SIZE, "Iuh rx");
 | 
				
			||||||
 | 
						int flags = 0;
 | 
				
			||||||
 | 
						int rc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!msg)
 | 
				
			||||||
 | 
							return -ENOMEM;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						rc = sctp_recvmsg(fd->fd, msgb_data(msg), msgb_tailroom(msg),
 | 
				
			||||||
 | 
								  NULL, NULL, &sinfo, &flags);
 | 
				
			||||||
 | 
						if (rc < 0) {
 | 
				
			||||||
 | 
							LOGP(DMAIN, LOGL_ERROR, "Error during sctp_recvmsg()\n");
 | 
				
			||||||
 | 
							/* FIXME: clean up after disappeared HNB */
 | 
				
			||||||
 | 
							osmo_stream_cli_close(conn);
 | 
				
			||||||
 | 
							goto free_ret;
 | 
				
			||||||
 | 
						} else if (rc == 0) {
 | 
				
			||||||
 | 
							LOGP(DMAIN, LOGL_INFO, "Connection to HNBGW closed\n");
 | 
				
			||||||
 | 
							osmo_stream_cli_close(conn);
 | 
				
			||||||
 | 
							rc = -1;
 | 
				
			||||||
 | 
							goto free_ret;
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							msgb_put(msg, rc);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (flags & MSG_NOTIFICATION) {
 | 
				
			||||||
 | 
							LOGP(DMAIN, LOGL_DEBUG, "Ignoring SCTP notification\n");
 | 
				
			||||||
 | 
							rc = 0;
 | 
				
			||||||
 | 
							goto free_ret;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						sinfo.sinfo_ppid = ntohl(sinfo.sinfo_ppid);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch (sinfo.sinfo_ppid) {
 | 
				
			||||||
 | 
						case IUH_PPI_HNBAP:
 | 
				
			||||||
 | 
							LOGP(DHNBAP, LOGL_INFO, "HNBAP message received\n");
 | 
				
			||||||
 | 
							rc = hnb_hnbap_rx(hnb, msg);
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case IUH_PPI_RUA:
 | 
				
			||||||
 | 
							LOGP(DRUA, LOGL_INFO, "RUA message received\n");
 | 
				
			||||||
 | 
							rc = hnb_rua_rx(hnb, msg);
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case IUH_PPI_SABP:
 | 
				
			||||||
 | 
						case IUH_PPI_RNA:
 | 
				
			||||||
 | 
						case IUH_PPI_PUA:
 | 
				
			||||||
 | 
							LOGP(DMAIN, LOGL_ERROR, "Unimplemented SCTP PPID=%u received\n",
 | 
				
			||||||
 | 
							     sinfo.sinfo_ppid);
 | 
				
			||||||
 | 
							rc = 0;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							LOGP(DMAIN, LOGL_ERROR, "Unknown SCTP PPID=%u received\n",
 | 
				
			||||||
 | 
							     sinfo.sinfo_ppid);
 | 
				
			||||||
 | 
							rc = 0;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					free_ret:
 | 
				
			||||||
 | 
						msgb_free(msg);
 | 
				
			||||||
 | 
						return rc;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int hnb_iuh_connect_cb(struct osmo_stream_cli *conn)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						LOGP(DMAIN, LOGL_NOTICE, "Iuh connected to HNBGW\n");
 | 
				
			||||||
 | 
						struct hnb *hnb = osmo_stream_cli_get_data(conn);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						hnb_send_register_req(hnb);
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void hnb_iuh_alloc(struct hnb *hnb)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct osmo_stream_cli *cli;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						hnb->iuh.local_addr = talloc_strdup(hnb, "0.0.0.0");
 | 
				
			||||||
 | 
						hnb->iuh.local_port = 0;
 | 
				
			||||||
 | 
						hnb->iuh.remote_addr = talloc_strdup(hnb, "127.0.0.1");
 | 
				
			||||||
 | 
						hnb->iuh.remote_port = IUH_DEFAULT_SCTP_PORT;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						cli = osmo_stream_cli_create(hnb);
 | 
				
			||||||
 | 
						OSMO_ASSERT(cli);
 | 
				
			||||||
 | 
						hnb->iuh.client = cli;
 | 
				
			||||||
 | 
						osmo_stream_cli_set_nodelay(cli, true);
 | 
				
			||||||
 | 
						osmo_stream_cli_set_proto(cli, IPPROTO_SCTP);
 | 
				
			||||||
 | 
						osmo_stream_cli_set_reconnect_timeout(cli, 5);
 | 
				
			||||||
 | 
						osmo_stream_cli_set_connect_cb(cli, hnb_iuh_connect_cb);
 | 
				
			||||||
 | 
						osmo_stream_cli_set_read_cb(cli, hnb_iuh_read_cb);
 | 
				
			||||||
 | 
						osmo_stream_cli_set_data(cli, hnb);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void hnb_iuh_free(struct hnb *hnb)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (!hnb->iuh.client)
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						osmo_stream_cli_destroy(hnb->iuh.client);
 | 
				
			||||||
 | 
						hnb->iuh.client = NULL;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int hnb_iuh_connect(struct hnb *hnb)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int rc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						LOGP(DMAIN, LOGL_INFO, "Iuh Connect: %s[:%u] => %s[:%u]\n",
 | 
				
			||||||
 | 
						     hnb->iuh.local_addr, hnb->iuh.local_port, hnb->iuh.remote_addr, hnb->iuh.remote_port);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						osmo_stream_cli_set_addrs(hnb->iuh.client, (const char **)&hnb->iuh.remote_addr, 1);
 | 
				
			||||||
 | 
						osmo_stream_cli_set_port(hnb->iuh.client, hnb->iuh.remote_port);
 | 
				
			||||||
 | 
						osmo_stream_cli_set_local_addrs(hnb->iuh.client, (const char **)&hnb->iuh.local_addr, 1);
 | 
				
			||||||
 | 
						osmo_stream_cli_set_local_port(hnb->iuh.client, hnb->iuh.local_port);
 | 
				
			||||||
 | 
						rc = osmo_stream_cli_open(hnb->iuh.client);
 | 
				
			||||||
 | 
						if (rc < 0) {
 | 
				
			||||||
 | 
							LOGP(DMAIN, LOGL_ERROR, "Unable to open stream client for Iuh %s[:%u] => %s[:%u]\n",
 | 
				
			||||||
 | 
							     hnb->iuh.local_addr, hnb->iuh.local_port, hnb->iuh.remote_addr, hnb->iuh.remote_port);
 | 
				
			||||||
 | 
							/* we don't return error in here because osmo_stream_cli_open()
 | 
				
			||||||
 | 
							   will continue to retry (due to timeout being explicitly set with
 | 
				
			||||||
 | 
							   osmo_stream_cli_set_reconnect_timeout() above) to connect so the error is transient */
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int hnb_iuh_send(struct hnb *hnb, struct msgb *msg)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						osmo_stream_cli_send(hnb->iuh.client, msg);
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -48,6 +48,7 @@
 | 
				
			|||||||
#include <osmocom/hnodeb/ranap.h>
 | 
					#include <osmocom/hnodeb/ranap.h>
 | 
				
			||||||
#include <osmocom/hnodeb/vty.h>
 | 
					#include <osmocom/hnodeb/vty.h>
 | 
				
			||||||
#include <osmocom/hnodeb/hnodeb.h>
 | 
					#include <osmocom/hnodeb/hnodeb.h>
 | 
				
			||||||
 | 
					#include <osmocom/hnodeb/iuh.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const char * const osmohnodeb_copyright =
 | 
					static const char * const osmohnodeb_copyright =
 | 
				
			||||||
	"OsmoHNodeB - Osmocom 3G Home NodeB implementation\r\n"
 | 
						"OsmoHNodeB - Osmocom 3G Home NodeB implementation\r\n"
 | 
				
			||||||
@@ -264,7 +265,7 @@ int main(int argc, char **argv)
 | 
				
			|||||||
		exit(1);
 | 
							exit(1);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	rc = hnb_connect(g_hnb);
 | 
						rc = hnb_iuh_connect(g_hnb);
 | 
				
			||||||
	if (rc < 0) {
 | 
						if (rc < 0) {
 | 
				
			||||||
		perror("Error connecting to Iuh port");
 | 
							perror("Error connecting to Iuh port");
 | 
				
			||||||
		exit(1);
 | 
							exit(1);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -28,6 +28,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include <osmocom/hnodeb/rua.h>
 | 
					#include <osmocom/hnodeb/rua.h>
 | 
				
			||||||
#include <osmocom/hnodeb/ranap.h>
 | 
					#include <osmocom/hnodeb/ranap.h>
 | 
				
			||||||
 | 
					#include <osmocom/hnodeb/iuh.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int hnb_tx_dt(struct hnb *hnb, struct msgb *txm)
 | 
					int hnb_tx_dt(struct hnb *hnb, struct msgb *txm)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -34,6 +34,7 @@
 | 
				
			|||||||
#include <osmocom/ranap/ranap_common.h>
 | 
					#include <osmocom/ranap/ranap_common.h>
 | 
				
			||||||
#include <osmocom/ranap/ranap_msg_factory.h>
 | 
					#include <osmocom/ranap/ranap_msg_factory.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <osmocom/hnodeb/iuh.h>
 | 
				
			||||||
#include <osmocom/hnodeb/hnbap.h>
 | 
					#include <osmocom/hnodeb/hnbap.h>
 | 
				
			||||||
#include <osmocom/hnodeb/ranap.h>
 | 
					#include <osmocom/hnodeb/ranap.h>
 | 
				
			||||||
#include <osmocom/hnodeb/vty.h>
 | 
					#include <osmocom/hnodeb/vty.h>
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user