Rename CBSP,SABP,SBcAP structs and APIs
Rename osmo_*_cbc -> cbc_*_mgr: Now they only hold TCP/SCTP server related conns, but will also hold TCP/SCTP client conns in the near future. Rename osmo_cbc_*_client -> cbc_*_link: The term "client" is confusing, since it doesn't exist in CBSP/SBcAP, and will later support connecting to server at TCP/SCTP level. Let's use "link" instead, similar to what's used in osmo-bsc which already supports both TCP client and server modes. Change-Id: Ia9d26dc1593c8ee08dce348fe9f5f4c9398ea2a5
This commit is contained in:
parent
0f17a212d1
commit
d3be026b93
|
@ -3,9 +3,9 @@
|
|||
#include <stdbool.h>
|
||||
#include <osmocom/core/linuxlist.h>
|
||||
|
||||
struct osmo_cbsp_cbc_client;
|
||||
struct osmo_sabp_cbc_client;
|
||||
struct osmo_sbcap_cbc_client;
|
||||
struct cbc_cbsp_link;
|
||||
struct cbc_sabp_link;
|
||||
struct cbc_sbcap_link;
|
||||
|
||||
#define CBC_MAX_REM_ADDRS 8
|
||||
|
||||
|
@ -30,10 +30,10 @@ struct cbc_peer {
|
|||
|
||||
enum cbc_peer_protocol proto;
|
||||
union {
|
||||
struct osmo_cbsp_cbc_client *cbsp;
|
||||
struct osmo_sabp_cbc_client *sabp;
|
||||
struct osmo_sbcap_cbc_client *sbcap;
|
||||
} client;
|
||||
struct cbc_cbsp_link *cbsp;
|
||||
struct cbc_sabp_link *sabp;
|
||||
struct cbc_sbcap_link *sbcap;
|
||||
} link;
|
||||
};
|
||||
|
||||
extern const struct value_string cbc_peer_proto_name[];
|
||||
|
|
|
@ -5,15 +5,15 @@
|
|||
|
||||
#include <osmocom/cbc/cbc_data.h>
|
||||
|
||||
#define LOGPCC(client, level, fmt, args...) \
|
||||
LOGP(DCBSP, level, "%s: " fmt, cbsp_cbc_client_name(client), ## args)
|
||||
#define LOGPCC(link, level, fmt, args...) \
|
||||
LOGP(DCBSP, level, "%s: " fmt, cbc_cbsp_link_name(link), ## args)
|
||||
|
||||
struct osmo_cbsp_cbc_client;
|
||||
struct cbc_cbsp_link;
|
||||
struct osmo_fsm_inst;
|
||||
struct cbc_peer;
|
||||
|
||||
/* a CBC server */
|
||||
struct osmo_cbsp_cbc {
|
||||
/* Holder of all CBSP conn related information: */
|
||||
struct cbc_cbsp_mgr {
|
||||
/* libosmo-netif stream server */
|
||||
struct osmo_stream_srv_link *link;
|
||||
|
||||
|
@ -21,16 +21,16 @@ struct osmo_cbsp_cbc {
|
|||
struct llist_head clients;
|
||||
|
||||
/* receive call-back; called for every received message */
|
||||
int (*rx_cb)(struct osmo_cbsp_cbc_client *client, struct osmo_cbsp_decoded *dec);
|
||||
int (*rx_cb)(struct cbc_cbsp_link *link, struct osmo_cbsp_decoded *dec);
|
||||
};
|
||||
|
||||
struct osmo_cbsp_cbc *cbsp_cbc_create(void *ctx);
|
||||
struct cbc_cbsp_mgr *cbc_cbsp_mgr_create(void *ctx);
|
||||
|
||||
/* a single (remote) client connected to the (local) CBC server */
|
||||
struct osmo_cbsp_cbc_client {
|
||||
/* a CBSP link with a single (remote) peer connected to us */
|
||||
struct cbc_cbsp_link {
|
||||
/* entry in osmo_cbsp_cbc.clients */
|
||||
struct llist_head list;
|
||||
/* stream server connection for this client */
|
||||
/* stream server connection for this link */
|
||||
struct osmo_stream_srv *conn;
|
||||
/* partially received CBSP message (rx completion pending) */
|
||||
struct msgb *rx_msg;
|
||||
|
@ -40,7 +40,7 @@ struct osmo_cbsp_cbc_client {
|
|||
struct cbc_peer *peer;
|
||||
};
|
||||
|
||||
const char *cbsp_cbc_client_name(const struct osmo_cbsp_cbc_client *client);
|
||||
void cbsp_cbc_client_tx(struct osmo_cbsp_cbc_client *client, struct osmo_cbsp_decoded *cbsp);
|
||||
void cbsp_cbc_client_close(struct osmo_cbsp_cbc_client *client);
|
||||
int cbsp_cbc_client_rx_cb(struct osmo_cbsp_cbc_client *client, struct osmo_cbsp_decoded *dec);
|
||||
const char *cbc_cbsp_link_name(const struct cbc_cbsp_link *link);
|
||||
void cbc_cbsp_link_tx(struct cbc_cbsp_link *link, struct osmo_cbsp_decoded *cbsp);
|
||||
void cbc_cbsp_link_close(struct cbc_cbsp_link *link);
|
||||
int cbc_cbsp_link_rx_cb(struct cbc_cbsp_link *link, struct osmo_cbsp_decoded *dec);
|
||||
|
|
|
@ -8,15 +8,15 @@
|
|||
|
||||
#define SBcAP_SCTP_PORT 29168
|
||||
typedef struct SBcAP_SBC_AP_PDU SBcAP_SBC_AP_PDU_t;
|
||||
#define LOGPSBCAPC(client, level, fmt, args...) \
|
||||
LOGP(DSBcAP, level, "%s: " fmt, sbcap_cbc_client_name(client), ## args)
|
||||
#define LOGPSBCAPC(link, level, fmt, args...) \
|
||||
LOGP(DSBcAP, level, "%s: " fmt, cbc_sbcap_link_name(link), ## args)
|
||||
|
||||
struct osmo_sbcap_cbc_client;
|
||||
struct cbc_sbcap_link;
|
||||
struct osmo_fsm_inst;
|
||||
struct cbc_peer;
|
||||
|
||||
/* a CBC server */
|
||||
struct osmo_sbcap_cbc {
|
||||
/* Holder of all SBc-AP conn related information: */
|
||||
struct cbc_sbcap_mgr {
|
||||
/* libosmo-netif stream server */
|
||||
struct osmo_stream_srv_link *link;
|
||||
|
||||
|
@ -24,21 +24,21 @@ struct osmo_sbcap_cbc {
|
|||
struct llist_head clients;
|
||||
|
||||
/* receive call-back; called for every received message */
|
||||
int (*rx_cb)(struct osmo_sbcap_cbc_client *client, SBcAP_SBC_AP_PDU_t *pdu);
|
||||
int (*rx_cb)(struct cbc_sbcap_link *link, SBcAP_SBC_AP_PDU_t *pdu);
|
||||
};
|
||||
struct osmo_sbcap_cbc *sbcap_cbc_create(void *ctx);
|
||||
struct cbc_sbcap_mgr *cbc_sbcap_mgr_create(void *ctx);
|
||||
|
||||
/* a single (remote) client connected to the (local) CBC server */
|
||||
struct osmo_sbcap_cbc_client {
|
||||
/* an SBc-AP link with a single (remote) peer connected to us */
|
||||
struct cbc_sbcap_link {
|
||||
/* entry in osmo_sbcap_cbc.clients */
|
||||
struct llist_head list;
|
||||
/* stream server connection for this client */
|
||||
/* stream server connection for this link */
|
||||
struct osmo_stream_srv *conn;
|
||||
struct osmo_fsm_inst *fi;
|
||||
struct cbc_peer *peer;
|
||||
};
|
||||
|
||||
const char *sbcap_cbc_client_name(const struct osmo_sbcap_cbc_client *client);
|
||||
void sbcap_cbc_client_tx(struct osmo_sbcap_cbc_client *client, SBcAP_SBC_AP_PDU_t *pdu);
|
||||
void sbcap_cbc_client_close(struct osmo_sbcap_cbc_client *client);
|
||||
int sbcap_cbc_client_rx_cb(struct osmo_sbcap_cbc_client *client, SBcAP_SBC_AP_PDU_t *pdu);
|
||||
const char *cbc_sbcap_link_name(const struct cbc_sbcap_link *link);
|
||||
void cbc_sbcap_link_tx(struct cbc_sbcap_link *link, SBcAP_SBC_AP_PDU_t *pdu);
|
||||
void cbc_sbcap_link_close(struct cbc_sbcap_link *link);
|
||||
int cbc_sbcap_link_rx_cb(struct cbc_sbcap_link *link, SBcAP_SBC_AP_PDU_t *pdu);
|
||||
|
|
|
@ -277,12 +277,12 @@ int main(int argc, char **argv)
|
|||
exit(1);
|
||||
}
|
||||
|
||||
if (cbsp_cbc_create(tall_cbc_ctx) == NULL) {
|
||||
if (cbc_cbsp_mgr_create(tall_cbc_ctx) == NULL) {
|
||||
perror("Error binding CBSP port");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (sbcap_cbc_create(tall_cbc_ctx) == NULL) {
|
||||
if (cbc_sbcap_mgr_create(tall_cbc_ctx) == NULL) {
|
||||
perror("Error binding SBc-AP port\n");
|
||||
exit(1);
|
||||
}
|
||||
|
|
|
@ -63,22 +63,22 @@ void cbc_peer_remove(struct cbc_peer *peer)
|
|||
{
|
||||
struct cbc_message *cbcmsg;
|
||||
|
||||
/* close any existing client connection */
|
||||
/* close any existing peer link connection */
|
||||
switch (peer->proto) {
|
||||
case CBC_PEER_PROTO_CBSP:
|
||||
if (peer->client.cbsp)
|
||||
cbsp_cbc_client_close(peer->client.cbsp);
|
||||
if (peer->link.cbsp)
|
||||
cbc_cbsp_link_close(peer->link.cbsp);
|
||||
break;
|
||||
case CBC_PEER_PROTO_SBcAP:
|
||||
if (peer->client.sbcap)
|
||||
sbcap_cbc_client_close(peer->client.sbcap);
|
||||
if (peer->link.sbcap)
|
||||
cbc_sbcap_link_close(peer->link.sbcap);
|
||||
break;
|
||||
case CBC_PEER_PROTO_SABP:
|
||||
default:
|
||||
OSMO_ASSERT(0);
|
||||
}
|
||||
|
||||
/* iterate over messages; remove client from all message_peers */
|
||||
/* iterate over messages; remove peer from all message_peers */
|
||||
llist_for_each_entry(cbcmsg, &g_cbc->messages, list) {
|
||||
cbc_message_del_peer(cbcmsg, peer);
|
||||
}
|
||||
|
|
|
@ -46,14 +46,14 @@ static void dump_one_cbc_peer(struct vty *vty, const struct cbc_peer *peer)
|
|||
|
||||
switch (peer->proto) {
|
||||
case CBC_PEER_PROTO_CBSP:
|
||||
if (peer->client.cbsp)
|
||||
state = osmo_fsm_inst_state_name(peer->client.cbsp->fi);
|
||||
if (peer->link.cbsp)
|
||||
state = osmo_fsm_inst_state_name(peer->link.cbsp->fi);
|
||||
break;
|
||||
case CBC_PEER_PROTO_SABP:
|
||||
break;
|
||||
case CBC_PEER_PROTO_SBcAP:
|
||||
if (peer->client.sbcap)
|
||||
state = osmo_fsm_inst_state_name(peer->client.sbcap->fi);
|
||||
if (peer->link.sbcap)
|
||||
state = osmo_fsm_inst_state_name(peer->link.sbcap->fi);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -37,14 +37,14 @@
|
|||
#include <osmocom/cbc/cbsp_server_fsm.h>
|
||||
#include <osmocom/cbc/cbc_peer.h>
|
||||
|
||||
const char *cbsp_cbc_client_name(const struct osmo_cbsp_cbc_client *client)
|
||||
const char *cbc_cbsp_link_name(const struct cbc_cbsp_link *link)
|
||||
{
|
||||
OSMO_ASSERT(client);
|
||||
OSMO_ASSERT(link);
|
||||
|
||||
if (client->peer && client->peer->name) {
|
||||
return client->peer->name;
|
||||
if (link->peer && link->peer->name) {
|
||||
return link->peer->name;
|
||||
} else {
|
||||
struct osmo_fd *ofd = osmo_stream_srv_get_ofd(client->conn);
|
||||
struct osmo_fd *ofd = osmo_stream_srv_get_ofd(link->conn);
|
||||
return osmo_sock_get_name2(ofd->fd);
|
||||
}
|
||||
}
|
||||
|
@ -52,18 +52,18 @@ const char *cbsp_cbc_client_name(const struct osmo_cbsp_cbc_client *client)
|
|||
/* data from BSC has arrived at CBC */
|
||||
static int cbsp_cbc_read_cb(struct osmo_stream_srv *conn)
|
||||
{
|
||||
struct osmo_stream_srv_link *link = osmo_stream_srv_get_master(conn);
|
||||
struct osmo_cbsp_cbc_client *client = osmo_stream_srv_get_data(conn);
|
||||
struct osmo_cbsp_cbc *cbc = osmo_stream_srv_link_get_data(link);
|
||||
struct osmo_stream_srv_link *srv_link = osmo_stream_srv_get_master(conn);
|
||||
struct cbc_cbsp_link *link = osmo_stream_srv_get_data(conn);
|
||||
struct cbc_cbsp_mgr *cbc = osmo_stream_srv_link_get_data(srv_link);
|
||||
struct osmo_fd *ofd = osmo_stream_srv_get_ofd(conn);
|
||||
struct osmo_cbsp_decoded *decoded;
|
||||
struct msgb *msg = NULL;
|
||||
int rc;
|
||||
|
||||
LOGPCC(client, LOGL_DEBUG, "read_cb rx_msg=%p\n", client->rx_msg);
|
||||
LOGPCC(link, LOGL_DEBUG, "read_cb rx_msg=%p\n", link->rx_msg);
|
||||
|
||||
/* message de-segmentation */
|
||||
rc = osmo_cbsp_recv_buffered(conn, ofd->fd, &msg, &client->rx_msg);
|
||||
rc = osmo_cbsp_recv_buffered(conn, ofd->fd, &msg, &link->rx_msg);
|
||||
if (rc <= 0) {
|
||||
if (rc == -EAGAIN || rc == -EINTR) {
|
||||
/* more data needs to be read */
|
||||
|
@ -79,15 +79,15 @@ static int cbsp_cbc_read_cb(struct osmo_stream_srv *conn)
|
|||
return -EBADF;
|
||||
}
|
||||
OSMO_ASSERT(msg);
|
||||
LOGPCC(client, LOGL_DEBUG, "Received CBSP %s\n", msgb_hexdump(msg));
|
||||
LOGPCC(link, LOGL_DEBUG, "Received CBSP %s\n", msgb_hexdump(msg));
|
||||
/* decode + dispatch message */
|
||||
decoded = osmo_cbsp_decode(client, msg);
|
||||
decoded = osmo_cbsp_decode(link, msg);
|
||||
if (decoded) {
|
||||
LOGPCC(client, LOGL_INFO, "Received CBSP %s\n",
|
||||
LOGPCC(link, LOGL_INFO, "Received CBSP %s\n",
|
||||
get_value_string(cbsp_msg_type_names, decoded->msg_type));
|
||||
cbc->rx_cb(client, decoded);
|
||||
cbc->rx_cb(link, decoded);
|
||||
} else {
|
||||
LOGPCC(client, LOGL_ERROR, "Unable to decode %s\n", msgb_hexdump(msg));
|
||||
LOGPCC(link, LOGL_ERROR, "Unable to decode %s\n", msgb_hexdump(msg));
|
||||
}
|
||||
msgb_free(msg);
|
||||
return 0;
|
||||
|
@ -96,111 +96,111 @@ static int cbsp_cbc_read_cb(struct osmo_stream_srv *conn)
|
|||
/* connection from BSC to CBC has been closed */
|
||||
static int cbsp_cbc_closed_cb(struct osmo_stream_srv *conn)
|
||||
{
|
||||
struct osmo_cbsp_cbc_client *client = osmo_stream_srv_get_data(conn);
|
||||
LOGPCC(client, LOGL_NOTICE, "connection closed\n");
|
||||
struct cbc_cbsp_link *link = osmo_stream_srv_get_data(conn);
|
||||
LOGPCC(link, LOGL_NOTICE, "connection closed\n");
|
||||
|
||||
if (client->peer)
|
||||
client->peer->client.cbsp = NULL;
|
||||
client->conn = NULL;
|
||||
if (client->fi)
|
||||
osmo_fsm_inst_dispatch(client->fi, CBSP_SRV_E_CMD_CLOSE, NULL);
|
||||
if (link->peer)
|
||||
link->peer->link.cbsp = NULL;
|
||||
link->conn = NULL;
|
||||
if (link->fi)
|
||||
osmo_fsm_inst_dispatch(link->fi, CBSP_SRV_E_CMD_CLOSE, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* new connection from BSC has arrived at CBC */
|
||||
static int cbsp_cbc_accept_cb(struct osmo_stream_srv_link *link, int fd)
|
||||
static int cbsp_cbc_accept_cb(struct osmo_stream_srv_link *srv_link, int fd)
|
||||
{
|
||||
struct osmo_cbsp_cbc *cbc = osmo_stream_srv_link_get_data(link);
|
||||
struct osmo_cbsp_cbc_client *client = talloc_zero(cbc, struct osmo_cbsp_cbc_client);
|
||||
struct cbc_cbsp_mgr *cbc = osmo_stream_srv_link_get_data(srv_link);
|
||||
struct cbc_cbsp_link *link = talloc_zero(cbc, struct cbc_cbsp_link);
|
||||
char remote_ip[INET6_ADDRSTRLEN], portbuf[6];
|
||||
int remote_port;
|
||||
OSMO_ASSERT(client);
|
||||
OSMO_ASSERT(link);
|
||||
|
||||
remote_ip[0] = '\0';
|
||||
portbuf[0] = '\0';
|
||||
osmo_sock_get_ip_and_port(fd, remote_ip, sizeof(remote_ip), portbuf, sizeof(portbuf), false);
|
||||
remote_port = atoi(portbuf);
|
||||
|
||||
LOGP(DCBSP, LOGL_NOTICE, "New CBSP client connection from %s:%u\n", remote_ip, remote_port);
|
||||
LOGP(DCBSP, LOGL_NOTICE, "New CBSP link connection from %s:%u\n", remote_ip, remote_port);
|
||||
|
||||
client->conn = osmo_stream_srv_create(link, link, fd, cbsp_cbc_read_cb, cbsp_cbc_closed_cb, client);
|
||||
if (!client->conn) {
|
||||
link->conn = osmo_stream_srv_create(srv_link, srv_link, fd, cbsp_cbc_read_cb, cbsp_cbc_closed_cb, link);
|
||||
if (!link->conn) {
|
||||
LOGP(DCBSP, LOGL_ERROR, "Unable to create stream server for %s:%d\n",
|
||||
remote_ip, remote_port);
|
||||
talloc_free(client);
|
||||
talloc_free(link);
|
||||
return -1;
|
||||
}
|
||||
client->fi = osmo_fsm_inst_alloc(&cbsp_server_fsm, client, client, LOGL_DEBUG, NULL);
|
||||
if (!client->fi) {
|
||||
LOGPCC(client, LOGL_ERROR, "Unable to allocate FSM\n");
|
||||
osmo_stream_srv_destroy(client->conn);
|
||||
talloc_free(client);
|
||||
link->fi = osmo_fsm_inst_alloc(&cbsp_server_fsm, link, link, LOGL_DEBUG, NULL);
|
||||
if (!link->fi) {
|
||||
LOGPCC(link, LOGL_ERROR, "Unable to allocate FSM\n");
|
||||
osmo_stream_srv_destroy(link->conn);
|
||||
talloc_free(link);
|
||||
return -1;
|
||||
}
|
||||
llist_add_tail(&client->list, &cbc->clients);
|
||||
llist_add_tail(&link->list, &cbc->clients);
|
||||
|
||||
/* Match client to peer */
|
||||
client->peer = cbc_peer_by_addr_proto(remote_ip, remote_port, CBC_PEER_PROTO_CBSP);
|
||||
if (!client->peer) {
|
||||
/* Match link to peer */
|
||||
link->peer = cbc_peer_by_addr_proto(remote_ip, remote_port, CBC_PEER_PROTO_CBSP);
|
||||
if (!link->peer) {
|
||||
if (g_cbc->config.permit_unknown_peers) {
|
||||
LOGPCC(client, LOGL_NOTICE, "Accepting unknown CBSP peer %s:%d\n",
|
||||
LOGPCC(link, LOGL_NOTICE, "Accepting unknown CBSP peer %s:%d\n",
|
||||
remote_ip, remote_port);
|
||||
client->peer = cbc_peer_create(NULL, CBC_PEER_PROTO_CBSP);
|
||||
OSMO_ASSERT(client->peer);
|
||||
client->peer->unknown_dynamic_peer = true;
|
||||
link->peer = cbc_peer_create(NULL, CBC_PEER_PROTO_CBSP);
|
||||
OSMO_ASSERT(link->peer);
|
||||
link->peer->unknown_dynamic_peer = true;
|
||||
} else {
|
||||
LOGPCC(client, LOGL_NOTICE, "Rejecting unknown CBSP peer %s:%d (not permitted)\n",
|
||||
LOGPCC(link, LOGL_NOTICE, "Rejecting unknown CBSP peer %s:%d (not permitted)\n",
|
||||
remote_ip, remote_port);
|
||||
osmo_stream_srv_destroy(client->conn);
|
||||
osmo_stream_srv_destroy(link->conn);
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
if (client->peer->client.cbsp) {
|
||||
LOGPCC(client, LOGL_ERROR, "We already have a connection for peer %s\n",
|
||||
client->peer->name);
|
||||
if (link->peer->link.cbsp) {
|
||||
LOGPCC(link, LOGL_ERROR, "We already have a connection for peer %s\n",
|
||||
link->peer->name);
|
||||
/* FIXME */
|
||||
}
|
||||
client->peer->client.cbsp = client;
|
||||
link->peer->link.cbsp = link;
|
||||
}
|
||||
|
||||
osmo_fsm_inst_dispatch(client->fi, CBSP_SRV_E_CMD_RESET, NULL);
|
||||
osmo_fsm_inst_dispatch(link->fi, CBSP_SRV_E_CMD_RESET, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void cbsp_cbc_client_tx(struct osmo_cbsp_cbc_client *client, struct osmo_cbsp_decoded *cbsp)
|
||||
void cbc_cbsp_link_tx(struct cbc_cbsp_link *link, struct osmo_cbsp_decoded *cbsp)
|
||||
{
|
||||
struct msgb *msg;
|
||||
|
||||
if (!client) {
|
||||
if (!link) {
|
||||
LOGP(DCBSP, LOGL_NOTICE, "Cannot transmit %s: no connection\n",
|
||||
get_value_string(cbsp_msg_type_names, cbsp->msg_type));
|
||||
return ;
|
||||
}
|
||||
|
||||
LOGPCC(client, LOGL_INFO, "Transmitting %s\n",
|
||||
LOGPCC(link, LOGL_INFO, "Transmitting %s\n",
|
||||
get_value_string(cbsp_msg_type_names, cbsp->msg_type));
|
||||
|
||||
msg = osmo_cbsp_encode(client, cbsp);
|
||||
msg = osmo_cbsp_encode(link, cbsp);
|
||||
if (!msg) {
|
||||
LOGPCC(client, LOGL_ERROR, "Failed to encode CBSP %s: %s\n",
|
||||
LOGPCC(link, LOGL_ERROR, "Failed to encode CBSP %s: %s\n",
|
||||
get_value_string(cbsp_msg_type_names, cbsp->msg_type), osmo_cbsp_errstr);
|
||||
talloc_free(cbsp);
|
||||
return;
|
||||
}
|
||||
talloc_free(cbsp);
|
||||
osmo_stream_srv_send(client->conn, msg);
|
||||
osmo_stream_srv_send(link->conn, msg);
|
||||
}
|
||||
|
||||
void cbsp_cbc_client_close(struct osmo_cbsp_cbc_client *client)
|
||||
void cbc_cbsp_link_close(struct cbc_cbsp_link *link)
|
||||
{
|
||||
osmo_stream_srv_destroy(client->conn);
|
||||
osmo_stream_srv_destroy(link->conn);
|
||||
}
|
||||
|
||||
/* initialize the CBC-side CBSP server */
|
||||
struct osmo_cbsp_cbc *cbsp_cbc_create(void *ctx)
|
||||
struct cbc_cbsp_mgr *cbc_cbsp_mgr_create(void *ctx)
|
||||
{
|
||||
struct osmo_cbsp_cbc *cbc = talloc_zero(ctx, struct osmo_cbsp_cbc);
|
||||
struct cbc_cbsp_mgr *cbc = talloc_zero(ctx, struct cbc_cbsp_mgr);
|
||||
int rc;
|
||||
char *bind_ip = g_cbc->config.cbsp.local_host;
|
||||
int bind_port = g_cbc->config.cbsp.local_port;
|
||||
|
@ -209,7 +209,7 @@ struct osmo_cbsp_cbc *cbsp_cbc_create(void *ctx)
|
|||
bind_port = CBSP_TCP_PORT;
|
||||
|
||||
OSMO_ASSERT(cbc);
|
||||
cbc->rx_cb = cbsp_cbc_client_rx_cb;
|
||||
cbc->rx_cb = cbc_cbsp_link_rx_cb;
|
||||
INIT_LLIST_HEAD(&cbc->clients);
|
||||
cbc->link = osmo_stream_srv_link_create(cbc);
|
||||
osmo_stream_srv_link_set_data(cbc->link, cbc);
|
||||
|
|
|
@ -41,7 +41,7 @@
|
|||
#define T_WAIT_RESET_RESP_SECS 5
|
||||
|
||||
enum cbsp_server_state {
|
||||
/* initial state after client TCP connection established */
|
||||
/* initial state after link TCP connection established */
|
||||
CBSP_SRV_S_INIT,
|
||||
/* RESET has been sent to BSC, waiting for response */
|
||||
CBSP_SRV_S_RESET_PENDING,
|
||||
|
@ -74,7 +74,7 @@ static void cbsp_server_s_init(struct osmo_fsm_inst *fi, uint32_t event, void *d
|
|||
|
||||
static void cbsp_server_s_reset_pending_onenter(struct osmo_fsm_inst *fi, uint32_t prev_state)
|
||||
{
|
||||
struct osmo_cbsp_cbc_client *client = (struct osmo_cbsp_cbc_client *) fi->priv;
|
||||
struct cbc_cbsp_link *link = (struct cbc_cbsp_link *) fi->priv;
|
||||
struct osmo_cbsp_decoded *cbspd;
|
||||
|
||||
if (prev_state == CBSP_SRV_S_RESET_PENDING)
|
||||
|
@ -86,7 +86,7 @@ static void cbsp_server_s_reset_pending_onenter(struct osmo_fsm_inst *fi, uint32
|
|||
cbspd->u.reset.cell_list.id_discr = CELL_IDENT_BSS;
|
||||
INIT_LLIST_HEAD(&cbspd->u.reset.cell_list.list);
|
||||
|
||||
cbsp_cbc_client_tx(client, cbspd);
|
||||
cbc_cbsp_link_tx(link, cbspd);
|
||||
/* wait for response */
|
||||
osmo_fsm_inst_state_chg(fi, CBSP_SRV_S_RESET_PENDING, T_WAIT_RESET_RESP_SECS,
|
||||
T_WAIT_RESET_RESP);
|
||||
|
@ -136,7 +136,7 @@ static void cbsp_server_s_idle(struct osmo_fsm_inst *fi, uint32_t event, void *d
|
|||
|
||||
static int cbsp_server_fsm_timer_cb(struct osmo_fsm_inst *fi)
|
||||
{
|
||||
struct osmo_cbsp_cbc_client *client = (struct osmo_cbsp_cbc_client *) fi->priv;
|
||||
struct cbc_cbsp_link *link = (struct cbc_cbsp_link *) fi->priv;
|
||||
struct osmo_cbsp_decoded *cbspd;
|
||||
|
||||
switch (fi->T) {
|
||||
|
@ -146,7 +146,7 @@ static int cbsp_server_fsm_timer_cb(struct osmo_fsm_inst *fi)
|
|||
OSMO_ASSERT(cbspd);
|
||||
cbspd->msg_type = CBSP_MSGT_KEEP_ALIVE;
|
||||
cbspd->u.keep_alive.repetition_period = T_KEEPALIVE_SECS;
|
||||
cbsp_cbc_client_tx(client, cbspd);
|
||||
cbc_cbsp_link_tx(link, cbspd);
|
||||
/* wait for response */
|
||||
osmo_fsm_inst_state_chg(fi, CBSP_SRV_S_KEEPALIVE_PENDING, T_WAIT_KEEPALIVE_RESP_SECS,
|
||||
T_WAIT_KEEPALIVE_RESP);
|
||||
|
@ -162,7 +162,7 @@ static int cbsp_server_fsm_timer_cb(struct osmo_fsm_inst *fi)
|
|||
|
||||
static void cbsp_server_fsm_allstate(struct osmo_fsm_inst *fi, uint32_t event, void *data)
|
||||
{
|
||||
struct osmo_cbsp_cbc_client *client = (struct osmo_cbsp_cbc_client *) fi->priv;
|
||||
struct cbc_cbsp_link *link = (struct cbc_cbsp_link *) fi->priv;
|
||||
struct osmo_cbsp_decoded *dec;
|
||||
|
||||
switch (event) {
|
||||
|
@ -178,12 +178,12 @@ static void cbsp_server_fsm_allstate(struct osmo_fsm_inst *fi, uint32_t event, v
|
|||
case 0: /* CBS */
|
||||
/* TODO: delete any CBS state we have for this peer */
|
||||
/* TODO: re-send CBS messages we have matching the scope of the peer */
|
||||
LOGPCC(client, LOGL_NOTICE, "RESTART (CBS) but re-sending not implemented yet\n");
|
||||
LOGPCC(link, LOGL_NOTICE, "RESTART (CBS) but re-sending not implemented yet\n");
|
||||
break;
|
||||
case 1: /* ETWS */
|
||||
/* TODO: delete any ETWS state we have for this peer */
|
||||
/* TODO: re-send ETWS messages we have matching the scope of the peer */
|
||||
LOGPCC(client, LOGL_NOTICE, "RESTART (ETWS) but re-sending not implemented yet\n");
|
||||
LOGPCC(link, LOGL_NOTICE, "RESTART (ETWS) but re-sending not implemented yet\n");
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
@ -194,17 +194,17 @@ static void cbsp_server_fsm_allstate(struct osmo_fsm_inst *fi, uint32_t event, v
|
|||
|
||||
static void cbsp_server_fsm_cleanup(struct osmo_fsm_inst *fi, enum osmo_fsm_term_cause cause)
|
||||
{
|
||||
struct osmo_cbsp_cbc_client *client = (struct osmo_cbsp_cbc_client *) fi->priv;
|
||||
struct cbc_cbsp_link *link = (struct cbc_cbsp_link *) fi->priv;
|
||||
|
||||
if (client->conn)
|
||||
osmo_stream_srv_destroy(client->conn);
|
||||
llist_del(&client->list);
|
||||
client->fi = NULL;
|
||||
if (link->conn)
|
||||
osmo_stream_srv_destroy(link->conn);
|
||||
llist_del(&link->list);
|
||||
link->fi = NULL;
|
||||
|
||||
/* reparent the fsm_inst to the cbc as we're about to free() it's talloc
|
||||
* parent 'client' */
|
||||
* parent 'link' */
|
||||
talloc_steal(g_cbc, fi);
|
||||
talloc_free(client);
|
||||
talloc_free(link);
|
||||
}
|
||||
|
||||
static const struct osmo_fsm_state cbsp_server_fsm_states[] = {
|
||||
|
@ -273,7 +273,7 @@ static int get_msg_id(const struct osmo_cbsp_decoded *dec)
|
|||
}
|
||||
|
||||
/* message was received from remote CBSP peer (BSC) */
|
||||
int cbsp_cbc_client_rx_cb(struct osmo_cbsp_cbc_client *client, struct osmo_cbsp_decoded *dec)
|
||||
int cbc_cbsp_link_rx_cb(struct cbc_cbsp_link *link, struct osmo_cbsp_decoded *dec)
|
||||
{
|
||||
struct cbc_message *smscb;
|
||||
struct cbc_message_peer *mp;
|
||||
|
@ -282,32 +282,32 @@ int cbsp_cbc_client_rx_cb(struct osmo_cbsp_cbc_client *client, struct osmo_cbsp_
|
|||
/* messages without reference to a specific SMSCB message */
|
||||
switch (dec->msg_type) {
|
||||
case CBSP_MSGT_RESTART:
|
||||
osmo_fsm_inst_dispatch(client->fi, CBSP_SRV_E_RX_RESTART, dec);
|
||||
osmo_fsm_inst_dispatch(link->fi, CBSP_SRV_E_RX_RESTART, dec);
|
||||
return 0;
|
||||
case CBSP_MSGT_KEEP_ALIVE_COMPL:
|
||||
osmo_fsm_inst_dispatch(client->fi, CBSP_SRV_E_RX_KA_COMPL, dec);
|
||||
osmo_fsm_inst_dispatch(link->fi, CBSP_SRV_E_RX_KA_COMPL, dec);
|
||||
return 0;
|
||||
case CBSP_MSGT_FAILURE:
|
||||
LOGPCC(client, LOGL_ERROR, "CBSP FAILURE (bcast_msg_type=%u)\n",
|
||||
LOGPCC(link, LOGL_ERROR, "CBSP FAILURE (bcast_msg_type=%u)\n",
|
||||
dec->u.failure.bcast_msg_type);
|
||||
/* TODO: failure list */
|
||||
return 0;
|
||||
case CBSP_MSGT_ERROR_IND:
|
||||
LOGPCC(client, LOGL_ERROR, "CBSP ERROR_IND (cause=%u, msg_id=0x%04x)\n",
|
||||
LOGPCC(link, LOGL_ERROR, "CBSP ERROR_IND (cause=%u, msg_id=0x%04x)\n",
|
||||
dec->u.error_ind.cause,
|
||||
dec->u.error_ind.msg_id ? *dec->u.error_ind.msg_id : 0xffff);
|
||||
/* TODO: old/new serial number, channel_ind */
|
||||
return 0;
|
||||
case CBSP_MSGT_RESET_COMPL:
|
||||
return osmo_fsm_inst_dispatch(client->fi, CBSP_SRV_E_RX_RST_COMPL, dec);
|
||||
return osmo_fsm_inst_dispatch(link->fi, CBSP_SRV_E_RX_RST_COMPL, dec);
|
||||
case CBSP_MSGT_RESET_FAIL:
|
||||
return osmo_fsm_inst_dispatch(client->fi, CBSP_SRV_E_RX_RST_FAIL, dec);
|
||||
return osmo_fsm_inst_dispatch(link->fi, CBSP_SRV_E_RX_RST_FAIL, dec);
|
||||
case CBSP_MSGT_KEEP_ALIVE:
|
||||
case CBSP_MSGT_LOAD_QUERY_COMPL:
|
||||
case CBSP_MSGT_LOAD_QUERY_FAIL:
|
||||
case CBSP_MSGT_SET_DRX_COMPL:
|
||||
case CBSP_MSGT_SET_DRX_FAIL:
|
||||
LOGPCC(client, LOGL_ERROR, "unimplemented message %s\n",
|
||||
LOGPCC(link, LOGL_ERROR, "unimplemented message %s\n",
|
||||
get_value_string(cbsp_msg_type_names, dec->msg_type));
|
||||
return 0;
|
||||
default:
|
||||
|
@ -321,17 +321,17 @@ int cbsp_cbc_client_rx_cb(struct osmo_cbsp_cbc_client *client, struct osmo_cbsp_
|
|||
/* look-up smscb_message */
|
||||
smscb = cbc_message_by_id(msg_id);
|
||||
if (!smscb) {
|
||||
LOGPCC(client, LOGL_ERROR, "%s for unknown message-id 0x%04x\n",
|
||||
LOGPCC(link, LOGL_ERROR, "%s for unknown message-id 0x%04x\n",
|
||||
get_value_string(cbsp_msg_type_names, dec->msg_type), msg_id);
|
||||
/* TODO: inform peer? */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* look-up smscb_message_peer */
|
||||
mp = cbc_message_peer_get(smscb, client->peer);
|
||||
mp = cbc_message_peer_get(smscb, link->peer);
|
||||
if (!mp) {
|
||||
LOGPCC(client, LOGL_ERROR, "%s for message-id 0x%04x without peer %s\n",
|
||||
get_value_string(cbsp_msg_type_names, dec->msg_type), msg_id, client->peer->name);
|
||||
LOGPCC(link, LOGL_ERROR, "%s for message-id 0x%04x without peer %s\n",
|
||||
get_value_string(cbsp_msg_type_names, dec->msg_type), msg_id, link->peer->name);
|
||||
/* TODO: inform peer? */
|
||||
return 0;
|
||||
}
|
||||
|
@ -357,7 +357,7 @@ int cbsp_cbc_client_rx_cb(struct osmo_cbsp_cbc_client *client, struct osmo_cbsp_
|
|||
case CBSP_MSGT_MSG_STATUS_QUERY_FAIL:
|
||||
return osmo_fsm_inst_dispatch(mp->fi, SMSCB_E_CBSP_STATUS_NACK, dec);
|
||||
default:
|
||||
LOGPCC(client, LOGL_ERROR, "unknown message %s\n",
|
||||
LOGPCC(link, LOGL_ERROR, "unknown message %s\n",
|
||||
get_value_string(cbsp_msg_type_names, dec->msg_type));
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -137,7 +137,7 @@ int peer_new_cbc_message(struct cbc_peer *peer, struct cbc_message *cbcmsg)
|
|||
switch (peer->proto) {
|
||||
case CBC_PEER_PROTO_CBSP:
|
||||
/* skip peers without any current CBSP connection */
|
||||
if (!peer->client.cbsp) {
|
||||
if (!peer->link.cbsp) {
|
||||
LOGP(DCBSP, LOGL_NOTICE, "[%s] Tx CBSP: not connected\n",
|
||||
peer->name);
|
||||
return -ENOTCONN;
|
||||
|
@ -147,11 +147,11 @@ int peer_new_cbc_message(struct cbc_peer *peer, struct cbc_message *cbcmsg)
|
|||
peer->name);
|
||||
return -EINVAL;
|
||||
}
|
||||
cbsp_cbc_client_tx(peer->client.cbsp, cbsp);
|
||||
cbc_cbsp_link_tx(peer->link.cbsp, cbsp);
|
||||
break;
|
||||
case CBC_PEER_PROTO_SBcAP:
|
||||
/* skip peers without any current SBc-AP connection */
|
||||
if (!peer->client.sbcap) {
|
||||
if (!peer->link.sbcap) {
|
||||
LOGP(DSBcAP, LOGL_NOTICE, "[%s] Tx SBc-AP: not connected\n",
|
||||
peer->name);
|
||||
return -ENOTCONN;
|
||||
|
@ -161,7 +161,7 @@ int peer_new_cbc_message(struct cbc_peer *peer, struct cbc_message *cbcmsg)
|
|||
peer->name);
|
||||
return -EINVAL;
|
||||
}
|
||||
sbcap_cbc_client_tx(peer->client.sbcap, sbcap);
|
||||
cbc_sbcap_link_tx(peer->link.sbcap, sbcap);
|
||||
break;
|
||||
case CBC_PEER_PROTO_SABP:
|
||||
LOGP(DLGLOBAL, LOGL_ERROR, "Sending message to peer proto %s not implemented!\n",
|
||||
|
|
|
@ -41,25 +41,25 @@
|
|||
#include <osmocom/cbc/cbc_peer.h>
|
||||
#include <osmocom/cbc/debug.h>
|
||||
|
||||
const char *sbcap_cbc_client_name(const struct osmo_sbcap_cbc_client *client)
|
||||
const char *cbc_sbcap_link_name(const struct cbc_sbcap_link *link)
|
||||
{
|
||||
struct osmo_fd *ofd;
|
||||
OSMO_ASSERT(client);
|
||||
OSMO_ASSERT(link);
|
||||
|
||||
if (client->peer && client->peer->name) {
|
||||
return client->peer->name;
|
||||
if (link->peer && link->peer->name) {
|
||||
return link->peer->name;
|
||||
}
|
||||
|
||||
ofd = osmo_stream_srv_get_ofd(client->conn);
|
||||
ofd = osmo_stream_srv_get_ofd(link->conn);
|
||||
return osmo_sock_get_name2(ofd->fd);
|
||||
}
|
||||
|
||||
/* data from MME has arrived at CBC */
|
||||
static int sbcap_cbc_read_cb(struct osmo_stream_srv *conn)
|
||||
{
|
||||
struct osmo_stream_srv_link *link = osmo_stream_srv_get_master(conn);
|
||||
struct osmo_sbcap_cbc_client *client = osmo_stream_srv_get_data(conn);
|
||||
struct osmo_sbcap_cbc *cbc = osmo_stream_srv_link_get_data(link);
|
||||
struct osmo_stream_srv_link *srv_link = osmo_stream_srv_get_master(conn);
|
||||
struct cbc_sbcap_link *link = osmo_stream_srv_get_data(conn);
|
||||
struct cbc_sbcap_mgr *cbc = osmo_stream_srv_link_get_data(srv_link);
|
||||
struct osmo_fd *ofd = osmo_stream_srv_get_ofd(conn);
|
||||
SBcAP_SBC_AP_PDU_t *pdu;
|
||||
struct msgb *msg = msgb_alloc_c(g_cbc, 1500, "SBcAP-rx");
|
||||
|
@ -70,7 +70,7 @@ static int sbcap_cbc_read_cb(struct osmo_stream_srv *conn)
|
|||
/* read SBc-AP message from socket and process it */
|
||||
rc = sctp_recvmsg(ofd->fd, msgb_data(msg), msgb_tailroom(msg),
|
||||
NULL, NULL, &sinfo, &flags);
|
||||
LOGPSBCAPC(client, LOGL_DEBUG, "%s(): sctp_recvmsg() returned %d (flags=0x%x)\n",
|
||||
LOGPSBCAPC(link, LOGL_DEBUG, "%s(): sctp_recvmsg() returned %d (flags=0x%x)\n",
|
||||
__func__, rc, flags);
|
||||
if (rc < 0) {
|
||||
osmo_stream_srv_destroy(conn);
|
||||
|
@ -83,18 +83,18 @@ static int sbcap_cbc_read_cb(struct osmo_stream_srv *conn)
|
|||
|
||||
if (flags & MSG_NOTIFICATION) {
|
||||
union sctp_notification *notif = (union sctp_notification *) msgb_data(msg);
|
||||
LOGPSBCAPC(client, LOGL_DEBUG, "Rx sctp notif %s\n",
|
||||
LOGPSBCAPC(link, LOGL_DEBUG, "Rx sctp notif %s\n",
|
||||
osmo_sctp_sn_type_str(notif->sn_header.sn_type));
|
||||
switch (notif->sn_header.sn_type) {
|
||||
case SCTP_SHUTDOWN_EVENT:
|
||||
osmo_stream_srv_destroy(conn);
|
||||
break;
|
||||
case SCTP_ASSOC_CHANGE:
|
||||
LOGPSBCAPC(client, LOGL_DEBUG, "Rx sctp notif SCTP_ASSOC_CHANGE: %s\n",
|
||||
LOGPSBCAPC(link, LOGL_DEBUG, "Rx sctp notif SCTP_ASSOC_CHANGE: %s\n",
|
||||
osmo_sctp_assoc_chg_str(notif->sn_assoc_change.sac_state));
|
||||
break;
|
||||
default:
|
||||
LOGPSBCAPC(client, LOGL_DEBUG, "Rx sctp notif %s (%u)\n",
|
||||
LOGPSBCAPC(link, LOGL_DEBUG, "Rx sctp notif %s (%u)\n",
|
||||
osmo_sctp_sn_type_str(notif->sn_header.sn_type),
|
||||
notif->sn_header.sn_type);
|
||||
break;
|
||||
|
@ -105,16 +105,16 @@ static int sbcap_cbc_read_cb(struct osmo_stream_srv *conn)
|
|||
if (rc == 0)
|
||||
goto out;
|
||||
|
||||
LOGPSBCAPC(client, LOGL_DEBUG, "Received SBc-AP %s\n", msgb_hexdump(msg));
|
||||
LOGPSBCAPC(link, LOGL_DEBUG, "Received SBc-AP %s\n", msgb_hexdump(msg));
|
||||
|
||||
/* decode + dispatch message */
|
||||
pdu = sbcap_decode(msg);
|
||||
if (pdu) {
|
||||
LOGPSBCAPC(client, LOGL_INFO, "Received SBc-AP %d\n",
|
||||
LOGPSBCAPC(link, LOGL_INFO, "Received SBc-AP %d\n",
|
||||
pdu->present);
|
||||
cbc->rx_cb(client, pdu);
|
||||
cbc->rx_cb(link, pdu);
|
||||
} else {
|
||||
LOGPSBCAPC(client, LOGL_ERROR, "Unable to decode %s\n", msgb_hexdump(msg));
|
||||
LOGPSBCAPC(link, LOGL_ERROR, "Unable to decode %s\n", msgb_hexdump(msg));
|
||||
}
|
||||
out:
|
||||
msgb_free(msg);
|
||||
|
@ -124,79 +124,79 @@ out:
|
|||
/* connection from MME to CBC has been closed */
|
||||
static int sbcap_cbc_closed_cb(struct osmo_stream_srv *conn)
|
||||
{
|
||||
struct osmo_sbcap_cbc_client *client = osmo_stream_srv_get_data(conn);
|
||||
LOGPSBCAPC(client, LOGL_NOTICE, "connection closed\n");
|
||||
struct cbc_sbcap_link *link = osmo_stream_srv_get_data(conn);
|
||||
LOGPSBCAPC(link, LOGL_NOTICE, "connection closed\n");
|
||||
|
||||
if (client->peer)
|
||||
client->peer->client.sbcap = NULL;
|
||||
client->conn = NULL;
|
||||
if (client->fi)
|
||||
osmo_fsm_inst_dispatch(client->fi, SBcAP_SRV_E_CMD_CLOSE, NULL);
|
||||
if (link->peer)
|
||||
link->peer->link.sbcap = NULL;
|
||||
link->conn = NULL;
|
||||
if (link->fi)
|
||||
osmo_fsm_inst_dispatch(link->fi, SBcAP_SRV_E_CMD_CLOSE, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* new connection from MME has arrived at CBC */
|
||||
static int sbcap_cbc_accept_cb(struct osmo_stream_srv_link *link, int fd)
|
||||
static int sbcap_cbc_accept_cb(struct osmo_stream_srv_link *srv_link, int fd)
|
||||
{
|
||||
struct osmo_sbcap_cbc *cbc = osmo_stream_srv_link_get_data(link);
|
||||
struct osmo_sbcap_cbc_client *client = talloc_zero(cbc, struct osmo_sbcap_cbc_client);
|
||||
struct cbc_sbcap_mgr *cbc = osmo_stream_srv_link_get_data(srv_link);
|
||||
struct cbc_sbcap_link *link = talloc_zero(cbc, struct cbc_sbcap_link);
|
||||
char remote_ip[INET6_ADDRSTRLEN], portbuf[6];
|
||||
int remote_port;
|
||||
OSMO_ASSERT(client);
|
||||
OSMO_ASSERT(link);
|
||||
|
||||
remote_ip[0] = '\0';
|
||||
portbuf[0] = '\0';
|
||||
osmo_sock_get_ip_and_port(fd, remote_ip, sizeof(remote_ip), portbuf, sizeof(portbuf), false);
|
||||
remote_port = atoi(portbuf);
|
||||
|
||||
LOGP(DSBcAP, LOGL_NOTICE, "New SBc-AP client connection from %s:%u\n", remote_ip, remote_port);
|
||||
LOGP(DSBcAP, LOGL_NOTICE, "New SBc-AP link connection from %s:%u\n", remote_ip, remote_port);
|
||||
|
||||
client->conn = osmo_stream_srv_create(link, link, fd, sbcap_cbc_read_cb, sbcap_cbc_closed_cb, client);
|
||||
if (!client->conn) {
|
||||
link->conn = osmo_stream_srv_create(srv_link, srv_link, fd, sbcap_cbc_read_cb, sbcap_cbc_closed_cb, link);
|
||||
if (!link->conn) {
|
||||
LOGP(DSBcAP, LOGL_ERROR, "Unable to create stream server for %s:%d\n",
|
||||
remote_ip, remote_port);
|
||||
talloc_free(client);
|
||||
talloc_free(link);
|
||||
return -1;
|
||||
}
|
||||
client->fi = osmo_fsm_inst_alloc(&sbcap_server_fsm, client, client, LOGL_DEBUG, NULL);
|
||||
if (!client->fi) {
|
||||
LOGPSBCAPC(client, LOGL_ERROR, "Unable to allocate FSM\n");
|
||||
osmo_stream_srv_destroy(client->conn);
|
||||
talloc_free(client);
|
||||
link->fi = osmo_fsm_inst_alloc(&sbcap_server_fsm, link, link, LOGL_DEBUG, NULL);
|
||||
if (!link->fi) {
|
||||
LOGPSBCAPC(link, LOGL_ERROR, "Unable to allocate FSM\n");
|
||||
osmo_stream_srv_destroy(link->conn);
|
||||
talloc_free(link);
|
||||
return -1;
|
||||
}
|
||||
llist_add_tail(&client->list, &cbc->clients);
|
||||
llist_add_tail(&link->list, &cbc->clients);
|
||||
|
||||
/* Match client to peer */
|
||||
client->peer = cbc_peer_by_addr_proto(remote_ip, remote_port, CBC_PEER_PROTO_SBcAP);
|
||||
if (!client->peer) {
|
||||
/* Match link to peer */
|
||||
link->peer = cbc_peer_by_addr_proto(remote_ip, remote_port, CBC_PEER_PROTO_SBcAP);
|
||||
if (!link->peer) {
|
||||
if (g_cbc->config.permit_unknown_peers) {
|
||||
LOGPSBCAPC(client, LOGL_NOTICE, "Accepting unknown SBc-AP peer %s:%d\n",
|
||||
LOGPSBCAPC(link, LOGL_NOTICE, "Accepting unknown SBc-AP peer %s:%d\n",
|
||||
remote_ip, remote_port);
|
||||
client->peer = cbc_peer_create(NULL, CBC_PEER_PROTO_SBcAP);
|
||||
OSMO_ASSERT(client->peer);
|
||||
client->peer->unknown_dynamic_peer = true;
|
||||
link->peer = cbc_peer_create(NULL, CBC_PEER_PROTO_SBcAP);
|
||||
OSMO_ASSERT(link->peer);
|
||||
link->peer->unknown_dynamic_peer = true;
|
||||
} else {
|
||||
LOGPSBCAPC(client, LOGL_NOTICE, "Rejecting unknown SBc-AP peer %s:%d (not permitted)\n",
|
||||
LOGPSBCAPC(link, LOGL_NOTICE, "Rejecting unknown SBc-AP peer %s:%d (not permitted)\n",
|
||||
remote_ip, remote_port);
|
||||
osmo_stream_srv_destroy(client->conn);
|
||||
osmo_stream_srv_destroy(link->conn);
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
if (client->peer->client.sbcap) {
|
||||
LOGPSBCAPC(client, LOGL_ERROR, "We already have a connection for peer %s\n",
|
||||
client->peer->name);
|
||||
if (link->peer->link.sbcap) {
|
||||
LOGPSBCAPC(link, LOGL_ERROR, "We already have a connection for peer %s\n",
|
||||
link->peer->name);
|
||||
/* FIXME */
|
||||
}
|
||||
client->peer->client.sbcap = client;
|
||||
link->peer->link.sbcap = link;
|
||||
}
|
||||
|
||||
osmo_fsm_inst_dispatch(client->fi, SBcAP_SRV_E_CMD_RESET, NULL);
|
||||
osmo_fsm_inst_dispatch(link->fi, SBcAP_SRV_E_CMD_RESET, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void sbcap_cbc_client_tx(struct osmo_sbcap_cbc_client *client, SBcAP_SBC_AP_PDU_t *pdu)
|
||||
void cbc_sbcap_link_tx(struct cbc_sbcap_link *link, SBcAP_SBC_AP_PDU_t *pdu)
|
||||
{
|
||||
struct msgb *msg;
|
||||
|
||||
|
@ -205,31 +205,31 @@ void sbcap_cbc_client_tx(struct osmo_sbcap_cbc_client *client, SBcAP_SBC_AP_PDU_
|
|||
return;
|
||||
}
|
||||
|
||||
if (!client) {
|
||||
if (!link) {
|
||||
LOGP(DSBcAP, LOGL_NOTICE, "Cannot transmit msg: no connection\n");
|
||||
return;
|
||||
}
|
||||
|
||||
LOGPSBCAPC(client, LOGL_INFO, "Transmitting msg\n");
|
||||
OSMO_ASSERT(client->conn);
|
||||
LOGPSBCAPC(link, LOGL_INFO, "Transmitting msg\n");
|
||||
OSMO_ASSERT(link->conn);
|
||||
msg = sbcap_encode(pdu);
|
||||
if (!msg)
|
||||
goto ret_free;
|
||||
LOGPSBCAPC(client, LOGL_DEBUG, "Encoded message: %s\n", msgb_hexdump(msg));
|
||||
osmo_stream_srv_send(client->conn, msg);
|
||||
LOGPSBCAPC(link, LOGL_DEBUG, "Encoded message: %s\n", msgb_hexdump(msg));
|
||||
osmo_stream_srv_send(link->conn, msg);
|
||||
ret_free:
|
||||
sbcap_pdu_free(pdu);
|
||||
}
|
||||
|
||||
void sbcap_cbc_client_close(struct osmo_sbcap_cbc_client *client)
|
||||
void cbc_sbcap_link_close(struct cbc_sbcap_link *link)
|
||||
{
|
||||
osmo_stream_srv_destroy(client->conn);
|
||||
osmo_stream_srv_destroy(link->conn);
|
||||
}
|
||||
|
||||
/* initialize the CBC-side SBc-AP server */
|
||||
struct osmo_sbcap_cbc *sbcap_cbc_create(void *ctx)
|
||||
struct cbc_sbcap_mgr *cbc_sbcap_mgr_create(void *ctx)
|
||||
{
|
||||
struct osmo_sbcap_cbc *cbc = talloc_zero(ctx, struct osmo_sbcap_cbc);
|
||||
struct cbc_sbcap_mgr *cbc = talloc_zero(ctx, struct cbc_sbcap_mgr);
|
||||
int rc;
|
||||
int bind_port = g_cbc->config.sbcap.local_port;
|
||||
|
||||
|
@ -237,7 +237,7 @@ struct osmo_sbcap_cbc *sbcap_cbc_create(void *ctx)
|
|||
bind_port = SBcAP_SCTP_PORT;
|
||||
|
||||
OSMO_ASSERT(cbc);
|
||||
cbc->rx_cb = sbcap_cbc_client_rx_cb;
|
||||
cbc->rx_cb = cbc_sbcap_link_rx_cb;
|
||||
INIT_LLIST_HEAD(&cbc->clients);
|
||||
cbc->link = osmo_stream_srv_link_create(cbc);
|
||||
osmo_stream_srv_link_set_proto(cbc->link, IPPROTO_SCTP);
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
#define S(x) (1 << (x))
|
||||
|
||||
enum sbcap_server_state {
|
||||
/* initial state after client SCTP connection established */
|
||||
/* initial state after link SCTP connection established */
|
||||
SBcAP_SRV_S_INIT,
|
||||
/* normal operation (idle) */
|
||||
SBcAP_SRV_S_IDLE,
|
||||
|
@ -72,7 +72,7 @@ static void sbcap_server_s_idle(struct osmo_fsm_inst *fi, uint32_t event, void *
|
|||
|
||||
static void sbcap_server_fsm_allstate(struct osmo_fsm_inst *fi, uint32_t event, void *data)
|
||||
{
|
||||
struct osmo_sbcap_cbc_client *client = (struct osmo_sbcap_cbc_client *) fi->priv;
|
||||
struct cbc_sbcap_link *link = (struct cbc_sbcap_link *) fi->priv;
|
||||
//SBcAP_SBC_AP_PDU_t *pdu;
|
||||
|
||||
switch (event) {
|
||||
|
@ -83,7 +83,7 @@ static void sbcap_server_fsm_allstate(struct osmo_fsm_inst *fi, uint32_t event,
|
|||
//pdu = data;
|
||||
/* TODO: delete any CBS state we have for this peer */
|
||||
/* TODO: re-send messages we have matching the scope of the peer */
|
||||
LOGPSBCAPC(client, LOGL_NOTICE, "RESTART but re-sending not implemented yet\n");
|
||||
LOGPSBCAPC(link, LOGL_NOTICE, "RESTART but re-sending not implemented yet\n");
|
||||
break;
|
||||
default:
|
||||
OSMO_ASSERT(0);
|
||||
|
@ -92,17 +92,17 @@ static void sbcap_server_fsm_allstate(struct osmo_fsm_inst *fi, uint32_t event,
|
|||
|
||||
static void sbcap_server_fsm_cleanup(struct osmo_fsm_inst *fi, enum osmo_fsm_term_cause cause)
|
||||
{
|
||||
struct osmo_sbcap_cbc_client *client = (struct osmo_sbcap_cbc_client *) fi->priv;
|
||||
struct cbc_sbcap_link *link = (struct cbc_sbcap_link *) fi->priv;
|
||||
|
||||
if (client->conn)
|
||||
osmo_stream_srv_destroy(client->conn);
|
||||
llist_del(&client->list);
|
||||
client->fi = NULL;
|
||||
if (link->conn)
|
||||
osmo_stream_srv_destroy(link->conn);
|
||||
llist_del(&link->list);
|
||||
link->fi = NULL;
|
||||
|
||||
/* reparent the fsm_inst to the cbc as we're about to free() it's talloc
|
||||
* parent 'client' */
|
||||
* parent 'link' */
|
||||
talloc_steal(g_cbc, fi);
|
||||
talloc_free(client);
|
||||
talloc_free(link);
|
||||
}
|
||||
|
||||
static const struct osmo_fsm_state sbcap_server_fsm_states[] = {
|
||||
|
@ -146,7 +146,7 @@ static void *sbcap_as_find_ie(void *void_list, SBcAP_ProtocolIE_ID_t ie_id)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static SBcAP_Message_Identifier_t *get_msg_id_ie(struct osmo_sbcap_cbc_client *client,
|
||||
static SBcAP_Message_Identifier_t *get_msg_id_ie(struct cbc_sbcap_link *link,
|
||||
const SBcAP_SBC_AP_PDU_t *pdu)
|
||||
{
|
||||
A_SEQUENCE_OF(void) *as_pdu = NULL;
|
||||
|
@ -168,7 +168,7 @@ static SBcAP_Message_Identifier_t *get_msg_id_ie(struct osmo_sbcap_cbc_client *c
|
|||
return NULL;
|
||||
return &((SBcAP_Stop_Warning_Indication_IEs_t *)ie)->value.choice.Message_Identifier;
|
||||
default:
|
||||
LOGPSBCAPC(client, LOGL_ERROR, "get_msg_id initiatingMessage procedure=%ld not implemented\n",
|
||||
LOGPSBCAPC(link, LOGL_ERROR, "get_msg_id initiatingMessage procedure=%ld not implemented\n",
|
||||
pdu->choice.unsuccessfulOutcome.procedureCode);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -186,7 +186,7 @@ static SBcAP_Message_Identifier_t *get_msg_id_ie(struct osmo_sbcap_cbc_client *c
|
|||
return NULL;
|
||||
return &((SBcAP_Stop_Warning_Response_IEs_t *)ie)->value.choice.Message_Identifier;
|
||||
default:
|
||||
LOGPSBCAPC(client, LOGL_ERROR, "get_msg_id successfulOutcome procedure=%ld not implemented\n",
|
||||
LOGPSBCAPC(link, LOGL_ERROR, "get_msg_id successfulOutcome procedure=%ld not implemented\n",
|
||||
pdu->choice.unsuccessfulOutcome.procedureCode);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -194,7 +194,7 @@ static SBcAP_Message_Identifier_t *get_msg_id_ie(struct osmo_sbcap_cbc_client *c
|
|||
case SBcAP_SBC_AP_PDU_PR_unsuccessfulOutcome:
|
||||
switch (pdu->choice.unsuccessfulOutcome.procedureCode) {
|
||||
default:
|
||||
LOGPSBCAPC(client, LOGL_ERROR, "get_msg_id unsuccessfulOutcome procedure=%ld not implemented\n",
|
||||
LOGPSBCAPC(link, LOGL_ERROR, "get_msg_id unsuccessfulOutcome procedure=%ld not implemented\n",
|
||||
pdu->choice.unsuccessfulOutcome.procedureCode);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -204,20 +204,20 @@ static SBcAP_Message_Identifier_t *get_msg_id_ie(struct osmo_sbcap_cbc_client *c
|
|||
}
|
||||
}
|
||||
|
||||
static int get_msg_id(struct osmo_sbcap_cbc_client *client, const SBcAP_SBC_AP_PDU_t *pdu)
|
||||
static int get_msg_id(struct cbc_sbcap_link *link, const SBcAP_SBC_AP_PDU_t *pdu)
|
||||
{
|
||||
SBcAP_Message_Identifier_t *ie = get_msg_id_ie(client, pdu);
|
||||
SBcAP_Message_Identifier_t *ie = get_msg_id_ie(link, pdu);
|
||||
if (!ie)
|
||||
return -1;
|
||||
if (ie->size != 2) {
|
||||
LOGPSBCAPC(client, LOGL_ERROR, "get_msg_id wrong size %zu\n", ie->size);
|
||||
LOGPSBCAPC(link, LOGL_ERROR, "get_msg_id wrong size %zu\n", ie->size);
|
||||
return -1;
|
||||
}
|
||||
return osmo_load16be(ie->buf);
|
||||
}
|
||||
|
||||
/* message was received from remote SBcAP peer (BSC) */
|
||||
int sbcap_cbc_client_rx_cb(struct osmo_sbcap_cbc_client *client, SBcAP_SBC_AP_PDU_t *pdu)
|
||||
int cbc_sbcap_link_rx_cb(struct cbc_sbcap_link *link, SBcAP_SBC_AP_PDU_t *pdu)
|
||||
{
|
||||
struct cbc_message *smscb;
|
||||
struct cbc_message_peer *mp;
|
||||
|
@ -229,19 +229,19 @@ int sbcap_cbc_client_rx_cb(struct osmo_sbcap_cbc_client *client, SBcAP_SBC_AP_PD
|
|||
switch (pdu->choice.initiatingMessage.procedureCode) {
|
||||
case SBcAP_ProcedureId_Write_Replace_Warning:
|
||||
case SBcAP_ProcedureId_Stop_Warning:
|
||||
LOGPSBCAPC(client, LOGL_ERROR,
|
||||
LOGPSBCAPC(link, LOGL_ERROR,
|
||||
"SBcAP initiatingMessage procedure=%ld MME->CBC not expected\n",
|
||||
pdu->choice.initiatingMessage.procedureCode);
|
||||
return -EINVAL;
|
||||
case SBcAP_ProcedureId_PWS_Restart_Indication:
|
||||
return osmo_fsm_inst_dispatch(client->fi, SBcAP_SRV_E_RX_RESTART, pdu);
|
||||
return osmo_fsm_inst_dispatch(link->fi, SBcAP_SRV_E_RX_RESTART, pdu);
|
||||
case SBcAP_ProcedureId_Stop_Warning_Indication:
|
||||
case SBcAP_ProcedureId_Write_Replace_Warning_Indication:
|
||||
break; /* Handle msg id below */
|
||||
case SBcAP_ProcedureId_Error_Indication:
|
||||
case SBcAP_ProcedureId_PWS_Failure_Indication:
|
||||
default:
|
||||
LOGPSBCAPC(client, LOGL_ERROR, "SBcAP initiatingMessage procedure=%ld not implemented?\n",
|
||||
LOGPSBCAPC(link, LOGL_ERROR, "SBcAP initiatingMessage procedure=%ld not implemented?\n",
|
||||
pdu->choice.initiatingMessage.procedureCode);
|
||||
return 0;
|
||||
}
|
||||
|
@ -249,7 +249,7 @@ int sbcap_cbc_client_rx_cb(struct osmo_sbcap_cbc_client *client, SBcAP_SBC_AP_PD
|
|||
case SBcAP_SBC_AP_PDU_PR_successfulOutcome:
|
||||
switch (pdu->choice.successfulOutcome.procedureCode) {
|
||||
default:
|
||||
LOGPSBCAPC(client, LOGL_INFO, "SBcAP SuccessfulOutcome procedure=%ld\n",
|
||||
LOGPSBCAPC(link, LOGL_INFO, "SBcAP SuccessfulOutcome procedure=%ld\n",
|
||||
pdu->choice.successfulOutcome.procedureCode);
|
||||
break;
|
||||
}
|
||||
|
@ -257,37 +257,37 @@ int sbcap_cbc_client_rx_cb(struct osmo_sbcap_cbc_client *client, SBcAP_SBC_AP_PD
|
|||
case SBcAP_SBC_AP_PDU_PR_unsuccessfulOutcome:
|
||||
switch (pdu->choice.unsuccessfulOutcome.procedureCode) {
|
||||
default:
|
||||
LOGPSBCAPC(client, LOGL_ERROR, "SBcAP UnsuccessfulOutcome procedure=%ld\n",
|
||||
LOGPSBCAPC(link, LOGL_ERROR, "SBcAP UnsuccessfulOutcome procedure=%ld\n",
|
||||
pdu->choice.unsuccessfulOutcome.procedureCode);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case SBcAP_SBC_AP_PDU_PR_NOTHING:
|
||||
default:
|
||||
LOGPSBCAPC(client, LOGL_ERROR, "Rx SBc-AP unexpected message type %d\n",
|
||||
LOGPSBCAPC(link, LOGL_ERROR, "Rx SBc-AP unexpected message type %d\n",
|
||||
pdu->present);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* messages with reference to a specific SMSCB message handled below*/
|
||||
msg_id = get_msg_id(client, pdu);
|
||||
msg_id = get_msg_id(link, pdu);
|
||||
OSMO_ASSERT(msg_id >= 0);
|
||||
|
||||
/* look-up smscb_message */
|
||||
smscb = cbc_message_by_id(msg_id);
|
||||
if (!smscb) {
|
||||
LOGPSBCAPC(client, LOGL_ERROR, "Rx SBc-AP msg for unknown message-id 0x%04x\n",
|
||||
LOGPSBCAPC(link, LOGL_ERROR, "Rx SBc-AP msg for unknown message-id 0x%04x\n",
|
||||
msg_id);
|
||||
/* TODO: inform peer? */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* look-up smscb_message_peer */
|
||||
mp = cbc_message_peer_get(smscb, client->peer);
|
||||
mp = cbc_message_peer_get(smscb, link->peer);
|
||||
if (!mp) {
|
||||
LOGPSBCAPC(client, LOGL_ERROR, "Rx SBc-AP msg for message-id 0x%04x without peer %s\n",
|
||||
msg_id, client->peer->name);
|
||||
LOGPSBCAPC(link, LOGL_ERROR, "Rx SBc-AP msg for message-id 0x%04x without peer %s\n",
|
||||
msg_id, link->peer->name);
|
||||
/* TODO: inform peer? */
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -362,7 +362,7 @@ static void smscb_p_fsm_active(struct osmo_fsm_inst *fi, uint32_t event, void *d
|
|||
/* TODO: we assume that the replace will always affect all original cells */
|
||||
cbsp_append_cell_list(&cbsp->u.write_replace.cell_list, cbsp, mp);
|
||||
// TODO: ALL OTHER DATA
|
||||
cbsp_cbc_client_tx(mp->peer->client.cbsp, cbsp);
|
||||
cbc_cbsp_link_tx(mp->peer->link.cbsp, cbsp);
|
||||
osmo_fsm_inst_state_chg(fi, SMSCB_S_WAIT_REPLACE_ACK, 10, T_WAIT_REPLACE_ACK);
|
||||
break;
|
||||
case SMSCB_E_STATUS: /* send MSG-STATUS-QUERY to BSC */
|
||||
|
@ -372,7 +372,7 @@ static void smscb_p_fsm_active(struct osmo_fsm_inst *fi, uint32_t event, void *d
|
|||
cbsp->u.msg_status_query.old_serial_nr = mp->cbcmsg->msg.serial_nr;
|
||||
cbsp_append_cell_list(&cbsp->u.msg_status_query.cell_list, cbsp, mp);
|
||||
cbsp->u.msg_status_query.channel_ind = CBSP_CHAN_IND_BASIC;
|
||||
cbsp_cbc_client_tx(mp->peer->client.cbsp, cbsp);
|
||||
cbc_cbsp_link_tx(mp->peer->link.cbsp, cbsp);
|
||||
osmo_fsm_inst_state_chg(fi, SMSCB_S_WAIT_STATUS_ACK, 10, T_WAIT_STATUS_ACK);
|
||||
break;
|
||||
default:
|
||||
|
@ -558,11 +558,11 @@ static void smscb_p_fsm_allstate(struct osmo_fsm_inst *fi, uint32_t event, void
|
|||
OSMO_ASSERT(cbsp->u.kill.channel_ind);
|
||||
*(cbsp->u.kill.channel_ind) = CBSP_CHAN_IND_BASIC;
|
||||
}
|
||||
cbsp_cbc_client_tx(mp->peer->client.cbsp, cbsp);
|
||||
cbc_cbsp_link_tx(mp->peer->link.cbsp, cbsp);
|
||||
break;
|
||||
case CBC_PEER_PROTO_SBcAP:
|
||||
if ((sbcap = sbcap_gen_stop_warning_req(mp->peer, mp->cbcmsg))) {
|
||||
sbcap_cbc_client_tx(mp->peer->client.sbcap, sbcap);
|
||||
cbc_sbcap_link_tx(mp->peer->link.sbcap, sbcap);
|
||||
} else {
|
||||
LOGP(DSBcAP, LOGL_ERROR,
|
||||
"[%s] Tx SBc-AP Stop-Warning-Request: msg gen failed\n",
|
||||
|
|
Loading…
Reference in New Issue