pespin has uploaded this change for review. ( https://gerrit.osmocom.org/c/osmo-cbc/+/28718 )
Change subject: Avoid changing peer's protocol once set ......................................................................
Avoid changing peer's protocol once set
Let's explicitly not support this feature, since it makes code a lot more complex for no good reason. If a peer is created/confgiured with a given protocol, it should be kept forever. If the user wants to change the protocol, she can do so by removign the peer and re-adding it through the VTY.
Ideally the protocol would be in the "peer" VTY command, but it's given as a separate command under its now, which makes stuff a bit more difficult to handle in code.
Change-Id: I47756dddd8f9b8450ba14c914614fd2391d5486e --- M include/osmocom/cbc/cbc_peer.h M include/osmocom/cbc/debug.h M src/cbc_main.c M src/cbc_peer.c M src/cbc_vty.c M src/cbsp_link.c M src/sbcap_link.c 7 files changed, 47 insertions(+), 7 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/osmo-cbc refs/changes/18/28718/1
diff --git a/include/osmocom/cbc/cbc_peer.h b/include/osmocom/cbc/cbc_peer.h index 785ea09..bc1ae6a 100644 --- a/include/osmocom/cbc/cbc_peer.h +++ b/include/osmocom/cbc/cbc_peer.h @@ -14,6 +14,7 @@ *********************************************************************************/
enum cbc_peer_protocol { + CBC_PEER_PROTO_UNSET, CBC_PEER_PROTO_CBSP, CBC_PEER_PROTO_SABP, CBC_PEER_PROTO_SBcAP @@ -38,7 +39,8 @@
extern const struct value_string cbc_peer_proto_name[];
-struct cbc_peer *cbc_peer_create(const char *name, enum cbc_peer_protocol proto); +struct cbc_peer *cbc_peer_create(const char *name); +int cbc_peer_set_proto(struct cbc_peer *peer, enum cbc_peer_protocol proto); void cbc_peer_remove(struct cbc_peer *peer);
struct cbc_peer *cbc_peer_by_name(const char *name); diff --git a/include/osmocom/cbc/debug.h b/include/osmocom/cbc/debug.h index 1ec0a8e..025419e 100644 --- a/include/osmocom/cbc/debug.h +++ b/include/osmocom/cbc/debug.h @@ -1,6 +1,7 @@ #pragma once
enum { + DMAIN, DCBSP, DSBcAP, DREST, diff --git a/src/cbc_main.c b/src/cbc_main.c index a670722..836982a 100644 --- a/src/cbc_main.c +++ b/src/cbc_main.c @@ -55,6 +55,13 @@ struct cbc *g_cbc;
static const struct log_info_cat log_info_cat[] = { + [DMAIN] = { + .name = "DMAIN", + .description = "Main logging category", + .color = "\033[1;30m", + .enabled = 1, + .loglevel = LOGL_NOTICE, + }, [DCBSP] = { .name = "DCBSP", .description = "Cell Broadcast Service Protocol (CBC-BSC)", diff --git a/src/cbc_peer.c b/src/cbc_peer.c index e8b79f9..d130c52 100644 --- a/src/cbc_peer.c +++ b/src/cbc_peer.c @@ -32,8 +32,10 @@ #include <osmocom/cbc/cbc_peer.h> #include <osmocom/cbc/cbsp_link.h> #include <osmocom/cbc/sbcap_link.h> +#include <osmocom/cbc/debug.h>
const struct value_string cbc_peer_proto_name[] = { + { CBC_PEER_PROTO_UNSET, "UNSET" }, { CBC_PEER_PROTO_CBSP, "CBSP" }, { CBC_PEER_PROTO_SABP, "SABP" }, { CBC_PEER_PROTO_SBcAP, "SBc-AP" }, @@ -41,7 +43,7 @@ };
/* create a new cbc_peer */ -struct cbc_peer *cbc_peer_create(const char *name, enum cbc_peer_protocol proto) +struct cbc_peer *cbc_peer_create(const char *name) { struct cbc_peer *peer; if (name && cbc_peer_by_name(name)) @@ -51,13 +53,27 @@ if (!peer) return NULL;
- peer->proto = proto; peer->name = talloc_strdup(peer, name); llist_add_tail(&peer->list, &g_cbc->peers);
return peer; }
+int cbc_peer_set_proto(struct cbc_peer *peer, enum cbc_peer_protocol proto) +{ + OSMO_ASSERT(proto != CBC_PEER_PROTO_UNSET); + if (peer->proto != CBC_PEER_PROTO_UNSET && peer->proto != proto) { + LOGP(DMAIN, LOGL_ERROR, + "Cannot set new protocol %s on peer with already assigned protocol %s. " + "The peer must be re-created.\n", + get_value_string(cbc_peer_proto_name, proto), + get_value_string(cbc_peer_proto_name, peer->proto)); + return -EINVAL; + } + peer->proto = proto; + return 0; +} + /* remove a cbc_peer */ void cbc_peer_remove(struct cbc_peer *peer) { diff --git a/src/cbc_vty.c b/src/cbc_vty.c index 36d646d..aea1ceb 100644 --- a/src/cbc_vty.c +++ b/src/cbc_vty.c @@ -38,6 +38,7 @@ #include <osmocom/cbc/sbcap_link.h>
static const struct value_string cbc_peer_proto_name_vty[] = { + { CBC_PEER_PROTO_UNSET, "unset" }, { CBC_PEER_PROTO_CBSP, "cbsp" }, { CBC_PEER_PROTO_SABP, "sabp" }, { CBC_PEER_PROTO_SBcAP, "sbcap" }, @@ -52,6 +53,8 @@ unsigned int i;
switch (peer->proto) { + case CBC_PEER_PROTO_UNSET: + break; case CBC_PEER_PROTO_CBSP: if (peer->link.cbsp) state = osmo_fsm_inst_state_name(peer->link.cbsp->fi); @@ -528,7 +531,7 @@
peer = cbc_peer_by_name(argv[0]); if (!peer) - peer = cbc_peer_create(argv[0], CBC_PEER_PROTO_CBSP); + peer = cbc_peer_create(argv[0]); if (!peer) return CMD_WARNING;
@@ -560,7 +563,16 @@ "Cell Broadcast Service Protocol (GSM)\n") { struct cbc_peer *peer = (struct cbc_peer *) vty->index; - peer->proto = get_string_value(cbc_peer_proto_name_vty, argv[0]); + enum cbc_peer_protocol proto = get_string_value(cbc_peer_proto_name_vty, argv[0]); + int rc = cbc_peer_set_proto(peer, proto); + if (rc < 0) { + vty_out(vty, "%% Cannot set new protocol %s on peer with already assigned protocol %s. " + "The peer must be re-created.%s", + get_value_string(cbc_peer_proto_name, proto), + get_value_string(cbc_peer_proto_name, peer->proto), + VTY_NEWLINE); + return CMD_WARNING; + } return CMD_SUCCESS; }
diff --git a/src/cbsp_link.c b/src/cbsp_link.c index cd1c308..9f94a00 100644 --- a/src/cbsp_link.c +++ b/src/cbsp_link.c @@ -167,8 +167,9 @@ } LOGP(DCBSP, LOGL_NOTICE, "Accepting unknown CBSP peer %s:%d\n", remote_ip, remote_port); - peer = cbc_peer_create(NULL, CBC_PEER_PROTO_CBSP); + peer = cbc_peer_create(NULL); OSMO_ASSERT(peer); + OSMO_ASSERT(cbc_peer_set_proto(peer, CBC_PEER_PROTO_CBSP) == 0); peer->unknown_dynamic_peer = true; } if (peer->link.cbsp) { diff --git a/src/sbcap_link.c b/src/sbcap_link.c index 9194509..d6aba7e 100644 --- a/src/sbcap_link.c +++ b/src/sbcap_link.c @@ -195,8 +195,9 @@ } LOGP(DSBcAP, LOGL_NOTICE, "Accepting unknown SBc-AP peer %s:%d\n", remote_ip, remote_port); - peer = cbc_peer_create(NULL, CBC_PEER_PROTO_SBcAP); + peer = cbc_peer_create(NULL); OSMO_ASSERT(peer); + OSMO_ASSERT(cbc_peer_set_proto(peer, CBC_PEER_PROTO_SBcAP) == 0); peer->unknown_dynamic_peer = true; } if (peer->link.sbcap) {