diff options
author | Holger Hans Peter Freyther <holger@moiji-mobile.com> | 2017-11-09 09:15:37 +0100 |
---|---|---|
committer | Holger Hans Peter Freyther <holger@moiji-mobile.com> | 2017-12-03 12:58:52 +0000 |
commit | a8726d977a67459e7bf314b4b69283f65e45cbf0 (patch) | |
tree | b24ecdf77a199e24d2e9286f8517e59686c67eb7 /src/host/layer23 | |
parent | 04754e88899c58051ef1a0b0602261f033609dce (diff) |
mobile: Begin with a primitive interface on top of the code
We want the script interface to interface through a primitive
interface. This will allow to move it to a different thread or
a process in the future. The script interface will just use the
primitives.
It is not clear how "sap" will be used here. I am keeping it
at 0 right now. The first primitive is starting a timer with a
request and then getting an indication as a response.
Change-Id: Id2456b7fae35546553c4805f12a40c0812d9255c
Diffstat (limited to 'src/host/layer23')
-rw-r--r-- | src/host/layer23/include/osmocom/bb/common/logging.h | 1 | ||||
-rw-r--r-- | src/host/layer23/include/osmocom/bb/mobile/Makefile.am | 2 | ||||
-rw-r--r-- | src/host/layer23/include/osmocom/bb/mobile/primitives.h | 48 | ||||
-rw-r--r-- | src/host/layer23/src/common/logging.c | 6 | ||||
-rw-r--r-- | src/host/layer23/src/mobile/Makefile.am | 2 | ||||
-rw-r--r-- | src/host/layer23/src/mobile/main.c | 2 | ||||
-rw-r--r-- | src/host/layer23/src/mobile/primitives.c | 135 |
7 files changed, 193 insertions, 3 deletions
diff --git a/src/host/layer23/include/osmocom/bb/common/logging.h b/src/host/layer23/include/osmocom/bb/common/logging.h index efe493d0..fb1229ef 100644 --- a/src/host/layer23/include/osmocom/bb/common/logging.h +++ b/src/host/layer23/include/osmocom/bb/common/logging.h @@ -23,6 +23,7 @@ enum { DSIM, DGPS, DMOB, + DPRIM, }; extern const struct log_info log_info; diff --git a/src/host/layer23/include/osmocom/bb/mobile/Makefile.am b/src/host/layer23/include/osmocom/bb/mobile/Makefile.am index b58b9529..12cf24b0 100644 --- a/src/host/layer23/include/osmocom/bb/mobile/Makefile.am +++ b/src/host/layer23/include/osmocom/bb/mobile/Makefile.am @@ -1,3 +1,3 @@ noinst_HEADERS = gsm322.h gsm480_ss.h gsm411_sms.h gsm48_cc.h gsm48_mm.h \ gsm48_rr.h mncc.h settings.h subscriber.h support.h \ - transaction.h vty.h mncc_sock.h + transaction.h vty.h mncc_sock.h primitives.h diff --git a/src/host/layer23/include/osmocom/bb/mobile/primitives.h b/src/host/layer23/include/osmocom/bb/mobile/primitives.h new file mode 100644 index 00000000..a3168b2e --- /dev/null +++ b/src/host/layer23/include/osmocom/bb/mobile/primitives.h @@ -0,0 +1,48 @@ +#pragma once + +#include <osmocom/core/prim.h> + +struct mobile_prim; + +/** + * Mobile Script<->App primitives. Application script will receive + * indications and will send primitives to the lower layers. Here + * we will convert from internal state/events to the primitives. In + * the future the indications might be generated at lower levels + * directly. + */ +enum mobile_prims { + PRIM_MOB_TIMER, + PRIM_MOB_TIMER_CANCEL, +}; + +struct mobile_prim_intf { + struct osmocom_ms *ms; + void (*indication)(struct mobile_prim_intf *, struct mobile_prim *prim); + + /* Internal state */ + struct llist_head timers; +}; + +/** + * Primitive to create timers and get indication once they have + * expired. Currently there is no way to cancel timers. + */ +struct mobile_timer_param { + uint64_t timer_id; /*!< Unique Id identifying the timer */ + int seconds; /*!< Seconds the timer should fire in */ +}; + +struct mobile_prim { + struct osmo_prim_hdr hdr; /*!< Primitive base class */ + union { + struct mobile_timer_param timer; + } u; +}; + + +struct mobile_prim_intf *mobile_prim_intf_alloc(struct osmocom_ms *ms); +int mobile_prim_intf_req(struct mobile_prim_intf *intf, struct mobile_prim *hdr); +void mobile_prim_intf_free(struct mobile_prim_intf *intf); + +struct mobile_prim *mobile_prim_alloc(unsigned int primitive, enum osmo_prim_operation op); diff --git a/src/host/layer23/src/common/logging.c b/src/host/layer23/src/common/logging.c index 3b761ef7..7b3ea26b 100644 --- a/src/host/layer23/src/common/logging.c +++ b/src/host/layer23/src/common/logging.c @@ -133,6 +133,12 @@ static const struct log_info_cat default_categories[] = { .color = "\033[1;35m", .enabled = 1, .loglevel = LOGL_DEBUG, }, + [DPRIM] = { + .name = "DPRIM", + .description = "PRIM", + .color = "\033[1;32m", + .enabled = 1, .loglevel = LOGL_DEBUG, + }, }; const struct log_info log_info = { diff --git a/src/host/layer23/src/mobile/Makefile.am b/src/host/layer23/src/mobile/Makefile.am index 04dd0257..90468c04 100644 --- a/src/host/layer23/src/mobile/Makefile.am +++ b/src/host/layer23/src/mobile/Makefile.am @@ -5,7 +5,7 @@ LDADD = ../common/liblayer23.a $(LIBOSMOCORE_LIBS) $(LIBOSMOVTY_LIBS) $(LIBOSMOG noinst_LIBRARIES = libmobile.a libmobile_a_SOURCES = gsm322.c gsm480_ss.c gsm411_sms.c gsm48_cc.c gsm48_mm.c \ gsm48_rr.c mnccms.c settings.c subscriber.c support.c \ - transaction.c vty_interface.c voice.c mncc_sock.c + transaction.c vty_interface.c voice.c mncc_sock.c primitives.c bin_PROGRAMS = mobile diff --git a/src/host/layer23/src/mobile/main.c b/src/host/layer23/src/mobile/main.c index 8921bd8b..227cd102 100644 --- a/src/host/layer23/src/mobile/main.c +++ b/src/host/layer23/src/mobile/main.c @@ -70,7 +70,7 @@ int mobile_exit(struct osmocom_ms *ms, int force); const char *debug_default = - "DCS:DNB:DPLMN:DRR:DMM:DSIM:DCC:DMNCC:DSS:DLSMS:DPAG:DSUM:DSAP:DGPS:DMOB"; + "DCS:DNB:DPLMN:DRR:DMM:DSIM:DCC:DMNCC:DSS:DLSMS:DPAG:DSUM:DSAP:DGPS:DMOB:DPRIM"; const char *openbsc_copyright = "Copyright (C) 2010-2015 Andreas Eversberg, Sylvain Munaut, Holger Freyther, Harald Welte\n" diff --git a/src/host/layer23/src/mobile/primitives.c b/src/host/layer23/src/mobile/primitives.c new file mode 100644 index 00000000..efa7f3ff --- /dev/null +++ b/src/host/layer23/src/mobile/primitives.c @@ -0,0 +1,135 @@ +/* (C) 2017 by Holger Hans Peter Freyther + * + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + */ + +#include <osmocom/bb/mobile/primitives.h> +#include <osmocom/bb/common/logging.h> + +#include <osmocom/core/timer.h> +#include <osmocom/core/talloc.h> + +struct timer_closure { + struct llist_head entry; + struct mobile_prim_intf *intf; + struct osmo_timer_list timer; + uint64_t id; +}; + +struct mobile_prim_intf *mobile_prim_intf_alloc(struct osmocom_ms *ms) +{ + struct mobile_prim_intf *intf; + + intf = talloc_zero(ms, struct mobile_prim_intf); + intf->ms = ms; + + INIT_LLIST_HEAD(&intf->timers); + return intf; +} + +void mobile_prim_intf_free(struct mobile_prim_intf *intf) +{ + struct timer_closure *timer, *tmp; + + llist_for_each_entry_safe(timer, tmp, &intf->timers, entry) { + osmo_timer_del(&timer->timer); + llist_del(&timer->entry); + talloc_free(timer); + } + talloc_free(intf); +} + +struct mobile_prim *mobile_prim_alloc(unsigned int primitive, enum osmo_prim_operation op) +{ + struct msgb *msg = msgb_alloc(1024, "Mobile Primitive"); + struct mobile_prim *prim = (struct mobile_prim *) msgb_put(msg, sizeof(*prim)); + osmo_prim_init(&prim->hdr, 0, primitive, op, msg); + msg->l2h = msg->tail; + return prim; +} + +static void timer_expired_cb(void *_closure) +{ + struct timer_closure *closure = _closure; + struct mobile_prim_intf *intf; + struct mobile_prim *prim; + + prim = mobile_prim_alloc(PRIM_MOB_TIMER, PRIM_OP_INDICATION); + intf = closure->intf; + prim->u.timer.timer_id = closure->id; + + llist_del(&closure->entry); + talloc_free(closure); + + intf->indication(intf, prim); +} + +static int create_timer(struct mobile_prim_intf *intf, struct mobile_timer_param *param) +{ + struct timer_closure *closure; + + LOGP(DPRIM, LOGL_DEBUG, "Creating timer with reference: %llu\n", param->timer_id); + + closure = talloc_zero(intf, struct timer_closure); + closure->intf = intf; + closure->id = param->timer_id; + closure->timer.cb = timer_expired_cb; + closure->timer.data = closure; + llist_add_tail(&closure->entry, &intf->timers); + osmo_timer_schedule(&closure->timer, param->seconds, 0); + return 0; +} + +static int cancel_timer(struct mobile_prim_intf *intf, struct mobile_timer_param *param) +{ + struct timer_closure *closure; + + + llist_for_each_entry(closure, &intf->timers, entry) { + if (closure->id != param->timer_id) + continue; + + LOGP(DPRIM, LOGL_DEBUG, + "Canceling timer with reference: %llu\n", param->timer_id); + osmo_timer_del(&closure->timer); + llist_del(&closure->entry); + talloc_free(closure); + return 0; + } + return -1; +} + +int mobile_prim_intf_req(struct mobile_prim_intf *intf, struct mobile_prim *prim) +{ + int rc = 0; + + switch (OSMO_PRIM_HDR(&prim->hdr)) { + case OSMO_PRIM(PRIM_MOB_TIMER, PRIM_OP_REQUEST): + rc = create_timer(intf, &prim->u.timer); + break; + case OSMO_PRIM(PRIM_MOB_TIMER_CANCEL, PRIM_OP_REQUEST): + rc = cancel_timer(intf, &prim->u.timer); + break; + default: + LOGP(DPRIM, LOGL_ERROR, "Unknown primitive: %d\n", OSMO_PRIM_HDR(&prim->hdr)); + break; + } + + msgb_free(prim->hdr.msg); + return rc; +} |