mirror of
https://gitea.osmocom.org/cellular-infrastructure/osmo-cbc.git
synced 2025-10-23 08:22:19 +00:00
WIP
Change-Id: I240b4be2fbb316e423d1bf366061b08912814011
This commit is contained in:
@@ -110,6 +110,8 @@ enum cbc_message_scope {
|
||||
struct cbc_message_peer {
|
||||
struct llist_head list; /* lined to cbc_message.peers */
|
||||
|
||||
/* 'cbcmsg' is not really needed, as the fsm instance parent points to
|
||||
* the fsm instance of cbc_message, so we could also dereference those */
|
||||
struct cbc_message *cbcmsg; /* the SMSCB this relates to */
|
||||
struct cbc_peer *peer; /* the peer thos relates to */
|
||||
struct osmo_fsm_inst *fi; /* the FSM instance representing our state */
|
||||
|
@@ -20,12 +20,14 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <getopt.h>
|
||||
#include <signal.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <osmocom/core/stats.h>
|
||||
#include <osmocom/core/select.h>
|
||||
@@ -204,8 +206,10 @@ int main(int argc, char **argv)
|
||||
|
||||
rest_api_init(tall_rest_ctx, 12345);
|
||||
|
||||
LOGP(DREST, LOGL_INFO, "Main thread tid: %d\n", gettid());
|
||||
g_cbc->it_q.rest2main = osmo_it_q_alloc(g_cbc, "rest2main", 10, rest2main_read_cb, NULL);
|
||||
OSMO_ASSERT(g_cbc->it_q.rest2main);
|
||||
osmo_fd_register(&g_cbc->it_q.rest2main->event_ofd);
|
||||
|
||||
signal(SIGUSR1, &signal_handler);
|
||||
signal(SIGUSR2, &signal_handler);
|
||||
|
@@ -149,6 +149,12 @@ static int cbsp_cbc_accept_cb(struct osmo_stream_srv_link *link, int fd)
|
||||
/* FIXME: further cleanup needed? or does close_cb handle everything? */
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
if (client->peer->client.cbsp) {
|
||||
LOGPCC(client, LOGL_ERROR, "We already have a connection for peer %s\n");
|
||||
/* FIXME */
|
||||
}
|
||||
client->peer->client.cbsp = client;
|
||||
}
|
||||
|
||||
LOGPCC(client, LOGL_INFO, "New CBSP client connection\n");
|
||||
@@ -163,8 +169,8 @@ void cbsp_cbc_client_tx(struct osmo_cbsp_cbc_client *client, struct osmo_cbsp_de
|
||||
LOGPCC(client, LOGL_INFO, "Transmitting %s\n",
|
||||
get_value_string(cbsp_msg_type_names, cbsp->msg_type));
|
||||
if (!msg) {
|
||||
LOGPCC(client, LOGL_ERROR, "Failed to encode CBSP %s\n",
|
||||
get_value_string(cbsp_msg_type_names, cbsp->msg_type));
|
||||
LOGPCC(client, 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;
|
||||
}
|
||||
|
@@ -25,18 +25,20 @@
|
||||
|
||||
#include "charset.h"
|
||||
|
||||
/* return number of output bytes written */
|
||||
int charset_utf8_to_gsm7(char *out, size_t out_len, const char *in, size_t in_len)
|
||||
{
|
||||
/* FIXME: implement this */
|
||||
osmo_strlcpy(out, in, out_len);
|
||||
return 0;
|
||||
return in_len;
|
||||
}
|
||||
|
||||
/* return number of output bytes written */
|
||||
int charset_gsm7_to_utf8(char *out, size_t out_len, const char *in, size_t in_len)
|
||||
{
|
||||
/* FIXME: implement this */
|
||||
osmo_strlcpy(out, in, out_len);
|
||||
return 0;
|
||||
return in_len;
|
||||
}
|
||||
|
||||
|
||||
|
@@ -32,6 +32,7 @@ void rest_api_fin(void);
|
||||
void cbc_vty_init(void);
|
||||
|
||||
/* message_handling.c */
|
||||
struct cbc_message *cbc_message_alloc(void *ctx, const struct cbc_message *cbcmsg);
|
||||
int cbc_message_new(const struct cbc_message *cbcmsg);
|
||||
void cbc_message_delete(struct cbc_message *cbcmsg);
|
||||
struct cbc_message *cbc_message_by_id(uint16_t message_id);
|
||||
|
@@ -68,7 +68,7 @@ struct osmo_cbsp_decoded *cbcmsg_to_cbsp(void *ctx, const struct cbc_message *cb
|
||||
wrepl->new_serial_nr = smscb->serial_nr;
|
||||
/* FIXME: old? */
|
||||
/* Cell list */
|
||||
rc = cbcmsg_to_cbsp_cell_list(smscb, &wrepl->cell_list, cbcmsg);
|
||||
rc = cbcmsg_to_cbsp_cell_list(cbcmsg, &wrepl->cell_list, cbcmsg);
|
||||
if (rc < 0) {
|
||||
talloc_free(cbsp);
|
||||
return NULL;
|
||||
@@ -84,6 +84,7 @@ struct osmo_cbsp_decoded *cbcmsg_to_cbsp(void *ctx, const struct cbc_message *cb
|
||||
wrepl->u.cbs.rep_period = cbcmsg->rep_period;
|
||||
wrepl->u.cbs.num_bcast_req = cbcmsg->num_bcast;
|
||||
wrepl->u.cbs.dcs = smscb->cbs.dcs;
|
||||
INIT_LLIST_HEAD(&wrepl->u.cbs.msg_content);
|
||||
for (i = 0; i < smscb->cbs.num_pages; i++) {
|
||||
struct osmo_cbsp_content *ce = talloc_zero(cbsp, struct osmo_cbsp_content);
|
||||
// FIXME: ce->user_len =
|
||||
@@ -134,6 +135,9 @@ int cbc_message_new(const struct cbc_message *orig)
|
||||
struct cbc_message *cbcmsg = cbc_message_alloc(g_cbc, orig);
|
||||
struct cbc_peer *peer;
|
||||
|
||||
if (!cbcmsg)
|
||||
return -ENOMEM;
|
||||
|
||||
OSMO_ASSERT(llist_empty(&cbcmsg->peers));
|
||||
|
||||
/* iterate over all peers */
|
||||
|
@@ -209,6 +209,15 @@ static int json2serial_nr(uint16_t *out, json_t *jser_nr, const char **errstr)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* compute the number of pages needed for number of octets */
|
||||
static unsigned int pages_from_octets(int n_octets)
|
||||
{
|
||||
unsigned int n_pages = n_octets / SMSCB_RAW_PAGE_LEN;
|
||||
if (n_octets % SMSCB_RAW_PAGE_LEN)
|
||||
n_pages++;
|
||||
return n_pages;
|
||||
}
|
||||
|
||||
/* parse a smscb.schema.json/payload_decoded type */
|
||||
static int parse_payload_decoded(struct smscb_message *out, json_t *jtmp, const char **errstr)
|
||||
{
|
||||
@@ -266,11 +275,15 @@ static int parse_payload_decoded(struct smscb_message *out, json_t *jtmp, const
|
||||
/* convert from UTF-8 input to GSM 7bit output */
|
||||
rc = charset_utf8_to_gsm7((char *)out->cbs.data, sizeof(out->cbs.data),
|
||||
data_utf8_str, strlen(data_utf8_str));
|
||||
if (rc > 0)
|
||||
out->cbs.num_pages = pages_from_octets(rc);
|
||||
} else if (!strcmp(cset_str, "8bit")) {
|
||||
/* Determine DCS based on UDH + message class */
|
||||
out->cbs.dcs = 0xF4 | (dcs_class & 3);
|
||||
/* copy 8bit data over (hex -> binary conversion) */
|
||||
rc = osmo_hexparse(data_utf8_str, (uint8_t *)out->cbs.data, sizeof(out->cbs.data));
|
||||
if (rc > 0)
|
||||
out->cbs.num_pages = pages_from_octets(rc);
|
||||
} else if (!strcmp(cset_str, "ucs2")) {
|
||||
if (lang_str) {
|
||||
/* TODO: we must encode it in the first two octets */
|
||||
@@ -278,6 +291,8 @@ static int parse_payload_decoded(struct smscb_message *out, json_t *jtmp, const
|
||||
/* convert from UTF-8 input to UCS2 output */
|
||||
rc = charset_utf8_to_ucs2((char *) out->cbs.data, sizeof(out->cbs.data),
|
||||
data_utf8_str, strlen(data_utf8_str));
|
||||
if (rc > 0)
|
||||
out->cbs.num_pages = pages_from_octets(rc);
|
||||
} else {
|
||||
*errstr = "Invalid 'character_set'";
|
||||
return -EINVAL;
|
||||
@@ -445,16 +460,17 @@ static int json2cbc_message(struct cbc_message *out, void *ctx, json_t *in, cons
|
||||
/* Repetition Period (O) */
|
||||
jtmp = json_object_get(in, "repetition_period");
|
||||
if (jtmp) {
|
||||
/* FIXME */
|
||||
}
|
||||
|
||||
/* Number of Broadcasts (O) */
|
||||
rc = json_get_integer_range(&tmp, in, "number_of_broadcasts", 0, 65535);
|
||||
rc = json_get_integer_range(&tmp, in, "num_of_bcast", 0, 65535);
|
||||
if (rc == 0)
|
||||
out->num_bcast = tmp;
|
||||
else if (rc == -ENOENT)
|
||||
out->num_bcast = 0; /* unlimited */
|
||||
else {
|
||||
*errstr = "CBCMSG 'number_of_broadcasts' out of range";
|
||||
*errstr = "CBCMSG 'num_of_bcast' out of range";
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
@@ -20,6 +20,9 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <pthread.h>
|
||||
@@ -51,7 +54,7 @@ int rest_it_op_send_and_wait(struct rest_it_op *op, unsigned int wait_sec)
|
||||
struct timespec ts;
|
||||
int rc = 0;
|
||||
|
||||
LOGP(DREST, LOGL_DEBUG, "rest_it_op enqueue\n");
|
||||
LOGP(DREST, LOGL_DEBUG, "rest_it_op enqueue from %u\n", gettid());
|
||||
|
||||
rc = osmo_it_q_enqueue(g_cbc->it_q.rest2main, op, list);
|
||||
if (rc < 0)
|
||||
@@ -90,6 +93,8 @@ void rest2main_read_cb(struct osmo_it_q *q, void *item)
|
||||
struct rest_it_op *op = item;
|
||||
struct cbc_message *cbc_msg;
|
||||
|
||||
LOGP(DREST, LOGL_DEBUG, "%s() from %u\n", __func__, gettid());
|
||||
|
||||
/* FIXME: look up related message and dispatch to message FSM,
|
||||
* which will eventually call pthread_cond_signal(&op->cond) */
|
||||
|
||||
|
@@ -344,17 +344,23 @@ struct cbc_message *cbc_message_alloc(void *ctx, const struct cbc_message *orig_
|
||||
|
||||
snprintf(idbuf, sizeof(idbuf), "%s-%u", orig_msg->cbe_name, orig_msg->msg.message_id);
|
||||
fi = osmo_fsm_inst_alloc(&smscb_fsm, ctx, NULL, LOGL_INFO, idbuf);
|
||||
if (!fi)
|
||||
if (!fi) {
|
||||
LOGP(DCBSP, LOGL_ERROR, "Cannot allocate cbc_message fsm\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* copy data from original message */
|
||||
smscb = talloc_zero(fi, struct cbc_message);
|
||||
smscb = talloc(fi, struct cbc_message);
|
||||
if (!smscb) {
|
||||
LOGP(DCBSP, LOGL_ERROR, "Cannot allocate cbc_message\n");
|
||||
osmo_fsm_inst_term(fi, OSMO_FSM_TERM_ERROR, NULL);
|
||||
return NULL;
|
||||
}
|
||||
/* copy data from original message */
|
||||
memcpy(smscb, orig_msg, sizeof(*smscb));
|
||||
/* initialize other members */
|
||||
INIT_LLIST_HEAD(&smscb->peers);
|
||||
smscb->fi = fi;
|
||||
smscb->it_op = NULL;
|
||||
|
||||
fi->priv = smscb;
|
||||
|
||||
@@ -363,3 +369,8 @@ struct cbc_message *cbc_message_alloc(void *ctx, const struct cbc_message *orig_
|
||||
|
||||
return smscb;
|
||||
}
|
||||
|
||||
__attribute__((constructor)) smscb_fsm_constructor(void)
|
||||
{
|
||||
OSMO_ASSERT(osmo_fsm_register(&smscb_fsm) == 0);
|
||||
}
|
||||
|
@@ -537,6 +537,10 @@ struct cbc_message_peer *smscb_peer_fsm_alloc(struct cbc_peer *peer, struct cbc_
|
||||
return NULL;
|
||||
}
|
||||
mp->peer = peer;
|
||||
mp->cbcmsg = cbcmsg;
|
||||
INIT_LLIST_HEAD(&mp->cell_list);
|
||||
INIT_LLIST_HEAD(&mp->fail_list);
|
||||
INIT_LLIST_HEAD(&mp->num_compl_list);
|
||||
|
||||
/* link message_peer with its FSM instance */
|
||||
fi->priv = mp;
|
||||
|
Reference in New Issue
Block a user