aboutsummaryrefslogtreecommitdiffstats
path: root/src/osmo-bts-litecell15
diff options
context:
space:
mode:
authorVadim Yanitskiy <vyanitskiy@sysmocom.de>2020-10-29 06:40:58 +0700
committerVadim Yanitskiy <vyanitskiy@sysmocom.de>2020-11-05 03:39:50 +0700
commitef1671c6ed3362958b95a7074c8d2242b756c6cf (patch)
tree1c80d546d39abcee29b0924e251a58b451c20369 /src/osmo-bts-litecell15
parent44d25af9cd1288feda867ce60c636d9334521c4f (diff)
osmo-bts-lc15: use consistent name for containing directory
The binary is called 'osmo-bts-lc15', while the containing folder is named 'osmo-bts-litecell15'. This inconsistency complicates automatic generation of the XML VTY reference - fix it. Change-Id: I55c073fbd01aee42871101401d76d87e7c91832e Related: SYS#4937, OS#3036
Diffstat (limited to 'src/osmo-bts-litecell15')
-rw-r--r--src/osmo-bts-litecell15/Makefile.am38
-rw-r--r--src/osmo-bts-litecell15/calib_file.c456
-rw-r--r--src/osmo-bts-litecell15/hw_misc.c88
-rw-r--r--src/osmo-bts-litecell15/hw_misc.h13
-rw-r--r--src/osmo-bts-litecell15/l1_if.c1726
-rw-r--r--src/osmo-bts-litecell15/l1_if.h149
-rw-r--r--src/osmo-bts-litecell15/l1_transp.h14
-rw-r--r--src/osmo-bts-litecell15/l1_transp_hw.c318
-rw-r--r--src/osmo-bts-litecell15/lc15bts.c353
-rw-r--r--src/osmo-bts-litecell15/lc15bts.h101
-rw-r--r--src/osmo-bts-litecell15/lc15bts_vty.c638
-rw-r--r--src/osmo-bts-litecell15/main.c226
-rw-r--r--src/osmo-bts-litecell15/misc/lc15bts_bid.c162
-rw-r--r--src/osmo-bts-litecell15/misc/lc15bts_bid.h52
-rw-r--r--src/osmo-bts-litecell15/misc/lc15bts_bts.c131
-rw-r--r--src/osmo-bts-litecell15/misc/lc15bts_bts.h21
-rw-r--r--src/osmo-bts-litecell15/misc/lc15bts_clock.c260
-rw-r--r--src/osmo-bts-litecell15/misc/lc15bts_clock.h16
-rw-r--r--src/osmo-bts-litecell15/misc/lc15bts_led.c333
-rw-r--r--src/osmo-bts-litecell15/misc/lc15bts_led.h22
-rw-r--r--src/osmo-bts-litecell15/misc/lc15bts_mgr.c366
-rw-r--r--src/osmo-bts-litecell15/misc/lc15bts_mgr.h422
-rw-r--r--src/osmo-bts-litecell15/misc/lc15bts_mgr_calib.c292
-rw-r--r--src/osmo-bts-litecell15/misc/lc15bts_mgr_nl.c195
-rw-r--r--src/osmo-bts-litecell15/misc/lc15bts_mgr_temp.c378
-rw-r--r--src/osmo-bts-litecell15/misc/lc15bts_mgr_vty.c1074
-rw-r--r--src/osmo-bts-litecell15/misc/lc15bts_misc.c383
-rw-r--r--src/osmo-bts-litecell15/misc/lc15bts_misc.h18
-rw-r--r--src/osmo-bts-litecell15/misc/lc15bts_nl.c123
-rw-r--r--src/osmo-bts-litecell15/misc/lc15bts_nl.h27
-rw-r--r--src/osmo-bts-litecell15/misc/lc15bts_par.c232
-rw-r--r--src/osmo-bts-litecell15/misc/lc15bts_par.h43
-rw-r--r--src/osmo-bts-litecell15/misc/lc15bts_power.c210
-rw-r--r--src/osmo-bts-litecell15/misc/lc15bts_power.h38
-rw-r--r--src/osmo-bts-litecell15/misc/lc15bts_swd.c178
-rw-r--r--src/osmo-bts-litecell15/misc/lc15bts_swd.h7
-rw-r--r--src/osmo-bts-litecell15/misc/lc15bts_temp.c74
-rw-r--r--src/osmo-bts-litecell15/misc/lc15bts_temp.h28
-rw-r--r--src/osmo-bts-litecell15/misc/lc15bts_util.c164
-rw-r--r--src/osmo-bts-litecell15/oml.c2112
-rw-r--r--src/osmo-bts-litecell15/tch.c533
-rw-r--r--src/osmo-bts-litecell15/utils.c118
-rw-r--r--src/osmo-bts-litecell15/utils.h13
43 files changed, 0 insertions, 12145 deletions
diff --git a/src/osmo-bts-litecell15/Makefile.am b/src/osmo-bts-litecell15/Makefile.am
deleted file mode 100644
index bb68efaf..00000000
--- a/src/osmo-bts-litecell15/Makefile.am
+++ /dev/null
@@ -1,38 +0,0 @@
-AUTOMAKE_OPTIONS = subdir-objects
-
-AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include $(LITECELL15_INCDIR)
-AM_CFLAGS = -Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOCODEC_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBOSMOVTY_CFLAGS) $(LIBOSMOTRAU_CFLAGS) $(LIBOSMOABIS_CFLAGS) $(LIBOSMOCTRL_CFLAGS) $(LIBOSMOABIS_CFLAGS) $(LIBGPS_CFLAGS) $(LIBSYSTEMD_CFLAGS)
-COMMON_LDADD = $(LIBOSMOCORE_LIBS) $(LIBOSMOCODEC_LIBS) $(LIBOSMOGSM_LIBS) $(LIBOSMOVTY_LIBS) $(LIBOSMOTRAU_LIBS) $(LIBOSMOABIS_LIBS) $(LIBOSMOCTRL_LIBS)
-
-AM_CFLAGS += -DENABLE_LC15BTS
-
-EXTRA_DIST = misc/lc15bts_mgr.h misc/lc15bts_misc.h misc/lc15bts_par.h misc/lc15bts_led.h \
- misc/lc15bts_temp.h misc/lc15bts_power.h misc/lc15bts_clock.h \
- misc/lc15bts_bid.h misc/lc15bts_nl.h misc/lc15bts_bts.h misc/lc15bts_swd.h \
- hw_misc.h l1_if.h l1_transp.h lc15bts.h utils.h
-
-bin_PROGRAMS = osmo-bts-lc15 lc15bts-mgr lc15bts-util
-
-COMMON_SOURCES = main.c lc15bts.c l1_if.c oml.c lc15bts_vty.c tch.c hw_misc.c calib_file.c \
- utils.c misc/lc15bts_par.c misc/lc15bts_bid.c
-
-osmo_bts_lc15_SOURCES = $(COMMON_SOURCES) l1_transp_hw.c
-osmo_bts_lc15_LDADD = $(top_builddir)/src/common/libbts.a $(COMMON_LDADD)
-
-lc15bts_mgr_SOURCES = \
- misc/lc15bts_mgr.c misc/lc15bts_misc.c \
- misc/lc15bts_par.c misc/lc15bts_nl.c \
- misc/lc15bts_temp.c misc/lc15bts_power.c \
- misc/lc15bts_clock.c misc/lc15bts_bid.c \
- misc/lc15bts_mgr_vty.c \
- misc/lc15bts_mgr_nl.c \
- misc/lc15bts_mgr_temp.c \
- misc/lc15bts_mgr_calib.c \
- misc/lc15bts_led.c \
- misc/lc15bts_bts.c \
- misc/lc15bts_swd.c
-
-lc15bts_mgr_LDADD = $(top_builddir)/src/common/libbts.a $(LIBGPS_LIBS) $(LIBOSMOCORE_LIBS) $(LIBOSMOVTY_LIBS) $(LIBOSMOABIS_LIBS) $(LIBOSMOGSM_LIBS) $(LIBOSMOCTRL_LIBS) $(LIBSYSTEMD_LIBS) $(COMMON_LDADD)
-
-lc15bts_util_SOURCES = misc/lc15bts_util.c misc/lc15bts_par.c
-lc15bts_util_LDADD = $(LIBOSMOCORE_LIBS)
diff --git a/src/osmo-bts-litecell15/calib_file.c b/src/osmo-bts-litecell15/calib_file.c
deleted file mode 100644
index 2641552f..00000000
--- a/src/osmo-bts-litecell15/calib_file.c
+++ /dev/null
@@ -1,456 +0,0 @@
-/* NuRAN Wireless Litecell 1.5 BTS L1 calibration file routines*/
-
-/* Copyright (C) 2015 by Yves Godin <support@nuranwireless.com>
- * Copyright (C) 2016 by Harald Welte <laforge@gnumonks.org>
- *
- * Based on sysmoBTS:
- * (C) 2012 by Harald Welte <laforge@gnumonks.org>
- *
- * 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 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/licenses/>.
- *
- */
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <fcntl.h>
-#include <limits.h>
-#include <errno.h>
-
-#include <osmocom/core/utils.h>
-
-#include <osmo-bts/gsm_data.h>
-#include <osmo-bts/logging.h>
-
-#include <nrw/litecell15/litecell15.h>
-#include <nrw/litecell15/gsml1const.h>
-
-#include "l1_if.h"
-#include "lc15bts.h"
-#include "utils.h"
-
-/* Maximum calibration data chunk size */
-#define MAX_CALIB_TBL_SIZE 65536
-/* Calibration header version */
-#define CALIB_HDR_V1 0x01
-
-struct calib_file_desc {
- const char *fname;
- int rx;
- int trx;
- int rxpath;
-};
-
-static const struct calib_file_desc calib_files[] = {
- {
- .fname = "calib_rx0a.conf",
- .rx = 1,
- .trx = 0,
- .rxpath = 0,
- }, {
- .fname = "calib_rx0b.conf",
- .rx = 1,
- .trx = 0,
- .rxpath = 1,
- }, {
- .fname = "calib_rx1a.conf",
- .rx = 1,
- .trx = 1,
- .rxpath = 0,
- }, {
- .fname = "calib_rx1b.conf",
- .rx = 1,
- .trx = 1,
- .rxpath = 1,
- }, {
- .fname = "calib_tx0.conf",
- .rx = 0,
- .trx = 0,
- }, {
- .fname = "calib_tx1.conf",
- .rx = 0,
- .trx = 1,
- },
-};
-
-struct calTbl_t
-{
- union
- {
- struct
- {
- uint8_t u8Version; /* Header version (1) */
- uint8_t u8Parity; /* Parity byte (xor) */
- uint8_t u8Type; /* Table type (0:TX Downlink, 1:RX-A Uplink, 2:RX-B Uplink) */
- uint8_t u8Band; /* GSM Band (0:GSM-850, 1:EGSM-900, 2:DCS-1800, 3:PCS-1900) */
- uint32_t u32Len; /* Table length in bytes including the header */
- struct
- {
- uint32_t u32DescOfst; /* Description section offset */
- uint32_t u32DateOfst; /* Date section offset */
- uint32_t u32StationOfst; /* Calibration test station section offset */
- uint32_t u32FpgaFwVerOfst; /* Calibration FPGA firmware version section offset */
- uint32_t u32DspFwVerOfst; /* Calibration DSP firmware section offset */
- uint32_t u32DataOfst; /* Calibration data section offset */
- } toc;
- } v1;
- } hdr;
-
- uint8_t u8RawData[MAX_CALIB_TBL_SIZE - 32];
-};
-
-
-static int calib_file_send(struct lc15l1_hdl *fl1h,
- const struct calib_file_desc *desc);
-static int calib_verify(struct lc15l1_hdl *fl1h,
- const struct calib_file_desc *desc);
-
-/* determine next calibration file index based on supported bands */
-static int get_next_calib_file_idx(struct lc15l1_hdl *fl1h, int last_idx)
-{
- struct phy_link *plink = fl1h->phy_inst->phy_link;
- int i;
-
- for (i = last_idx+1; i < ARRAY_SIZE(calib_files); i++) {
- if (calib_files[i].trx == plink->num)
- return i;
- }
- return -1;
-}
-
-static int calib_file_open(struct lc15l1_hdl *fl1h,
- const struct calib_file_desc *desc)
-{
- struct calib_send_state *st = &fl1h->st;
- char *calib_path = fl1h->phy_inst->u.lc15.calib_path;
- char fname[PATH_MAX];
-
- if (st->fp) {
- LOGP(DL1C, LOGL_NOTICE, "L1 calibration file was left opened !!\n");
- fclose(st->fp);
- st->fp = NULL;
- }
-
- fname[0] = '\0';
- snprintf(fname, sizeof(fname)-1, "%s/%s", calib_path, desc->fname);
- fname[sizeof(fname)-1] = '\0';
-
- st->fp = fopen(fname, "rb");
- if (!st->fp) {
- LOGP(DL1C, LOGL_ERROR,
- "Failed to open '%s' for calibration data.\n", fname);
- return -1;
- }
- return 0;
-}
-
-static int calib_file_close(struct lc15l1_hdl *fl1h)
-{
- struct calib_send_state *st = &fl1h->st;
-
- if (st->fp) {
- fclose(st->fp);
- st->fp = NULL;
- }
- return 0;
-}
-
-/* iteratively download the calibration data into the L1 */
-
-static int calib_send_compl_cb(struct gsm_bts_trx *trx, struct msgb *l1_msg,
- void *data);
-
-/* send a chunk of calibration tabledata for a single specified file */
-static int calib_file_send_next_chunk(struct lc15l1_hdl *fl1h)
-{
- struct calib_send_state *st = &fl1h->st;
- Litecell15_Prim_t *prim;
- struct msgb *msg;
- size_t n;
-
- msg = sysp_msgb_alloc();
- prim = msgb_sysprim(msg);
-
- prim->id = Litecell15_PrimId_SetCalibTblReq;
- prim->u.setCalibTblReq.offset = (uint32_t)ftell(st->fp);
- n = fread(prim->u.setCalibTblReq.u8Data, 1,
- sizeof(prim->u.setCalibTblReq.u8Data), st->fp);
- prim->u.setCalibTblReq.length = n;
-
-
- if (n == 0) {
- /* The table data has been completely sent and acknowledged */
- LOGP(DL1C, LOGL_NOTICE, "L1 calibration table %s loaded\n",
- calib_files[st->last_file_idx].fname);
-
- calib_file_close(fl1h);
-
- msgb_free(msg);
-
- /* Send the next one if any */
- st->last_file_idx = get_next_calib_file_idx(fl1h, st->last_file_idx);
- if (st->last_file_idx >= 0) {
- return calib_file_send(fl1h,
- &calib_files[st->last_file_idx]);
- }
-
- LOGP(DL1C, LOGL_INFO, "L1 calibration table loading complete!\n");
- return 0;
- }
-
- return l1if_req_compl(fl1h, msg, calib_send_compl_cb, NULL);
-}
-
-/* send the calibration table for a single specified file */
-static int calib_file_send(struct lc15l1_hdl *fl1h,
- const struct calib_file_desc *desc)
-{
- struct calib_send_state *st = &fl1h->st;
- int rc;
-
- rc = calib_file_open(fl1h, desc);
- if (rc < 0) {
- /* still, we'd like to continue trying to load
- * calibration for all other bands */
- st->last_file_idx = get_next_calib_file_idx(fl1h, st->last_file_idx);
- if (st->last_file_idx >= 0)
- return calib_file_send(fl1h,
- &calib_files[st->last_file_idx]);
-
- LOGP(DL1C, LOGL_INFO, "L1 calibration table loading complete!\n");
- return 0;
- }
-
- rc = calib_verify(fl1h, desc);
- if ( rc < 0 ) {
- LOGP(DL1C, LOGL_ERROR, "Verify L1 calibration table %s -> failed (%d)\n", desc->fname, rc);
- st->last_file_idx = get_next_calib_file_idx(fl1h, st->last_file_idx);
-
- if (st->last_file_idx >= 0)
- return calib_file_send(fl1h,
- &calib_files[st->last_file_idx]);
- return 0;
-
- }
-
- LOGP(DL1C, LOGL_INFO, "Verify L1 calibration table %s -> done\n", desc->fname);
-
- return calib_file_send_next_chunk(fl1h);
-}
-
-/* completion callback after every SetCalibTbl is confirmed */
-static int calib_send_compl_cb(struct gsm_bts_trx *trx, struct msgb *l1_msg,
- void *data)
-{
- struct lc15l1_hdl *fl1h = trx_lc15l1_hdl(trx);
- struct calib_send_state *st = &fl1h->st;
- Litecell15_Prim_t *prim = msgb_sysprim(l1_msg);
-
- if (prim->u.setCalibTblCnf.status != GsmL1_Status_Success) {
- LOGP(DL1C, LOGL_ERROR, "L1 rejected calibration table\n");
-
- msgb_free(l1_msg);
-
- calib_file_close(fl1h);
-
- /* Skip this one and try the next one */
- st->last_file_idx = get_next_calib_file_idx(fl1h, st->last_file_idx);
- if (st->last_file_idx >= 0) {
- return calib_file_send(fl1h,
- &calib_files[st->last_file_idx]);
- }
-
- LOGP(DL1C, LOGL_INFO, "L1 calibration table loading complete!\n");
- return 0;
- }
-
- msgb_free(l1_msg);
-
- /* Keep sending the calibration file data */
- return calib_file_send_next_chunk(fl1h);
-}
-
-int calib_load(struct lc15l1_hdl *fl1h)
-{
- int rc;
- struct calib_send_state *st = &fl1h->st;
- char *calib_path = fl1h->phy_inst->u.lc15.calib_path;
-
- if (!calib_path) {
- LOGP(DL1C, LOGL_ERROR, "Calibration file path not specified\n");
- return -1;
- }
-
- rc = get_next_calib_file_idx(fl1h, -1);
- if (rc < 0) {
- return -1;
- }
- st->last_file_idx = rc;
-
- return calib_file_send(fl1h, &calib_files[st->last_file_idx]);
-}
-
-
-static int calib_verify(struct lc15l1_hdl *fl1h, const struct calib_file_desc *desc)
-{
- int rc, sz;
- struct calib_send_state *st = &fl1h->st;
- struct phy_link *plink = fl1h->phy_inst->phy_link;
- char *rbuf;
- struct calTbl_t *calTbl;
- char calChkSum ;
-
- /* calculate file size in bytes */
- fseek(st->fp, 0L, SEEK_END);
- sz = ftell(st->fp);
-
- /* rewind read pointer */
- fseek(st->fp, 0L, SEEK_SET);
-
- /* read file */
- rbuf = (char *) malloc( sizeof(char) * sz );
-
- rc = fread(rbuf, 1, sizeof(char) * sz, st->fp);
- if ( rc != sz) {
-
- LOGP(DL1C, LOGL_ERROR, "%s reading error\n", desc->fname);
- free(rbuf);
-
- /* close file */
- rc = calib_file_close(fl1h);
- if (rc < 0 ) {
- LOGP(DL1C, LOGL_ERROR, "%s can not close\n", desc->fname);
- return rc;
- }
-
- return -2;
- }
-
- calTbl = (struct calTbl_t*) rbuf;
- /* calculate file checksum */
- calChkSum = 0;
- while ( sz-- ) {
- calChkSum ^= rbuf[sz];
- }
-
- /* validate Tx calibration parity */
- if ( calChkSum ) {
- LOGP(DL1C, LOGL_ERROR, "%s has invalid checksum %x.\n", desc->fname, calChkSum);
- return -4;
- }
-
- /* validate Tx calibration header */
- if ( calTbl->hdr.v1.u8Version != CALIB_HDR_V1 ) {
- LOGP(DL1C, LOGL_ERROR, "%s has invalid header version %u.\n", desc->fname, calTbl->hdr.v1.u8Version);
- return -5;
- }
-
- /* validate calibration description */
- if ( calTbl->hdr.v1.toc.u32DescOfst == 0xFFFFFFFF ) {
- LOGP(DL1C, LOGL_ERROR, "%s has invalid calibration description offset.\n", desc->fname);
- return -6;
- }
-
- /* validate calibration date */
- if ( calTbl->hdr.v1.toc.u32DateOfst == 0xFFFFFFFF ) {
- LOGP(DL1C, LOGL_ERROR, "%s has invalid calibration date offset.\n", desc->fname);
- return -7;
- }
-
- LOGP(DL1C, LOGL_INFO, "L1 calibration table %s created on %s\n",
- desc->fname,
- calTbl->u8RawData + calTbl->hdr.v1.toc.u32DateOfst);
-
- /* validate calibration station */
- if ( calTbl->hdr.v1.toc.u32StationOfst == 0xFFFFFFFF ) {
- LOGP(DL1C, LOGL_ERROR, "%s has invalid calibration station ID offset.\n", desc->fname);
- return -8;
- }
-
- /* validate FPGA FW version */
- if ( calTbl->hdr.v1.toc.u32FpgaFwVerOfst == 0xFFFFFFFF ) {
- LOGP(DL1C, LOGL_ERROR, "%s has invalid FPGA FW version offset.\n", desc->fname);
- return -9;
- }
-
- /* validate DSP FW version */
- if ( calTbl->hdr.v1.toc.u32DspFwVerOfst == 0xFFFFFFFF ) {
- LOGP(DL1C, LOGL_ERROR, "%s has invalid DSP FW version offset.\n", desc->fname);
- return -10;
- }
-
- /* validate Tx calibration data offset */
- if ( calTbl->hdr.v1.toc.u32DataOfst == 0xFFFFFFFF ) {
- LOGP(DL1C, LOGL_ERROR, "%s has invalid calibration data offset.\n", desc->fname);
- return -11;
- }
-
- if ( !desc->rx ) {
-
- /* parse min/max Tx power */
- fl1h->phy_inst->u.lc15.minTxPower = calTbl->u8RawData[calTbl->hdr.v1.toc.u32DataOfst + (5 << 2)];
- fl1h->phy_inst->u.lc15.maxTxPower = calTbl->u8RawData[calTbl->hdr.v1.toc.u32DataOfst + (6 << 2)];
-
- /* override nominal Tx power of given TRX if needed */
- if ( fl1h->phy_inst->trx->nominal_power > fl1h->phy_inst->u.lc15.maxTxPower) {
- LOGP(DL1C, LOGL_INFO, "Set TRX %u nominal Tx power to %d dBm (%d)\n",
- plink->num,
- fl1h->phy_inst->u.lc15.maxTxPower,
- fl1h->phy_inst->trx->nominal_power);
-
- fl1h->phy_inst->trx->nominal_power = fl1h->phy_inst->u.lc15.maxTxPower;
- }
-
- if ( fl1h->phy_inst->trx->nominal_power < fl1h->phy_inst->u.lc15.minTxPower) {
- LOGP(DL1C, LOGL_INFO, "Set TRX %u nominal Tx power to %d dBm (%d)\n",
- plink->num,
- fl1h->phy_inst->u.lc15.minTxPower,
- fl1h->phy_inst->trx->nominal_power);
-
- fl1h->phy_inst->trx->nominal_power = fl1h->phy_inst->u.lc15.minTxPower;
- }
-
- if ( fl1h->phy_inst->trx->power_params.trx_p_max_out_mdBm > to_mdB(fl1h->phy_inst->u.lc15.maxTxPower) ) {
- LOGP(DL1C, LOGL_INFO, "Set TRX %u Tx power parameter to %d dBm (%d)\n",
- plink->num,
- to_mdB(fl1h->phy_inst->u.lc15.maxTxPower),
- fl1h->phy_inst->trx->power_params.trx_p_max_out_mdBm);
-
- fl1h->phy_inst->trx->power_params.trx_p_max_out_mdBm = to_mdB(fl1h->phy_inst->u.lc15.maxTxPower);
- }
-
- if ( fl1h->phy_inst->trx->power_params.trx_p_max_out_mdBm < to_mdB(fl1h->phy_inst->u.lc15.minTxPower) ) {
- LOGP(DL1C, LOGL_INFO, "Set TRX %u Tx power parameter to %d dBm (%d)\n",
- plink->num,
- to_mdB(fl1h->phy_inst->u.lc15.minTxPower),
- fl1h->phy_inst->trx->power_params.trx_p_max_out_mdBm);
-
- fl1h->phy_inst->trx->power_params.trx_p_max_out_mdBm = to_mdB(fl1h->phy_inst->u.lc15.minTxPower);
- }
-
- LOGP(DL1C, LOGL_DEBUG, "%s: minTxPower=%d, maxTxPower=%d\n",
- desc->fname,
- fl1h->phy_inst->u.lc15.minTxPower,
- fl1h->phy_inst->u.lc15.maxTxPower );
- }
-
- /* rewind read pointer for subsequence tasks */
- fseek(st->fp, 0L, SEEK_SET);
- free(rbuf);
-
- return 0;
-}
-
diff --git a/src/osmo-bts-litecell15/hw_misc.c b/src/osmo-bts-litecell15/hw_misc.c
deleted file mode 100644
index 9f070bba..00000000
--- a/src/osmo-bts-litecell15/hw_misc.c
+++ /dev/null
@@ -1,88 +0,0 @@
-/* Misc HW routines for NuRAN Wireless Litecell 1.5 BTS */
-
-/* Copyright (C) 2015 by Yves Godin <support@nuranwireless.com>
- *
- * Based on sysmoBTS:
- * (C) 2012 by Harald Welte <laforge@gnumonks.org>
- *
- * 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 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/licenses/>.
- *
- */
-
-#include <stdint.h>
-#include <unistd.h>
-#include <limits.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <stdio.h>
-#include <string.h>
-
-#include <sys/types.h>
-#include <sys/stat.h>
-
-#include <osmocom/core/utils.h>
-
-#include "hw_misc.h"
-
-int lc15bts_led_set(enum lc15bts_led_color c)
-{
- int fd, rc;
- uint8_t cmd[2];
-
- switch (c) {
- case LED_OFF:
- cmd[0] = 0;
- cmd[1] = 0;
- break;
- case LED_RED:
- cmd[0] = 1;
- cmd[1] = 0;
- break;
- case LED_GREEN:
- cmd[0] = 0;
- cmd[1] = 1;
- break;
- case LED_ORANGE:
- cmd[0] = 1;
- cmd[1] = 1;
- break;
- default:
- return -EINVAL;
- }
-
- fd = open("/var/lc15/leds/led0/brightness", O_WRONLY);
- if (fd < 0)
- return -ENODEV;
-
- rc = write(fd, cmd[0] ? "1" : "0", 2);
- if (rc != 2) {
- close(fd);
- return -1;
- }
- close(fd);
-
- fd = open("/var/lc15/leds/led1/brightness", O_WRONLY);
- if (fd < 0)
- return -ENODEV;
-
- rc = write(fd, cmd[1] ? "1" : "0", 2);
- if (rc != 2) {
- close(fd);
- return -1;
- }
- close(fd);
- return 0;
-}
diff --git a/src/osmo-bts-litecell15/hw_misc.h b/src/osmo-bts-litecell15/hw_misc.h
deleted file mode 100644
index 59ed04b7..00000000
--- a/src/osmo-bts-litecell15/hw_misc.h
+++ /dev/null
@@ -1,13 +0,0 @@
-#ifndef _HW_MISC_H
-#define _HW_MISC_H
-
-enum lc15bts_led_color {
- LED_OFF,
- LED_RED,
- LED_GREEN,
- LED_ORANGE,
-};
-
-int lc15bts_led_set(enum lc15bts_led_color c);
-
-#endif
diff --git a/src/osmo-bts-litecell15/l1_if.c b/src/osmo-bts-litecell15/l1_if.c
deleted file mode 100644
index b7c24c08..00000000
--- a/src/osmo-bts-litecell15/l1_if.c
+++ /dev/null
@@ -1,1726 +0,0 @@
-/* Interface handler for NuRAN Wireless Litecell 1.5 L1 */
-
-/* Copyright (C) 2015 by Yves Godin <support@nuranwireless.com>
- * Copyright (C) 2016 by Harald Welte <laforge@gnumonks.org>
- *
- * Based on sysmoBTS:
- * (C) 2011-2014 by Harald Welte <laforge@gnumonks.org>
- * (C) 2014 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 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 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/licenses/>.
- *
- */
-
-#include <stdint.h>
-#include <unistd.h>
-#include <errno.h>
-#include <fcntl.h>
-
-#include <sys/types.h>
-#include <sys/stat.h>
-
-#include <osmocom/core/talloc.h>
-#include <osmocom/core/utils.h>
-#include <osmocom/core/select.h>
-#include <osmocom/core/timer.h>
-#include <osmocom/core/write_queue.h>
-#include <osmocom/gsm/gsm_utils.h>
-#include <osmocom/gsm/lapdm.h>
-
-#include <osmo-bts/logging.h>
-#include <osmo-bts/bts.h>
-#include <osmo-bts/oml.h>
-#include <osmo-bts/rsl.h>
-#include <osmo-bts/gsm_data.h>
-#include <osmo-bts/phy_link.h>
-#include <osmo-bts/paging.h>
-#include <osmo-bts/measurement.h>
-#include <osmo-bts/pcu_if.h>
-#include <osmo-bts/handover.h>
-#include <osmo-bts/bts_model.h>
-#include <osmo-bts/l1sap.h>
-#include <osmo-bts/msg_utils.h>
-#include <osmo-bts/dtx_dl_amr_fsm.h>
-#include <osmo-bts/nm_common_fsm.h>
-
-#include <nrw/litecell15/litecell15.h>
-#include <nrw/litecell15/gsml1prim.h>
-#include <nrw/litecell15/gsml1const.h>
-#include <nrw/litecell15/gsml1types.h>
-
-#include "lc15bts.h"
-#include "l1_if.h"
-#include "l1_transp.h"
-#include "hw_misc.h"
-#include "misc/lc15bts_par.h"
-#include "misc/lc15bts_bid.h"
-#include "utils.h"
-
-extern unsigned int dsp_trace;
-
-struct wait_l1_conf {
- struct llist_head list; /* internal linked list */
- struct osmo_timer_list timer; /* timer for L1 timeout */
- unsigned int conf_prim_id; /* primitive we expect in response */
- HANDLE conf_hLayer3; /* layer 3 handle we expect in response */
- unsigned int is_sys_prim; /* is this a system (1) or L1 (0) primitive */
- l1if_compl_cb *cb;
- void *cb_data;
-};
-
-static void release_wlc(struct wait_l1_conf *wlc)
-{
- osmo_timer_del(&wlc->timer);
- talloc_free(wlc);
-}
-
-static void l1if_req_timeout(void *data)
-{
- struct wait_l1_conf *wlc = data;
-
- if (wlc->is_sys_prim)
- LOGP(DL1C, LOGL_FATAL, "Timeout waiting for SYS primitive %s\n",
- get_value_string(lc15bts_sysprim_names, wlc->conf_prim_id));
- else
- LOGP(DL1C, LOGL_FATAL, "Timeout waiting for L1 primitive %s\n",
- get_value_string(lc15bts_l1prim_names, wlc->conf_prim_id));
- exit(23);
-}
-
-static HANDLE l1p_get_hLayer3(GsmL1_Prim_t *prim)
-{
- switch (prim->id) {
- case GsmL1_PrimId_MphInitReq:
- return prim->u.mphInitReq.hLayer3;
- case GsmL1_PrimId_MphCloseReq:
- return prim->u.mphCloseReq.hLayer3;
- case GsmL1_PrimId_MphConnectReq:
- return prim->u.mphConnectReq.hLayer3;
- case GsmL1_PrimId_MphDisconnectReq:
- return prim->u.mphDisconnectReq.hLayer3;
- case GsmL1_PrimId_MphActivateReq:
- return prim->u.mphActivateReq.hLayer3;
- case GsmL1_PrimId_MphDeactivateReq:
- return prim->u.mphDeactivateReq.hLayer3;
- case GsmL1_PrimId_MphConfigReq:
- return prim->u.mphConfigReq.hLayer3;
- case GsmL1_PrimId_MphMeasureReq:
- return prim->u.mphMeasureReq.hLayer3;
- case GsmL1_PrimId_MphInitCnf:
- return prim->u.mphInitCnf.hLayer3;
- case GsmL1_PrimId_MphCloseCnf:
- return prim->u.mphCloseCnf.hLayer3;
- case GsmL1_PrimId_MphConnectCnf:
- return prim->u.mphConnectCnf.hLayer3;
- case GsmL1_PrimId_MphDisconnectCnf:
- return prim->u.mphDisconnectCnf.hLayer3;
- case GsmL1_PrimId_MphActivateCnf:
- return prim->u.mphActivateCnf.hLayer3;
- case GsmL1_PrimId_MphDeactivateCnf:
- return prim->u.mphDeactivateCnf.hLayer3;
- case GsmL1_PrimId_MphConfigCnf:
- return prim->u.mphConfigCnf.hLayer3;
- case GsmL1_PrimId_MphMeasureCnf:
- return prim->u.mphMeasureCnf.hLayer3;
- case GsmL1_PrimId_MphTimeInd:
- case GsmL1_PrimId_MphSyncInd:
- case GsmL1_PrimId_PhEmptyFrameReq:
- case GsmL1_PrimId_PhDataReq:
- case GsmL1_PrimId_PhConnectInd:
- case GsmL1_PrimId_PhReadyToSendInd:
- case GsmL1_PrimId_PhDataInd:
- case GsmL1_PrimId_PhRaInd:
- break;
- default:
- LOGP(DL1C, LOGL_ERROR, "unknown L1 primitive %u\n", prim->id);
- break;
- }
- return 0;
-}
-
-static int _l1if_req_compl(struct lc15l1_hdl *fl1h, struct msgb *msg,
- int is_system_prim, l1if_compl_cb *cb, void *data)
-{
- struct wait_l1_conf *wlc;
- struct osmo_wqueue *wqueue;
- unsigned int timeout_secs;
-
- /* allocate new wsc and store reference to mutex and conf_id */
- wlc = talloc_zero(fl1h, struct wait_l1_conf);
- wlc->cb = cb;
- wlc->cb_data = data;
-
- /* Make sure we actually have received a REQUEST type primitive */
- if (is_system_prim == 0) {
- GsmL1_Prim_t *l1p = msgb_l1prim(msg);
-
- LOGP(DL1P, LOGL_INFO, "Tx L1 prim %s\n",
- get_value_string(lc15bts_l1prim_names, l1p->id));
-
- if (lc15bts_get_l1prim_type(l1p->id) != L1P_T_REQ) {
- LOGP(DL1C, LOGL_ERROR, "L1 Prim %s is not a Request!\n",
- get_value_string(lc15bts_l1prim_names, l1p->id));
- talloc_free(wlc);
- return -EINVAL;
- }
- wlc->is_sys_prim = 0;
- wlc->conf_prim_id = lc15bts_get_l1prim_conf(l1p->id);
- wlc->conf_hLayer3 = l1p_get_hLayer3(l1p);
- wqueue = &fl1h->write_q[MQ_L1_WRITE];
- timeout_secs = 30;
- } else {
- Litecell15_Prim_t *sysp = msgb_sysprim(msg);
-
- LOGP(DL1C, LOGL_INFO, "Tx SYS prim %s\n",
- get_value_string(lc15bts_sysprim_names, sysp->id));
-
- if (lc15bts_get_sysprim_type(sysp->id) != L1P_T_REQ) {
- LOGP(DL1C, LOGL_ERROR, "SYS Prim %s is not a Request!\n",
- get_value_string(lc15bts_sysprim_names, sysp->id));
- talloc_free(wlc);
- return -EINVAL;
- }
- wlc->is_sys_prim = 1;
- wlc->conf_prim_id = lc15bts_get_sysprim_conf(sysp->id);
- wqueue = &fl1h->write_q[MQ_SYS_WRITE];
- timeout_secs = 30;
- }
-
- /* enqueue the message in the queue and add wsc to list */
- if (osmo_wqueue_enqueue(wqueue, msg) != 0) {
- /* So we will get a timeout but the log message might help */
- LOGP(DL1C, LOGL_ERROR, "Write queue for %s full. dropping msg.\n",
- is_system_prim ? "system primitive" : "gsm");
- msgb_free(msg);
- }
- llist_add(&wlc->list, &fl1h->wlc_list);
-
- /* schedule a timer for timeout_secs seconds. If DSP fails to respond, we terminate */
- wlc->timer.data = wlc;
- wlc->timer.cb = l1if_req_timeout;
- osmo_timer_schedule(&wlc->timer, timeout_secs, 0);
-
- return 0;
-}
-
-/* send a request primitive to the L1 and schedule completion call-back */
-int l1if_req_compl(struct lc15l1_hdl *fl1h, struct msgb *msg,
- l1if_compl_cb *cb, void *data)
-{
- return _l1if_req_compl(fl1h, msg, 1, cb, data);
-}
-
-int l1if_gsm_req_compl(struct lc15l1_hdl *fl1h, struct msgb *msg,
- l1if_compl_cb *cb, void *data)
-{
- return _l1if_req_compl(fl1h, msg, 0, cb, data);
-}
-
-/* allocate a msgb containing a GsmL1_Prim_t */
-struct msgb *l1p_msgb_alloc(void)
-{
- struct msgb *msg = msgb_alloc(sizeof(GsmL1_Prim_t), "l1_prim");
-
- if (msg)
- msg->l1h = msgb_put(msg, sizeof(GsmL1_Prim_t));
-
- return msg;
-}
-
-/* allocate a msgb containing a Litecell15_Prim_t */
-struct msgb *sysp_msgb_alloc(void)
-{
- struct msgb *msg = msgb_alloc(sizeof(Litecell15_Prim_t), "sys_prim");
-
- if (msg)
- msg->l1h = msgb_put(msg, sizeof(Litecell15_Prim_t));
-
- return msg;
-}
-
-static GsmL1_PhDataReq_t *
-data_req_from_rts_ind(GsmL1_Prim_t *l1p,
- const GsmL1_PhReadyToSendInd_t *rts_ind)
-{
- GsmL1_PhDataReq_t *data_req = &l1p->u.phDataReq;
-
- l1p->id = GsmL1_PrimId_PhDataReq;
-
- /* copy fields from PH-RSS.ind */
- data_req->hLayer1 = rts_ind->hLayer1;
- data_req->u8Tn = rts_ind->u8Tn;
- data_req->u32Fn = rts_ind->u32Fn;
- data_req->sapi = rts_ind->sapi;
- data_req->subCh = rts_ind->subCh;
- data_req->u8BlockNbr = rts_ind->u8BlockNbr;
-
- return data_req;
-}
-
-static GsmL1_PhEmptyFrameReq_t *
-empty_req_from_rts_ind(GsmL1_Prim_t *l1p,
- const GsmL1_PhReadyToSendInd_t *rts_ind)
-{
- GsmL1_PhEmptyFrameReq_t *empty_req = &l1p->u.phEmptyFrameReq;
-
- l1p->id = GsmL1_PrimId_PhEmptyFrameReq;
-
- empty_req->hLayer1 = rts_ind->hLayer1;
- empty_req->u8Tn = rts_ind->u8Tn;
- empty_req->u32Fn = rts_ind->u32Fn;
- empty_req->sapi = rts_ind->sapi;
- empty_req->subCh = rts_ind->subCh;
- empty_req->u8BlockNbr = rts_ind->u8BlockNbr;
-
- return empty_req;
-}
-
-/* fill PH-DATA.req from l1sap primitive */
-static GsmL1_PhDataReq_t *
-data_req_from_l1sap(GsmL1_Prim_t *l1p, struct lc15l1_hdl *fl1,
- uint8_t tn, uint32_t fn, uint8_t sapi, uint8_t sub_ch,
- uint8_t block_nr, uint8_t len)
-{
- GsmL1_PhDataReq_t *data_req = &l1p->u.phDataReq;
-
- l1p->id = GsmL1_PrimId_PhDataReq;
-
- /* copy fields from PH-RSS.ind */
- data_req->hLayer1 = (HANDLE)fl1->hLayer1;
- data_req->u8Tn = tn;
- data_req->u32Fn = fn;
- data_req->sapi = sapi;
- data_req->subCh = sub_ch;
- data_req->u8BlockNbr = block_nr;
-
- data_req->msgUnitParam.u8Size = len;
-
- return data_req;
-}
-
-/* fill PH-EMPTY_FRAME.req from l1sap primitive */
-static GsmL1_PhEmptyFrameReq_t *
-empty_req_from_l1sap(GsmL1_Prim_t *l1p, struct lc15l1_hdl *fl1,
- uint8_t tn, uint32_t fn, uint8_t sapi,
- uint8_t subch, uint8_t block_nr)
-{
- GsmL1_PhEmptyFrameReq_t *empty_req = &l1p->u.phEmptyFrameReq;
-
- l1p->id = GsmL1_PrimId_PhEmptyFrameReq;
-
- empty_req->hLayer1 = (HANDLE)fl1->hLayer1;
- empty_req->u8Tn = tn;
- empty_req->u32Fn = fn;
- empty_req->sapi = sapi;
- empty_req->subCh = subch;
- empty_req->u8BlockNbr = block_nr;
-
- return empty_req;
-}
-
-static int ph_data_req(struct gsm_bts_trx *trx, struct msgb *msg,
- struct osmo_phsap_prim *l1sap, bool use_cache)
-{
- struct lc15l1_hdl *fl1 = trx_lc15l1_hdl(trx);
- struct msgb *l1msg = l1p_msgb_alloc();
- struct gsm_lchan *lchan;
- uint32_t u32Fn;
- uint8_t u8Tn, subCh, u8BlockNbr = 0, sapi = 0;
- uint8_t chan_nr, link_id;
- int len;
-
- if (!msg) {
- LOGPFN(DL1C, LOGL_FATAL, l1sap->u.data.fn, "PH-DATA.req without msg. Please fix!\n");
- abort();
- }
-
- len = msgb_l2len(msg);
-
- chan_nr = l1sap->u.data.chan_nr;
- link_id = l1sap->u.data.link_id;
- u32Fn = l1sap->u.data.fn;
- u8Tn = L1SAP_CHAN2TS(chan_nr);
- subCh = 0x1f;
- lchan = get_lchan_by_chan_nr(trx, chan_nr);
- if (L1SAP_IS_LINK_SACCH(link_id)) {
- sapi = GsmL1_Sapi_Sacch;
- if (!L1SAP_IS_CHAN_TCHF(chan_nr) && !L1SAP_IS_CHAN_PDCH(chan_nr))
- subCh = l1sap_chan2ss(chan_nr);
- } else if (L1SAP_IS_CHAN_TCHF(chan_nr) || L1SAP_IS_CHAN_PDCH(chan_nr)) {
- if (ts_is_pdch(&trx->ts[u8Tn])) {
- if (L1SAP_IS_PTCCH(u32Fn)) {
- sapi = GsmL1_Sapi_Ptcch;
- u8BlockNbr = L1SAP_FN2PTCCHBLOCK(u32Fn);
- } else {
- sapi = GsmL1_Sapi_Pdtch;
- u8BlockNbr = L1SAP_FN2MACBLOCK(u32Fn);
- }
- } else {
- sapi = GsmL1_Sapi_FacchF;
- u8BlockNbr = (u32Fn % 13) >> 2;
- }
- } else if (L1SAP_IS_CHAN_TCHH(chan_nr)) {
- subCh = L1SAP_CHAN2SS_TCHH(chan_nr);
- sapi = GsmL1_Sapi_FacchH;
- u8BlockNbr = (u32Fn % 26) >> 3;
- } else if (L1SAP_IS_CHAN_SDCCH4(chan_nr)) {
- subCh = L1SAP_CHAN2SS_SDCCH4(chan_nr);
- sapi = GsmL1_Sapi_Sdcch;
- } else if (L1SAP_IS_CHAN_SDCCH8(chan_nr)) {
- subCh = L1SAP_CHAN2SS_SDCCH8(chan_nr);
- sapi = GsmL1_Sapi_Sdcch;
- } else if (L1SAP_IS_CHAN_BCCH(chan_nr)) {
- sapi = GsmL1_Sapi_Bcch;
- } else if (L1SAP_IS_CHAN_CBCH(chan_nr)) {
- sapi = GsmL1_Sapi_Cbch;
- } else if (L1SAP_IS_CHAN_AGCH_PCH(chan_nr)) {
- /* The sapi depends on DSP configuration, not
- * on the actual SYSTEM INFORMATION 3. */
- u8BlockNbr = l1sap_fn2ccch_block(u32Fn);
- if (u8BlockNbr >= num_agch(trx, "PH-DATA-REQ"))
- sapi = GsmL1_Sapi_Pch;
- else
- sapi = GsmL1_Sapi_Agch;
- } else {
- LOGPFN(DL1C, LOGL_NOTICE, u32Fn, "unknown prim %d op %d "
- "chan_nr %d link_id %d\n", l1sap->oph.primitive,
- l1sap->oph.operation, chan_nr, link_id);
- msgb_free(l1msg);
- return -EINVAL;
- }
-
- /* convert l1sap message to GsmL1 primitive, keep payload */
- if (len) {
- /* data request */
- GsmL1_Prim_t *l1p = msgb_l1prim(l1msg);
- data_req_from_l1sap(l1p, fl1, u8Tn, u32Fn, sapi, subCh, u8BlockNbr, len);
- if (use_cache)
- memcpy(l1p->u.phDataReq.msgUnitParam.u8Buffer,
- lchan->tch.dtx.facch, msgb_l2len(msg));
- else if (dtx_dl_amr_enabled(lchan) &&
- ((lchan->tch.dtx.dl_amr_fsm->state == ST_ONSET_F) ||
- (lchan->tch.dtx.dl_amr_fsm->state == ST_U_INH_F) ||
- (lchan->tch.dtx.dl_amr_fsm->state == ST_F1_INH_F))) {
- if (sapi == GsmL1_Sapi_FacchF) {
- sapi = GsmL1_Sapi_TchF;
- }
- if (sapi == GsmL1_Sapi_FacchH) {
- sapi = GsmL1_Sapi_TchH;
- subCh = L1SAP_CHAN2SS_TCHH(chan_nr);
- u8BlockNbr = (u32Fn % 13) >> 2;
- }
- if (sapi == GsmL1_Sapi_TchH || sapi == GsmL1_Sapi_TchF) {
- /* FACCH interruption of DTX silence */
- /* cache FACCH data */
- memcpy(lchan->tch.dtx.facch, msg->l2h,
- msgb_l2len(msg));
- /* prepare ONSET or INH message */
- if(lchan->tch.dtx.dl_amr_fsm->state == ST_ONSET_F)
- l1p->u.phDataReq.msgUnitParam.u8Buffer[0] =
- GsmL1_TchPlType_Amr_Onset;
- else if(lchan->tch.dtx.dl_amr_fsm->state == ST_U_INH_F)
- l1p->u.phDataReq.msgUnitParam.u8Buffer[0] =
- GsmL1_TchPlType_Amr_SidUpdateInH;
- else if(lchan->tch.dtx.dl_amr_fsm->state == ST_F1_INH_F)
- l1p->u.phDataReq.msgUnitParam.u8Buffer[0] =
- GsmL1_TchPlType_Amr_SidFirstInH;
- /* ignored CMR/CMI pair */
- l1p->u.phDataReq.msgUnitParam.u8Buffer[1] = 0;
- l1p->u.phDataReq.msgUnitParam.u8Buffer[2] = 0;
- /* update length */
- data_req_from_l1sap(l1p, fl1, u8Tn, u32Fn, sapi,
- subCh, u8BlockNbr, 3);
- /* update FN so it can be checked by TCH silence
- resume handler */
- lchan->tch.dtx.fn = LCHAN_FN_DUMMY;
- }
- } else if (dtx_dl_amr_enabled(lchan) &&
- lchan->tch.dtx.dl_amr_fsm->state == ST_FACCH) {
- /* update FN so it can be checked by TCH silence
- resume handler */
- lchan->tch.dtx.fn = LCHAN_FN_DUMMY;
- }
- else {
- OSMO_ASSERT(msgb_l2len(msg) <= sizeof(l1p->u.phDataReq.msgUnitParam.u8Buffer));
- memcpy(l1p->u.phDataReq.msgUnitParam.u8Buffer, msg->l2h,
- msgb_l2len(msg));
- }
- LOGPFN(DL1P, LOGL_DEBUG, u32Fn, "PH-DATA.req(%s)\n",
- osmo_hexdump(l1p->u.phDataReq.msgUnitParam.u8Buffer,
- l1p->u.phDataReq.msgUnitParam.u8Size));
- } else {
- /* empty frame */
- GsmL1_Prim_t *l1p = msgb_l1prim(l1msg);
-
- empty_req_from_l1sap(l1p, fl1, u8Tn, u32Fn, sapi, subCh, u8BlockNbr);
- }
-
- /* send message to DSP's queue */
- if (osmo_wqueue_enqueue(&fl1->write_q[MQ_L1_WRITE], l1msg) != 0) {
- LOGPFN(DL1P, LOGL_ERROR, u32Fn, "MQ_L1_WRITE queue full. Dropping msg.\n");
- msgb_free(l1msg);
- } else
- dtx_int_signal(lchan);
-
- if (dtx_recursion(lchan))
- ph_data_req(trx, msg, l1sap, true);
- return 0;
-}
-
-static int ph_tch_req(struct gsm_bts_trx *trx, struct msgb *msg,
- struct osmo_phsap_prim *l1sap, bool use_cache, bool marker)
-{
- struct lc15l1_hdl *fl1 = trx_lc15l1_hdl(trx);
- struct gsm_lchan *lchan;
- uint32_t u32Fn;
- uint8_t u8Tn, subCh, u8BlockNbr = 0, sapi;
- uint8_t chan_nr;
- GsmL1_Prim_t *l1p;
- struct msgb *nmsg = NULL;
- int rc = -1;
-
- chan_nr = l1sap->u.tch.chan_nr;
- u32Fn = l1sap->u.tch.fn;
- u8Tn = L1SAP_CHAN2TS(chan_nr);
- u8BlockNbr = (u32Fn % 13) >> 2;
- if (L1SAP_IS_CHAN_TCHH(chan_nr)) {
- subCh = L1SAP_CHAN2SS_TCHH(chan_nr);
- sapi = GsmL1_Sapi_TchH;
- } else {
- subCh = 0x1f;
- sapi = GsmL1_Sapi_TchF;
- }
-
- lchan = get_lchan_by_chan_nr(trx, chan_nr);
-
- /* create new message and fill data */
- if (msg) {
- msgb_pull(msg, sizeof(*l1sap));
- /* create new message */
- nmsg = l1p_msgb_alloc();
- if (!nmsg)
- return -ENOMEM;
- l1p = msgb_l1prim(nmsg);
- rc = l1if_tch_encode(lchan,
- l1p->u.phDataReq.msgUnitParam.u8Buffer,
- &l1p->u.phDataReq.msgUnitParam.u8Size,
- msg->data, msg->len, u32Fn, use_cache,
- l1sap->u.tch.marker);
- if (rc < 0) {
- /* no data encoded for L1: smth will be generated below */
- msgb_free(nmsg);
- nmsg = NULL;
- }
- }
-
- /* no message/data, we might generate an empty traffic msg or re-send
- cached SID in case of DTX */
- if (!nmsg)
- nmsg = gen_empty_tch_msg(lchan, u32Fn);
-
- /* no traffic message, we generate an empty msg */
- if (!nmsg) {
- nmsg = l1p_msgb_alloc();
- if (!nmsg)
- return -ENOMEM;
- }
-
- l1p = msgb_l1prim(nmsg);
-
- /* if we provide data, or if data is already in nmsg */
- if (l1p->u.phDataReq.msgUnitParam.u8Size) {
- /* data request */
- data_req_from_l1sap(l1p, fl1, u8Tn, u32Fn, sapi, subCh,
- u8BlockNbr,
- l1p->u.phDataReq.msgUnitParam.u8Size);
- } else {
- /* empty frame */
- if (trx->bts->dtxd && trx != trx->bts->c0)
- lchan->tch.dtx.dl_active = true;
- empty_req_from_l1sap(l1p, fl1, u8Tn, u32Fn, sapi, subCh, u8BlockNbr);
- }
- /* send message to DSP's queue */
- osmo_wqueue_enqueue(&fl1->write_q[MQ_L1_WRITE], nmsg);
- if (dtx_is_first_p1(lchan))
- dtx_dispatch(lchan, E_FIRST);
- else
- dtx_int_signal(lchan);
-
- if (dtx_recursion(lchan)) /* DTX: send voice after ONSET was sent */
- return ph_tch_req(trx, l1sap->oph.msg, l1sap, true, false);
-
- return 0;
-}
-
-static int mph_info_req(struct gsm_bts_trx *trx, struct msgb *msg,
- struct osmo_phsap_prim *l1sap)
-{
- struct lc15l1_hdl *fl1 = trx_lc15l1_hdl(trx);
- uint8_t chan_nr;
- struct gsm_lchan *lchan;
- int rc = 0;
-
- switch (l1sap->u.info.type) {
- case PRIM_INFO_ACT_CIPH:
- chan_nr = l1sap->u.info.u.ciph_req.chan_nr;
- lchan = get_lchan_by_chan_nr(trx, chan_nr);
- if (l1sap->u.info.u.ciph_req.uplink) {
- l1if_set_ciphering(fl1, lchan, 0);
- lchan->ciph_state = LCHAN_CIPH_RX_REQ;
- }
- if (l1sap->u.info.u.ciph_req.downlink) {
- l1if_set_ciphering(fl1, lchan, 1);
- lchan->ciph_state = LCHAN_CIPH_RX_CONF_TX_REQ;
- }
- if (l1sap->u.info.u.ciph_req.downlink
- && l1sap->u.info.u.ciph_req.uplink)
- lchan->ciph_state = LCHAN_CIPH_RXTX_REQ;
- break;
- case PRIM_INFO_ACTIVATE:
- case PRIM_INFO_DEACTIVATE:
- case PRIM_INFO_MODIFY:
- chan_nr = l1sap->u.info.u.act_req.chan_nr;
- lchan = get_lchan_by_chan_nr(trx, chan_nr);
- if (l1sap->u.info.type == PRIM_INFO_ACTIVATE)
- l1if_rsl_chan_act(lchan);
- else if (l1sap->u.info.type == PRIM_INFO_MODIFY) {
- if (lchan->ho.active == HANDOVER_WAIT_FRAME)
- l1if_rsl_chan_mod(lchan);
- else
- l1if_rsl_mode_modify(lchan);
- } else if (l1sap->u.info.u.act_req.sacch_only)
- l1if_rsl_deact_sacch(lchan);
- else
- l1if_rsl_chan_rel(lchan);
- break;
- default:
- LOGP(DL1C, LOGL_NOTICE, "unknown MPH-INFO.req %d\n",
- l1sap->u.info.type);
- rc = -EINVAL;
- }
-
- return rc;
-}
-
-/* primitive from common part */
-int bts_model_l1sap_down(struct gsm_bts_trx *trx, struct osmo_phsap_prim *l1sap)
-{
- struct msgb *msg = l1sap->oph.msg;
- int rc = 0;
-
- /* called functions MUST NOT take ownership of msgb, as it is
- * free()d below */
- switch (OSMO_PRIM_HDR(&l1sap->oph)) {
- case OSMO_PRIM(PRIM_PH_DATA, PRIM_OP_REQUEST):
- rc = ph_data_req(trx, msg, l1sap, false);
- break;
- case OSMO_PRIM(PRIM_TCH, PRIM_OP_REQUEST):
- rc = ph_tch_req(trx, msg, l1sap, false, l1sap->u.tch.marker);
- break;
- case OSMO_PRIM(PRIM_MPH_INFO, PRIM_OP_REQUEST):
- rc = mph_info_req(trx, msg, l1sap);
- break;
- default:
- LOGP(DL1C, LOGL_NOTICE, "unknown prim %d op %d\n",
- l1sap->oph.primitive, l1sap->oph.operation);
- rc = -EINVAL;
- }
-
- msgb_free(msg);
-
- return rc;
-}
-
-static int handle_mph_time_ind(struct lc15l1_hdl *fl1,
- GsmL1_MphTimeInd_t *time_ind,
- struct msgb *msg)
-{
- struct gsm_bts_trx *trx = lc15l1_hdl_trx(fl1);
- struct gsm_bts *bts = trx->bts;
- struct osmo_phsap_prim l1sap;
- uint32_t fn;
-
- /* increment the primitive count for the alive timer */
- fl1->alive_prim_cnt++;
-
- /* ignore every time indication, except for c0 */
- if (trx != bts->c0) {
- msgb_free(msg);
- return 0;
- }
-
- fn = time_ind->u32Fn;
-
- memset(&l1sap, 0, sizeof(l1sap));
- osmo_prim_init(&l1sap.oph, SAP_GSM_PH, PRIM_MPH_INFO,
- PRIM_OP_INDICATION, NULL);
- l1sap.u.info.type = PRIM_INFO_TIME;
- l1sap.u.info.u.time_ind.fn = fn;
-
- msgb_free(msg);
-
- return l1sap_up(trx, &l1sap);
-}
-
-static enum gsm_phys_chan_config pick_pchan(struct gsm_bts_trx_ts *ts)
-{
- switch (ts->pchan) {
- case GSM_PCHAN_TCH_F_PDCH:
- if (ts->flags & TS_F_PDCH_ACTIVE)
- return GSM_PCHAN_PDCH;
- return GSM_PCHAN_TCH_F;
- case GSM_PCHAN_TCH_F_TCH_H_PDCH:
- return ts->dyn.pchan_is;
- default:
- return ts->pchan;
- }
-}
-
-static uint8_t chan_nr_by_sapi(struct gsm_bts_trx_ts *ts,
- GsmL1_Sapi_t sapi, GsmL1_SubCh_t subCh,
- uint8_t u8Tn, uint32_t u32Fn)
-{
- uint8_t cbits = 0;
- enum gsm_phys_chan_config pchan = pick_pchan(ts);
- OSMO_ASSERT(pchan != GSM_PCHAN_TCH_F_PDCH);
- OSMO_ASSERT(pchan != GSM_PCHAN_TCH_F_TCH_H_PDCH);
-
- switch (sapi) {
- case GsmL1_Sapi_Bcch:
- cbits = 0x10;
- break;
- case GsmL1_Sapi_Cbch:
- cbits = 0xc8 >> 3; /* Osmocom extension for CBCH via L1SAP */
- break;
- case GsmL1_Sapi_Sacch:
- switch(pchan) {
- case GSM_PCHAN_TCH_F:
- cbits = 0x01;
- break;
- case GSM_PCHAN_TCH_H:
- cbits = 0x02 + subCh;
- break;
- case GSM_PCHAN_CCCH_SDCCH4:
- case GSM_PCHAN_CCCH_SDCCH4_CBCH:
- cbits = 0x04 + subCh;
- break;
- case GSM_PCHAN_SDCCH8_SACCH8C:
- case GSM_PCHAN_SDCCH8_SACCH8C_CBCH:
- cbits = 0x08 + subCh;
- break;
- default:
- LOGP(DL1C, LOGL_ERROR, "SACCH for pchan %d?\n",
- pchan);
- return 0;
- }
- break;
- case GsmL1_Sapi_Sdcch:
- switch(pchan) {
- case GSM_PCHAN_CCCH_SDCCH4:
- case GSM_PCHAN_CCCH_SDCCH4_CBCH:
- cbits = 0x04 + subCh;
- break;
- case GSM_PCHAN_SDCCH8_SACCH8C:
- case GSM_PCHAN_SDCCH8_SACCH8C_CBCH:
- cbits = 0x08 + subCh;
- break;
- default:
- LOGP(DL1C, LOGL_ERROR, "SDCCH for pchan %d?\n",
- pchan);
- return 0;
- }
- break;
- case GsmL1_Sapi_Agch:
- case GsmL1_Sapi_Pch:
- cbits = 0x12;
- break;
- case GsmL1_Sapi_Pdtch:
- case GsmL1_Sapi_Pacch:
- switch(pchan) {
- case GSM_PCHAN_PDCH:
- cbits = 0x01;
- break;
- default:
- LOGP(DL1C, LOGL_ERROR, "PDTCH for pchan %d?\n",
- pchan);
- return 0;
- }
- break;
- case GsmL1_Sapi_TchF:
- cbits = 0x01;
- break;
- case GsmL1_Sapi_TchH:
- cbits = 0x02 + subCh;
- break;
- case GsmL1_Sapi_FacchF:
- cbits = 0x01;
- break;
- case GsmL1_Sapi_FacchH:
- cbits = 0x02 + subCh;
- break;
- case GsmL1_Sapi_Ptcch:
- if (!L1SAP_IS_PTCCH(u32Fn)) {
- LOGP(DL1C, LOGL_FATAL, "Not expecting PTCCH at frame "
- "number other than 12, got it at %u (%u). "
- "Please fix!\n", u32Fn % 52, u32Fn);
- abort();
- }
- switch(pchan) {
- case GSM_PCHAN_PDCH:
- cbits = 0x01;
- break;
- default:
- LOGP(DL1C, LOGL_ERROR, "PTCCH for pchan %d?\n",
- pchan);
- return 0;
- }
- break;
- default:
- return 0;
- }
-
- /* not reached due to default case above */
- return (cbits << 3) | u8Tn;
-}
-
-static const enum l1sap_common_sapi common_sapi_by_sapi_t[] = {
- [GsmL1_Sapi_Idle] = L1SAP_COMMON_SAPI_IDLE,
- [GsmL1_Sapi_Fcch] = L1SAP_COMMON_SAPI_FCCH,
- [GsmL1_Sapi_Sch] = L1SAP_COMMON_SAPI_SCH,
- [GsmL1_Sapi_Sacch] = L1SAP_COMMON_SAPI_SACCH,
- [GsmL1_Sapi_Sdcch] = L1SAP_COMMON_SAPI_SDCCH,
- [GsmL1_Sapi_Bcch] = L1SAP_COMMON_SAPI_BCCH,
- [GsmL1_Sapi_Pch] = L1SAP_COMMON_SAPI_PCH,
- [GsmL1_Sapi_Agch] = L1SAP_COMMON_SAPI_AGCH,
- [GsmL1_Sapi_Cbch] = L1SAP_COMMON_SAPI_CBCH,
- [GsmL1_Sapi_Rach] = L1SAP_COMMON_SAPI_RACH,
- [GsmL1_Sapi_TchF] = L1SAP_COMMON_SAPI_TCH_F,
- [GsmL1_Sapi_FacchF] = L1SAP_COMMON_SAPI_FACCH_F,
- [GsmL1_Sapi_TchH] = L1SAP_COMMON_SAPI_TCH_H,
- [GsmL1_Sapi_FacchH] = L1SAP_COMMON_SAPI_FACCH_H,
- [GsmL1_Sapi_Nch] = L1SAP_COMMON_SAPI_NCH,
- [GsmL1_Sapi_Pdtch] = L1SAP_COMMON_SAPI_PDTCH,
- [GsmL1_Sapi_Pacch] = L1SAP_COMMON_SAPI_PACCH,
- [GsmL1_Sapi_Pbcch] = L1SAP_COMMON_SAPI_PBCCH,
- [GsmL1_Sapi_Pagch] = L1SAP_COMMON_SAPI_PAGCH,
- [GsmL1_Sapi_Ppch] = L1SAP_COMMON_SAPI_PPCH,
- [GsmL1_Sapi_Pnch] = L1SAP_COMMON_SAPI_PNCH,
- [GsmL1_Sapi_Ptcch] = L1SAP_COMMON_SAPI_PTCCH,
- [GsmL1_Sapi_Prach] = L1SAP_COMMON_SAPI_PRACH,
-};
-
-static enum l1sap_common_sapi get_common_sapi(GsmL1_Sapi_t sapi)
-{
- if (sapi >= GsmL1_Sapi_NUM)
- return L1SAP_COMMON_SAPI_UNKNOWN;
- return common_sapi_by_sapi_t[sapi];
-}
-
-static void set_log_ctx_sapi(GsmL1_Sapi_t sapi)
-{
- l1sap_log_ctx_sapi = get_common_sapi(sapi);
- log_set_context(LOG_CTX_L1_SAPI, &l1sap_log_ctx_sapi);
-}
-
-static int handle_ph_readytosend_ind(struct lc15l1_hdl *fl1,
- GsmL1_PhReadyToSendInd_t *rts_ind,
- struct msgb *l1p_msg)
-{
- struct gsm_bts_trx *trx = lc15l1_hdl_trx(fl1);
- struct gsm_bts *bts = trx->bts;
- struct msgb *resp_msg;
- GsmL1_PhDataReq_t *data_req;
- GsmL1_MsgUnitParam_t *msu_param;
- struct gsm_time g_time;
- uint32_t t3p;
- int rc;
- struct osmo_phsap_prim *l1sap;
- uint8_t chan_nr, link_id;
- uint32_t fn;
-
- set_log_ctx_sapi(rts_ind->sapi);
-
- /* check if primitive should be handled by common part */
- chan_nr = chan_nr_by_sapi(&trx->ts[rts_ind->u8Tn], rts_ind->sapi,
- rts_ind->subCh, rts_ind->u8Tn, rts_ind->u32Fn);
- if (chan_nr) {
- fn = rts_ind->u32Fn;
- if (rts_ind->sapi == GsmL1_Sapi_Sacch)
- link_id = LID_SACCH;
- else
- link_id = LID_DEDIC;
- /* recycle the msgb and use it for the L1 primitive,
- * which means that we (or our caller) must not free it */
- rc = msgb_trim(l1p_msg, sizeof(*l1sap));
- if (rc < 0)
- MSGB_ABORT(l1p_msg, "No room for primitive\n");
- l1sap = msgb_l1sap_prim(l1p_msg);
- if (rts_ind->sapi == GsmL1_Sapi_TchF
- || rts_ind->sapi == GsmL1_Sapi_TchH) {
- osmo_prim_init(&l1sap->oph, SAP_GSM_PH, PRIM_TCH_RTS,
- PRIM_OP_INDICATION, l1p_msg);
- l1sap->u.tch.chan_nr = chan_nr;
- l1sap->u.tch.fn = fn;
- } else {
- osmo_prim_init(&l1sap->oph, SAP_GSM_PH, PRIM_PH_RTS,
- PRIM_OP_INDICATION, l1p_msg);
- l1sap->u.data.link_id = link_id;
- l1sap->u.data.chan_nr = chan_nr;
- l1sap->u.data.fn = fn;
- }
-
- return l1sap_up(trx, l1sap);
- }
-
- gsm_fn2gsmtime(&g_time, rts_ind->u32Fn);
-
- DEBUGPGT(DL1P, &g_time, "Rx PH-RTS.ind SAPI=%s\n",
- get_value_string(lc15bts_l1sapi_names, rts_ind->sapi));
-
- /* in all other cases, we need to allocate a new PH-DATA.ind
- * primitive msgb and start to fill it */
- resp_msg = l1p_msgb_alloc();
- data_req = data_req_from_rts_ind(msgb_l1prim(resp_msg), rts_ind);
- msu_param = &data_req->msgUnitParam;
-
- /* set default size */
- msu_param->u8Size = GSM_MACBLOCK_LEN;
-
- switch (rts_ind->sapi) {
- case GsmL1_Sapi_Sch:
- /* compute T3prime */
- t3p = (g_time.t3 - 1) / 10;
- /* fill SCH burst with data */
- msu_param->u8Size = 4;
- msu_param->u8Buffer[0] = (bts->bsic << 2) | (g_time.t1 >> 9);
- msu_param->u8Buffer[1] = (g_time.t1 >> 1);
- msu_param->u8Buffer[2] = (g_time.t1 << 7) | (g_time.t2 << 2) | (t3p >> 1);
- msu_param->u8Buffer[3] = (t3p & 1);
- break;
- case GsmL1_Sapi_Prach:
- goto empty_frame;
- break;
- default:
- memcpy(msu_param->u8Buffer, fill_frame, GSM_MACBLOCK_LEN);
- break;
- }
-tx:
-
- /* transmit */
- if (osmo_wqueue_enqueue(&fl1->write_q[MQ_L1_WRITE], resp_msg) != 0) {
- LOGPGT(DL1C, LOGL_ERROR, &g_time, "MQ_L1_WRITE queue full. Dropping msg.\n");
- msgb_free(resp_msg);
- }
-
- /* free the msgb, as we have not handed it to l1sap and thus
- * need to release its memory */
- msgb_free(l1p_msg);
- return 0;
-
-empty_frame:
- /* in case we decide to send an empty frame... */
- empty_req_from_rts_ind(msgb_l1prim(resp_msg), rts_ind);
-
- goto tx;
-}
-
-#define LOG_FMT_MEAS "Meas: RSSI %-3.2f dBm, Qual %-3.2f dB, BER %-3.2f, Timing %d"
-#define LOG_PARAM_MEAS(meas_param) (meas_param)->fRssi, (meas_param)->fLinkQuality, (meas_param)->fBer, (meas_param)->i16BurstTiming
-
-static int process_meas_res(struct gsm_bts_trx *trx, uint8_t chan_nr,
- GsmL1_MeasParam_t *m, uint32_t fn)
-{
- struct osmo_phsap_prim l1sap;
- memset(&l1sap, 0, sizeof(l1sap));
- osmo_prim_init(&l1sap.oph, SAP_GSM_PH, PRIM_MPH_INFO,
- PRIM_OP_INDICATION, NULL);
- l1sap.u.info.type = PRIM_INFO_MEAS;
- l1sap.u.info.u.meas_ind.chan_nr = chan_nr;
- l1sap.u.info.u.meas_ind.ta_offs_256bits = m->i16BurstTiming*64;
- l1sap.u.info.u.meas_ind.ber10k = (unsigned int) (m->fBer * 10000);
- l1sap.u.info.u.meas_ind.inv_rssi = (uint8_t) (m->fRssi * -1);
- l1sap.u.info.u.meas_ind.fn = fn;
-
- /* l1sap wants to take msgb ownership. However, as there is no
- * msg, it will msgb_free(l1sap.oph.msg == NULL) */
- return l1sap_up(trx, &l1sap);
-}
-
-static int handle_ph_data_ind(struct lc15l1_hdl *fl1, GsmL1_PhDataInd_t *data_ind,
- struct msgb *l1p_msg)
-{
- struct gsm_bts_trx *trx = lc15l1_hdl_trx(fl1);
- uint8_t chan_nr, link_id;
- struct osmo_phsap_prim *l1sap;
- uint32_t fn;
- struct gsm_time g_time;
- uint8_t *data, len;
- int rc = 0;
- int8_t rssi;
-
- set_log_ctx_sapi(data_ind->sapi);
-
- chan_nr = chan_nr_by_sapi(&trx->ts[data_ind->u8Tn], data_ind->sapi,
- data_ind->subCh, data_ind->u8Tn, data_ind->u32Fn);
- fn = data_ind->u32Fn;
- link_id = (data_ind->sapi == GsmL1_Sapi_Sacch) ? LID_SACCH : LID_DEDIC;
- gsm_fn2gsmtime(&g_time, fn);
-
- if (!chan_nr) {
- LOGPGT(DL1C, LOGL_ERROR, &g_time, "PH-DATA-INDICATION for unknown sapi %s (%d)\n",
- get_value_string(lc15bts_l1sapi_names, data_ind->sapi), data_ind->sapi);
- msgb_free(l1p_msg);
- return ENOTSUP;
- }
-
- process_meas_res(trx, chan_nr, &data_ind->measParam, fn);
-
-
- DEBUGPGT(DL1P, &g_time, "Rx PH-DATA.ind %s (hL2 %08x): %s, " LOG_FMT_MEAS "\n",
- get_value_string(lc15bts_l1sapi_names, data_ind->sapi), (uint32_t)data_ind->hLayer2,
- osmo_hexdump(data_ind->msgUnitParam.u8Buffer, data_ind->msgUnitParam.u8Size),
- LOG_PARAM_MEAS(&data_ind->measParam));
-
- /* check for TCH */
- if (data_ind->sapi == GsmL1_Sapi_TchF
- || data_ind->sapi == GsmL1_Sapi_TchH) {
- /* TCH speech frame handling */
- rc = l1if_tch_rx(trx, chan_nr, l1p_msg);
- msgb_free(l1p_msg);
- return rc;
- }
-
- /* get rssi */
- rssi = (int8_t) (data_ind->measParam.fRssi);
- /* get data pointer and length */
- data = data_ind->msgUnitParam.u8Buffer;
- len = data_ind->msgUnitParam.u8Size;
- /* pull lower header part before data */
- msgb_pull(l1p_msg, data - l1p_msg->data);
- /* trim remaining data to it's size, to get rid of upper header part */
- rc = msgb_trim(l1p_msg, len);
- if (rc < 0)
- MSGB_ABORT(l1p_msg, "No room for primitive data\n");
- l1p_msg->l2h = l1p_msg->data;
- /* push new l1 header */
- l1p_msg->l1h = msgb_push(l1p_msg, sizeof(*l1sap));
- /* fill header */
- l1sap = msgb_l1sap_prim(l1p_msg);
- osmo_prim_init(&l1sap->oph, SAP_GSM_PH, PRIM_PH_DATA,
- PRIM_OP_INDICATION, l1p_msg);
- l1sap->u.data.link_id = link_id;
- l1sap->u.data.chan_nr = chan_nr;
- l1sap->u.data.fn = fn;
- l1sap->u.data.rssi = rssi;
- l1sap->u.data.ber10k = data_ind->measParam.fBer * 10000;
- l1sap->u.data.ta_offs_256bits = data_ind->measParam.i16BurstTiming*64;
- l1sap->u.data.lqual_cb = data_ind->measParam.fLinkQuality * 10;
-
- return l1sap_up(trx, l1sap);
-}
-
-static int handle_ph_ra_ind(struct lc15l1_hdl *fl1, GsmL1_PhRaInd_t *ra_ind,
- struct msgb *l1p_msg)
-{
- struct gsm_bts_trx *trx = lc15l1_hdl_trx(fl1);
- struct gsm_lchan *lchan;
- struct osmo_phsap_prim *l1sap;
- int rc;
- struct ph_rach_ind_param rach_ind_param;
-
- set_log_ctx_sapi(ra_ind->sapi);
- LOGPFN(DL1C, LOGL_DEBUG, ra_ind->u32Fn, "Rx PH-RA.ind, " LOG_FMT_MEAS "\n",
- LOG_PARAM_MEAS(&ra_ind->measParam));
-
- if ((ra_ind->msgUnitParam.u8Size != 1) &&
- (ra_ind->msgUnitParam.u8Size != 2)) {
- LOGPFN(DL1P, LOGL_ERROR, ra_ind->u32Fn, "PH-RACH-INDICATION has %d bits\n", ra_ind->sapi);
- msgb_free(l1p_msg);
- return 0;
- }
-
- /* We need to evaluate ra_ind before below msgb_trim(), since that invalidates *ra_ind. */
- rach_ind_param = (struct ph_rach_ind_param) {
- /* .chan_nr set below */
- /* .ra set below */
- .acc_delay = 0,
- .fn = ra_ind->u32Fn,
- /* .is_11bit set below */
- /* .burst_type set below */
- .rssi = (int8_t) ra_ind->measParam.fRssi,
- .ber10k = (unsigned int) (ra_ind->measParam.fBer * 10000.0),
- .acc_delay_256bits = ra_ind->measParam.i16BurstTiming * 64,
- .lqual_cb = (int16_t) ra_ind->measParam.fLinkQuality * 10, /* centiBels */
- };
-
- lchan = l1if_hLayer_to_lchan(trx, (uint32_t)ra_ind->hLayer2);
- if (!lchan || lchan->ts->pchan == GSM_PCHAN_CCCH ||
- lchan->ts->pchan == GSM_PCHAN_CCCH_SDCCH4 ||
- lchan->ts->pchan == GSM_PCHAN_CCCH_SDCCH4_CBCH)
- rach_ind_param.chan_nr = RSL_CHAN_RACH;
- else
- rach_ind_param.chan_nr = gsm_lchan2chan_nr(lchan);
-
- if (ra_ind->msgUnitParam.u8Size == 2) {
- uint16_t temp;
- uint16_t ra = ra_ind->msgUnitParam.u8Buffer[0];
- ra = ra << 3;
- temp = (ra_ind->msgUnitParam.u8Buffer[1] & 0x7);
- ra = ra | temp;
- rach_ind_param.is_11bit = 1;
- rach_ind_param.ra = ra;
- } else {
- rach_ind_param.is_11bit = 0;
- rach_ind_param.ra = ra_ind->msgUnitParam.u8Buffer[0];
- }
-
- /* the old legacy full-bits acc_delay cannot express negative values */
- if (ra_ind->measParam.i16BurstTiming > 0)
- rach_ind_param.acc_delay = ra_ind->measParam.i16BurstTiming >> 2;
-
- /* mapping of the burst type, the values are specific to
- * osmo-bts-litecell15 */
- switch (ra_ind->burstType) {
- case GsmL1_BurstType_Access_0:
- rach_ind_param.burst_type =
- GSM_L1_BURST_TYPE_ACCESS_0;
- break;
- case GsmL1_BurstType_Access_1:
- rach_ind_param.burst_type =
- GSM_L1_BURST_TYPE_ACCESS_1;
- break;
- case GsmL1_BurstType_Access_2:
- rach_ind_param.burst_type =
- GSM_L1_BURST_TYPE_ACCESS_2;
- break;
- default:
- rach_ind_param.burst_type =
- GSM_L1_BURST_TYPE_NONE;
- break;
- }
-
- /* msgb_trim() invalidates ra_ind, make that abundantly clear: */
- ra_ind = NULL;
- rc = msgb_trim(l1p_msg, sizeof(*l1sap));
- if (rc < 0)
- MSGB_ABORT(l1p_msg, "No room for primitive data\n");
- l1sap = msgb_l1sap_prim(l1p_msg);
- osmo_prim_init(&l1sap->oph, SAP_GSM_PH, PRIM_PH_RACH, PRIM_OP_INDICATION,
- l1p_msg);
- l1sap->u.rach_ind = rach_ind_param;
-
- return l1sap_up(trx, l1sap);
-}
-
-/* handle any random indication from the L1 */
-static int l1if_handle_ind(struct lc15l1_hdl *fl1, struct msgb *msg)
-{
- GsmL1_Prim_t *l1p = msgb_l1prim(msg);
- int rc = 0;
-
- /* all the below called functions must take ownership of the msgb */
- switch (l1p->id) {
- case GsmL1_PrimId_MphTimeInd:
- rc = handle_mph_time_ind(fl1, &l1p->u.mphTimeInd, msg);
- break;
- case GsmL1_PrimId_MphSyncInd:
- msgb_free(msg);
- break;
- case GsmL1_PrimId_PhConnectInd:
- msgb_free(msg);
- break;
- case GsmL1_PrimId_PhReadyToSendInd:
- rc = handle_ph_readytosend_ind(fl1, &l1p->u.phReadyToSendInd,
- msg);
- break;
- case GsmL1_PrimId_PhDataInd:
- rc = handle_ph_data_ind(fl1, &l1p->u.phDataInd, msg);
- break;
- case GsmL1_PrimId_PhRaInd:
- rc = handle_ph_ra_ind(fl1, &l1p->u.phRaInd, msg);
- break;
- default:
- msgb_free(msg);
- }
-
- return rc;
-}
-
-static inline int is_prim_compat(GsmL1_Prim_t *l1p, struct wait_l1_conf *wlc)
-{
- if (wlc->is_sys_prim != 0)
- return 0;
- if (l1p->id != wlc->conf_prim_id)
- return 0;
- if (l1p_get_hLayer3(l1p) != wlc->conf_hLayer3)
- return 0;
- return 1;
-}
-
-int l1if_handle_l1prim(int wq, struct lc15l1_hdl *fl1h, struct msgb *msg)
-{
- GsmL1_Prim_t *l1p = msgb_l1prim(msg);
- struct wait_l1_conf *wlc;
- int rc;
-
- switch (l1p->id) {
- case GsmL1_PrimId_MphTimeInd:
- /* silent, don't clog the log file */
- break;
- default:
- LOGP(DL1P, LOGL_DEBUG, "Rx L1 prim %s on queue %d\n",
- get_value_string(lc15bts_l1prim_names, l1p->id), wq);
- }
-
- /* check if this is a resposne to a sync-waiting request */
- llist_for_each_entry(wlc, &fl1h->wlc_list, list) {
- if (is_prim_compat(l1p, wlc)) {
- llist_del(&wlc->list);
- if (wlc->cb) {
- /* call-back function must take
- * ownership of msgb */
- rc = wlc->cb(lc15l1_hdl_trx(fl1h), msg,
- wlc->cb_data);
- } else {
- rc = 0;
- msgb_free(msg);
- }
- release_wlc(wlc);
- return rc;
- }
- }
-
- /* if we reach here, it is not a Conf for a pending Req */
- return l1if_handle_ind(fl1h, msg);
-}
-
-int l1if_handle_sysprim(struct lc15l1_hdl *fl1h, struct msgb *msg)
-{
- Litecell15_Prim_t *sysp = msgb_sysprim(msg);
- struct wait_l1_conf *wlc;
- int rc;
-
- LOGP(DL1P, LOGL_DEBUG, "Rx SYS prim %s\n",
- get_value_string(lc15bts_sysprim_names, sysp->id));
-
- /* check if this is a resposne to a sync-waiting request */
- llist_for_each_entry(wlc, &fl1h->wlc_list, list) {
- /* the limitation here is that we cannot have multiple callers
- * sending the same primitive */
- if (wlc->is_sys_prim && sysp->id == wlc->conf_prim_id) {
- llist_del(&wlc->list);
- if (wlc->cb) {
- /* call-back function must take
- * ownership of msgb */
- rc = wlc->cb(lc15l1_hdl_trx(fl1h), msg,
- wlc->cb_data);
- } else {
- rc = 0;
- msgb_free(msg);
- }
- release_wlc(wlc);
- return rc;
- }
- }
- /* if we reach here, it is not a Conf for a pending Req */
- return l1if_handle_ind(fl1h, msg);
-}
-
-static int activate_rf_compl_cb(struct gsm_bts_trx *trx, struct msgb *resp,
- void *data)
-{
- Litecell15_Prim_t *sysp = msgb_sysprim(resp);
- GsmL1_Status_t status;
- int on = 0;
- unsigned int i;
-
- if (sysp->id == Litecell15_PrimId_ActivateRfCnf)
- on = 1;
-
- if (on)
- status = sysp->u.activateRfCnf.status;
- else
- status = sysp->u.deactivateRfCnf.status;
-
- LOGP(DL1C, LOGL_INFO, "Rx RF-%sACT.conf (status=%s)\n", on ? "" : "DE",
- get_value_string(lc15bts_l1status_names, status));
-
- struct bts_lc15_priv *bts_lc15 = trx->bts->model_priv;
-
- if (on) {
- if (status != GsmL1_Status_Success) {
- LOGP(DL1C, LOGL_FATAL, "RF-ACT.conf with status %s\n",
- get_value_string(lc15bts_l1status_names, status));
- bts_shutdown(trx->bts, "RF-ACT failure");
- } else {
- if (bts_lc15->led_ctrl_mode == LC15_LED_CONTROL_BTS)
- bts_update_status(BTS_STATUS_RF_ACTIVE, 1);
- }
-
- /* signal availability */
- osmo_fsm_inst_dispatch(trx->mo.fi, NM_EV_SW_ACT, NULL);
- osmo_fsm_inst_dispatch(trx->bb_transc.mo.fi, NM_EV_SW_ACT, NULL);
- } else {
- if (bts_lc15->led_ctrl_mode == LC15_LED_CONTROL_BTS)
- bts_update_status(BTS_STATUS_RF_ACTIVE, 0);
- osmo_fsm_inst_dispatch(trx->mo.fi, NM_EV_DISABLE, NULL);
- osmo_fsm_inst_dispatch(trx->bb_transc.mo.fi, NM_EV_DISABLE, NULL);
- }
-
- msgb_free(resp);
-
- return 0;
-}
-
-/* activate or de-activate the entire RF-Frontend */
-int l1if_activate_rf(struct lc15l1_hdl *hdl, int on)
-{
- struct msgb *msg = sysp_msgb_alloc();
- Litecell15_Prim_t *sysp = msgb_sysprim(msg);
- struct phy_instance *pinst = hdl->phy_inst;
-
- if (on) {
- sysp->id = Litecell15_PrimId_ActivateRfReq;
- sysp->u.activateRfReq.msgq.u8UseTchMsgq = 0;
- sysp->u.activateRfReq.msgq.u8UsePdtchMsgq = pcu_direct;
-
- sysp->u.activateRfReq.u8UnusedTsMode = pinst->u.lc15.pedestal_mode;
-
- sysp->u.activateRfReq.u8McCorrMode = 0;
-
- /* diversity mode: 0: SISO-A, 1: SISO-B, 2: MRC */
- sysp->u.activateRfReq.u8DiversityMode = pinst->u.lc15.diversity_mode;
-
- /* maximum cell size in quarter-bits, 90 == 12.456 km */
- sysp->u.activateRfReq.u8MaxCellSize = pinst->u.lc15.max_cell_size;
-
-#if LITECELL15_API_VERSION >= LITECELL15_API(2,1,7)
- /* auto tx power adjustment mode 0:none, 1: automatic*/
- sysp->u.activateRfReq.u8EnAutoPowerAdjust = pinst->u.lc15.tx_pwr_adj_mode;
-#endif
-
- } else {
- sysp->id = Litecell15_PrimId_DeactivateRfReq;
- }
-
- return l1if_req_compl(hdl, msg, activate_rf_compl_cb, NULL);
-}
-
-static void mute_handle_ts(struct gsm_bts_trx_ts *ts, int is_muted)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(ts->lchan); i++) {
- struct gsm_lchan *lchan = &ts->lchan[i];
-
- if (!is_muted)
- continue;
-
- if (lchan->state != LCHAN_S_ACTIVE)
- continue;
-
- /* skip channels that might be active for another reason */
- if (lchan->type == GSM_LCHAN_CCCH)
- continue;
- if (lchan->type == GSM_LCHAN_PDTCH)
- continue;
-
- if (lchan->s <= 0)
- continue;
-
- lchan->s = 0;
- rsl_tx_conn_fail(lchan, RSL_ERR_RADIO_LINK_FAIL);
- }
-}
-
-static int mute_rf_compl_cb(struct gsm_bts_trx *trx, struct msgb *resp,
- void *data)
-{
- struct lc15l1_hdl *fl1h = trx_lc15l1_hdl(trx);
- Litecell15_Prim_t *sysp = msgb_sysprim(resp);
- GsmL1_Status_t status;
-
- status = sysp->u.muteRfCnf.status;
-
- if (status != GsmL1_Status_Success) {
- LOGP(DL1C, LOGL_ERROR, "Rx RF-MUTE.conf with status %s\n",
- get_value_string(lc15bts_l1status_names, status));
- oml_mo_rf_lock_chg(&trx->mo, fl1h->last_rf_mute, 0);
- } else {
- int i;
-
- LOGP(DL1C, LOGL_INFO, "Rx RF-MUTE.conf with status=%s\n",
- get_value_string(lc15bts_l1status_names, status));
- bts_update_status(BTS_STATUS_RF_MUTE, fl1h->last_rf_mute[0]);
- oml_mo_rf_lock_chg(&trx->mo, fl1h->last_rf_mute, 1);
-
- osmo_static_assert(
- ARRAY_SIZE(trx->ts) >= ARRAY_SIZE(fl1h->last_rf_mute),
- ts_array_size);
-
- for (i = 0; i < ARRAY_SIZE(fl1h->last_rf_mute); ++i)
- mute_handle_ts(&trx->ts[i], fl1h->last_rf_mute[i]);
- }
-
- msgb_free(resp);
-
- return 0;
-}
-
-/* mute/unmute RF time slots */
-int l1if_mute_rf(struct lc15l1_hdl *hdl, uint8_t mute[8], l1if_compl_cb *cb)
-{
- struct msgb *msg = sysp_msgb_alloc();
- Litecell15_Prim_t *sysp = msgb_sysprim(msg);
-
- LOGP(DL1C, LOGL_INFO, "Tx RF-MUTE.req (%d, %d, %d, %d, %d, %d, %d, %d)\n",
- mute[0], mute[1], mute[2], mute[3],
- mute[4], mute[5], mute[6], mute[7]
- );
-
- sysp->id = Litecell15_PrimId_MuteRfReq;
- memcpy(sysp->u.muteRfReq.u8Mute, mute, sizeof(sysp->u.muteRfReq.u8Mute));
- /* save for later use */
- memcpy(hdl->last_rf_mute, mute, sizeof(hdl->last_rf_mute));
-
- return l1if_req_compl(hdl, msg, cb ? cb : mute_rf_compl_cb, NULL);
-}
-
-/* call-back on arrival of DSP+FPGA version + band capability */
-static int info_compl_cb(struct gsm_bts_trx *trx, struct msgb *resp,
- void *data)
-{
- Litecell15_Prim_t *sysp = msgb_sysprim(resp);
- Litecell15_SystemInfoCnf_t *sic = &sysp->u.systemInfoCnf;
- struct lc15l1_hdl *fl1h = trx_lc15l1_hdl(trx);
- int rc;
-
- fl1h->hw_info.dsp_version[0] = sic->dspVersion.major;
- fl1h->hw_info.dsp_version[1] = sic->dspVersion.minor;
- fl1h->hw_info.dsp_version[2] = sic->dspVersion.build;
-
- fl1h->hw_info.fpga_version[0] = sic->fpgaVersion.major;
- fl1h->hw_info.fpga_version[1] = sic->fpgaVersion.minor;
- fl1h->hw_info.fpga_version[2] = sic->fpgaVersion.build;
-
- LOGP(DL1C, LOGL_INFO, "DSP v%u.%u.%u, FPGA v%u.%u.%u\n",
- sic->dspVersion.major, sic->dspVersion.minor,
- sic->dspVersion.build, sic->fpgaVersion.major,
- sic->fpgaVersion.minor, sic->fpgaVersion.build);
-
- if (!(fl1h->hw_info.band_support & trx->bts->band))
- LOGP(DL1C, LOGL_FATAL, "BTS band %s not supported by hw\n",
- gsm_band_name(trx->bts->band));
-
- /* Request the activation */
- l1if_activate_rf(fl1h, 1);
-
- /* load calibration tables */
- rc = calib_load(fl1h);
- if (rc < 0)
- LOGP(DL1C, LOGL_ERROR, "Operating without calibration; "
- "unable to load tables!\n");
-
- msgb_free(resp);
- return 0;
-}
-
-/* request DSP+FPGA code versions */
-static int l1if_get_info(struct lc15l1_hdl *hdl)
-{
- struct msgb *msg = sysp_msgb_alloc();
- Litecell15_Prim_t *sysp = msgb_sysprim(msg);
-
- sysp->id = Litecell15_PrimId_SystemInfoReq;
-
- return l1if_req_compl(hdl, msg, info_compl_cb, NULL);
-}
-
-static int reset_compl_cb(struct gsm_bts_trx *trx, struct msgb *resp,
- void *data)
-{
- struct lc15l1_hdl *fl1h = trx_lc15l1_hdl(trx);
- Litecell15_Prim_t *sysp = msgb_sysprim(resp);
- GsmL1_Status_t status = sysp->u.layer1ResetCnf.status;
-
- LOGP(DL1C, LOGL_NOTICE, "Rx L1-RESET.conf (status=%s)\n",
- get_value_string(lc15bts_l1status_names, status));
-
- msgb_free(resp);
-
- /* If we're coming out of reset .. */
- if (status != GsmL1_Status_Success) {
- LOGP(DL1C, LOGL_FATAL, "L1-RESET.conf with status %s\n",
- get_value_string(lc15bts_l1status_names, status));
- bts_shutdown(trx->bts, "L1-RESET failure");
- }
-
- /* as we cannot get the current DSP trace flags, we simply
- * set them to zero (or whatever dsp_trace_f has been initialized to */
- l1if_set_trace_flags(fl1h, fl1h->dsp_trace_f);
-
- /* obtain version information on DSP/FPGA and band capabilities */
- l1if_get_info(fl1h);
-
- return 0;
-}
-
-int l1if_reset(struct lc15l1_hdl *hdl)
-{
- struct msgb *msg = sysp_msgb_alloc();
- Litecell15_Prim_t *sysp = msgb_sysprim(msg);
- sysp->id = Litecell15_PrimId_Layer1ResetReq;
-
- return l1if_req_compl(hdl, msg, reset_compl_cb, NULL);
-}
-
-/* set the trace flags within the DSP */
-int l1if_set_trace_flags(struct lc15l1_hdl *hdl, uint32_t flags)
-{
- struct msgb *msg = sysp_msgb_alloc();
- Litecell15_Prim_t *sysp = msgb_sysprim(msg);
-
- LOGP(DL1C, LOGL_INFO, "Tx SET-TRACE-FLAGS.req (0x%08x)\n",
- flags);
-
- sysp->id = Litecell15_PrimId_SetTraceFlagsReq;
- sysp->u.setTraceFlagsReq.u32Tf = flags;
-
- hdl->dsp_trace_f = flags;
-
- /* There is no confirmation we could wait for */
- if (osmo_wqueue_enqueue(&hdl->write_q[MQ_SYS_WRITE], msg) != 0) {
- LOGP(DL1C, LOGL_ERROR, "MQ_SYS_WRITE queue full. Dropping msg\n");
- msgb_free(msg);
- return -EAGAIN;
- }
- return 0;
-}
-
-static int get_hwinfo(struct lc15l1_hdl *fl1h)
-{
- int rc;
-
- rc = lc15bts_rev_get();
- if (rc < 0) {
- LOGP(DL1C, LOGL_ERROR, "Failed to obtain LC15BTS revision: %d\n", rc);
- return rc;
- }
- fl1h->hw_info.ver_major = rc;
-
- rc = lc15bts_model_get();
- if (rc < 0) {
- LOGP(DL1C, LOGL_ERROR, "Failed to obtain LC15BTS model: %d\n", rc);
- return rc;
- }
- fl1h->hw_info.ver_minor = rc;
-
- rc = lc15bts_option_get(LC15BTS_OPTION_BAND);
- if (rc < 0) {
- LOGP(DL1C, LOGL_ERROR, "Failed to obtain LC15BTS_OPTION_BAND: %d\n", rc);
- return rc;
- }
-
- switch (rc) {
- case LC15BTS_BAND_850:
- fl1h->hw_info.band_support = GSM_BAND_850;
- break;
- case LC15BTS_BAND_900:
- fl1h->hw_info.band_support = GSM_BAND_900;
- break;
- case LC15BTS_BAND_1800:
- fl1h->hw_info.band_support = GSM_BAND_1800;
- break;
- case LC15BTS_BAND_1900:
- fl1h->hw_info.band_support = GSM_BAND_1900;
- break;
- default:
- LOGP(DL1C, LOGL_ERROR, "Unexpected LC15BTS_BAND value: %d\n", rc);
- return -1;
- }
-
- LOGP(DL1C, LOGL_INFO, "BTS hw support band %s\n", gsm_band_name(fl1h->hw_info.band_support));
-
- return 0;
-}
-
-struct lc15l1_hdl *l1if_open(struct phy_instance *pinst)
-{
- struct lc15l1_hdl *fl1h;
- int rc;
-
- LOGP(DL1C, LOGL_INFO, "Litecell 1.5 BTS L1IF compiled against API headers "
- "v%u.%u.%u\n", LITECELL15_API_VERSION >> 16,
- (LITECELL15_API_VERSION >> 8) & 0xff,
- LITECELL15_API_VERSION & 0xff);
-
- fl1h = talloc_zero(pinst, struct lc15l1_hdl);
- if (!fl1h)
- return NULL;
- INIT_LLIST_HEAD(&fl1h->wlc_list);
-
- fl1h->phy_inst = pinst;
- fl1h->dsp_trace_f = pinst->u.lc15.dsp_trace_f;
-
- get_hwinfo(fl1h);
-
- rc = l1if_transport_open(MQ_SYS_WRITE, fl1h);
- if (rc < 0) {
- talloc_free(fl1h);
- return NULL;
- }
-
- rc = l1if_transport_open(MQ_L1_WRITE, fl1h);
- if (rc < 0) {
- l1if_transport_close(MQ_SYS_WRITE, fl1h);
- talloc_free(fl1h);
- return NULL;
- }
-
- return fl1h;
-}
-
-int l1if_close(struct lc15l1_hdl *fl1h)
-{
- l1if_transport_close(MQ_L1_WRITE, fl1h);
- l1if_transport_close(MQ_SYS_WRITE, fl1h);
- return 0;
-}
-
-#if LITECELL15_API_VERSION >= LITECELL15_API(2,1,7)
-static int dsp_alive_compl_cb(struct gsm_bts_trx *trx, struct msgb *resp, void *data)
-{
- Litecell15_Prim_t *sysp = msgb_sysprim(resp);
- Litecell15_IsAliveCnf_t *sac = &sysp->u.isAliveCnf;
- struct lc15l1_hdl *fl1h = trx_lc15l1_hdl(trx);
-
- fl1h->hw_alive.dsp_alive_cnt++;
- LOGP(DL1C, LOGL_DEBUG, "Rx SYS prim %s, status=%d (%d)\n",
- get_value_string(lc15bts_sysprim_names, sysp->id), sac->status, trx->nr);
-
- msgb_free(resp);
- return 0;
-}
-
-static void dsp_alive_timer_cb(void *data)
-{
- struct lc15l1_hdl *fl1h = data;
- struct gsm_bts_trx *trx = fl1h->phy_inst->trx;
- struct msgb *msg = sysp_msgb_alloc();
- int rc;
-
- Litecell15_Prim_t *sys_prim = msgb_sysprim(msg);
- sys_prim->id = Litecell15_PrimId_IsAliveReq;
-
- if (fl1h->hw_alive.dsp_alive_cnt == 0) {
- LOGP(DL1C, LOGL_ERROR, "Timeout waiting for SYS prim %s primitive (%d)\n",
- get_value_string(lc15bts_sysprim_names, sys_prim->id + 1), trx->nr);
-
- if( fl1h->phy_inst->trx ){
- fl1h->phy_inst->trx->mo.obj_inst.trx_nr = fl1h->phy_inst->trx->nr;
- }
- }
-
- LOGP(DL1C, LOGL_DEBUG, "Tx SYS prim %s (%d)\n",
- get_value_string(lc15bts_sysprim_names, sys_prim->id), trx->nr);
-
- rc = l1if_req_compl(fl1h, msg, dsp_alive_compl_cb, NULL);
- if (rc < 0) {
- LOGP(DL1C, LOGL_FATAL, "Failed to send %s primitive\n", get_value_string(lc15bts_sysprim_names, sys_prim->id));
- return;
- }
-
- /* restart timer */
- fl1h->hw_alive.dsp_alive_cnt = 0;
- osmo_timer_schedule(&fl1h->hw_alive.dsp_alive_timer, fl1h->hw_alive.dsp_alive_period, 0);
-
- return;
-}
-#endif
-
-int bts_model_phy_link_open(struct phy_link *plink)
-{
- struct phy_instance *pinst = phy_instance_by_num(plink, 0);
-
- OSMO_ASSERT(pinst);
-
- if (!pinst->trx) {
- LOGP(DL1C, LOGL_NOTICE, "Ignoring phy link %d instance %d "
- "because no TRX is associated with it\n", plink->num, pinst->num);
- return 0;
- }
- phy_link_state_set(plink, PHY_LINK_CONNECTING);
-
- pinst->u.lc15.hdl = l1if_open(pinst);
- if (!pinst->u.lc15.hdl) {
- LOGP(DL1C, LOGL_FATAL, "Cannot open L1 interface\n");
- return -EIO;
- }
-
- /* Set default PHY parameters */
- if (!pinst->u.lc15.max_cell_size)
- pinst->u.lc15.max_cell_size = LC15_BTS_MAX_CELL_SIZE_DEFAULT;
-
- if (!pinst->u.lc15.diversity_mode)
- pinst->u.lc15.diversity_mode = LC15_BTS_DIVERSITY_MODE_DEFAULT;
-
- if (!pinst->u.lc15.pedestal_mode)
- pinst->u.lc15.pedestal_mode = LC15_BTS_PEDESTAL_MODE_DEFAULT;
-
-#if LITECELL15_API_VERSION >= LITECELL15_API(2,1,7)
- if (!pinst->u.lc15.dsp_alive_period)
- pinst->u.lc15.dsp_alive_period = LC15_BTS_DSP_ALIVE_TMR_DEFAULT;
-
- if (!pinst->u.lc15.tx_pwr_adj_mode)
- pinst->u.lc15.tx_pwr_adj_mode = LC15_BTS_TX_PWR_ADJ_DEFAULT;
-
- if (!pinst->u.lc15.tx_pwr_red_8psk)
- pinst->u.lc15.tx_pwr_red_8psk = LC15_BTS_TX_RED_PWR_8PSK_DEFAULT;
-
- if (!pinst->u.lc15.tx_c0_idle_pwr_red)
- pinst->u.lc15.tx_c0_idle_pwr_red = LC15_BTS_TX_C0_IDLE_RED_PWR_DEFAULT;
-#endif
-
- struct lc15l1_hdl *fl1h = pinst->u.lc15.hdl;
- fl1h->dsp_trace_f = dsp_trace;
-
- l1if_reset(pinst->u.lc15.hdl);
-
- phy_link_state_set(plink, PHY_LINK_CONNECTED);
-
-#if LITECELL15_API_VERSION >= LITECELL15_API(2,1,7)
- /* Send first IS_ALIVE primitive */
- struct msgb *msg = sysp_msgb_alloc();
- int rc;
-
- Litecell15_Prim_t *sys_prim = msgb_sysprim(msg);
- sys_prim->id = Litecell15_PrimId_IsAliveReq;
-
- rc = l1if_req_compl(fl1h, msg, dsp_alive_compl_cb, NULL);
- if (rc < 0) {
- LOGP(DL1C, LOGL_FATAL, "Failed to send %s primitive\n", get_value_string(lc15bts_sysprim_names, sys_prim->id));
- return -EIO;
- }
-
- /* initialize DSP heart beat alive timer */
- osmo_timer_setup(&fl1h->hw_alive.dsp_alive_timer, dsp_alive_timer_cb, fl1h);
- fl1h->hw_alive.dsp_alive_cnt = 0;
- fl1h->hw_alive.dsp_alive_period = pinst->u.lc15.dsp_alive_period;
- osmo_timer_schedule(&fl1h->hw_alive.dsp_alive_timer, fl1h->hw_alive.dsp_alive_period, 0);
-#endif
-
- return 0;
-}
diff --git a/src/osmo-bts-litecell15/l1_if.h b/src/osmo-bts-litecell15/l1_if.h
deleted file mode 100644
index 655e63fb..00000000
--- a/src/osmo-bts-litecell15/l1_if.h
+++ /dev/null
@@ -1,149 +0,0 @@
-#ifndef _L1_IF_H
-#define _L1_IF_H
-
-#include <osmocom/core/select.h>
-#include <osmocom/core/write_queue.h>
-#include <osmocom/core/gsmtap_util.h>
-#include <osmocom/core/timer.h>
-#include <osmocom/gsm/gsm_utils.h>
-
-#include <osmo-bts/phy_link.h>
-
-#include <nrw/litecell15/gsml1prim.h>
-#include <nrw/litecell15/gsml1types.h>
-
-#include <stdbool.h>
-
-enum {
- MQ_SYS_READ,
- MQ_L1_READ,
- MQ_TCH_READ,
- MQ_PDTCH_READ,
- _NUM_MQ_READ
-};
-
-enum {
- MQ_SYS_WRITE,
- MQ_L1_WRITE,
- MQ_TCH_WRITE,
- MQ_PDTCH_WRITE,
- _NUM_MQ_WRITE
-};
-
-/* gsm_bts->model_priv, specific to Litecell 1.5 BTS */
-struct bts_lc15_priv {
- uint8_t led_ctrl_mode; /* 0: control by BTS, 1: not control by BTS */
- unsigned int rtp_drift_thres_ms; /* RTP timestamp drift detection threshold */
-};
-
-struct calib_send_state {
- FILE *fp;
- const char *path;
- int last_file_idx;
-};
-
-struct lc15l1_hdl {
- struct gsm_time gsm_time;
- HANDLE hLayer1; /* handle to the L1 instance in the DSP */
- uint32_t dsp_trace_f; /* currently operational DSP trace flags */
- struct llist_head wlc_list;
-
- struct phy_instance *phy_inst;
-
- struct osmo_timer_list alive_timer;
- unsigned int alive_prim_cnt;
-
- struct osmo_fd read_ofd[_NUM_MQ_READ]; /* osmo file descriptors */
- struct osmo_wqueue write_q[_NUM_MQ_WRITE];
-
- struct {
- /* from DSP/FPGA after L1 Init */
- uint8_t dsp_version[3];
- uint8_t fpga_version[3];
- uint32_t band_support;
- uint8_t ver_major;
- uint8_t ver_minor;
- } hw_info;
-
- struct calib_send_state st;
-
- uint8_t last_rf_mute[8];
-
-#if LITECELL15_API_VERSION >= LITECELL15_API(2,1,7)
- struct {
- struct osmo_timer_list dsp_alive_timer;
- unsigned int dsp_alive_cnt;
- uint8_t dsp_alive_period;
- } hw_alive;
-#endif
-
-};
-
-#define msgb_l1prim(msg) ((GsmL1_Prim_t *)(msg)->l1h)
-#define msgb_sysprim(msg) ((Litecell15_Prim_t *)(msg)->l1h)
-
-typedef int l1if_compl_cb(struct gsm_bts_trx *trx, struct msgb *l1_msg, void *data);
-
-/* send a request primitive to the L1 and schedule completion call-back */
-int l1if_req_compl(struct lc15l1_hdl *fl1h, struct msgb *msg,
- l1if_compl_cb *cb, void *cb_data);
-int l1if_gsm_req_compl(struct lc15l1_hdl *fl1h, struct msgb *msg,
- l1if_compl_cb *cb, void *cb_data);
-
-struct lc15l1_hdl *l1if_open(struct phy_instance *pinst);
-int l1if_close(struct lc15l1_hdl *hdl);
-int l1if_reset(struct lc15l1_hdl *hdl);
-int l1if_activate_rf(struct lc15l1_hdl *hdl, int on);
-int l1if_set_trace_flags(struct lc15l1_hdl *hdl, uint32_t flags);
-int l1if_set_txpower(struct lc15l1_hdl *fl1h, float tx_power);
-int l1if_mute_rf(struct lc15l1_hdl *hdl, uint8_t mute[8], l1if_compl_cb *cb);
-
-struct msgb *l1p_msgb_alloc(void);
-struct msgb *sysp_msgb_alloc(void);
-
-uint32_t l1if_lchan_to_hLayer(struct gsm_lchan *lchan);
-struct gsm_lchan *l1if_hLayer_to_lchan(struct gsm_bts_trx *trx, uint32_t hLayer);
-
-/* tch.c */
-int l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len,
- const uint8_t *rtp_pl, unsigned int rtp_pl_len, uint32_t fn,
- bool use_cache, bool marker);
-int l1if_tch_rx(struct gsm_bts_trx *trx, uint8_t chan_nr, struct msgb *l1p_msg);
-int l1if_tch_fill(struct gsm_lchan *lchan, uint8_t *l1_buffer);
-struct msgb *gen_empty_tch_msg(struct gsm_lchan *lchan, uint32_t fn);
-
-/* ciphering */
-int l1if_set_ciphering(struct lc15l1_hdl *fl1h,
- struct gsm_lchan *lchan,
- int dir_downlink);
-
-/* channel control */
-int l1if_rsl_chan_act(struct gsm_lchan *lchan);
-int l1if_rsl_chan_rel(struct gsm_lchan *lchan);
-int l1if_rsl_chan_mod(struct gsm_lchan *lchan);
-int l1if_rsl_deact_sacch(struct gsm_lchan *lchan);
-int l1if_rsl_mode_modify(struct gsm_lchan *lchan);
-
-/* calibration loading */
-int calib_load(struct lc15l1_hdl *fl1h);
-
-/* public helpers for test */
-int bts_check_for_ciph_cmd(struct lc15l1_hdl *fl1h,
- struct msgb *msg, struct gsm_lchan *lchan);
-int l1if_ms_pwr_ctrl(struct gsm_lchan *lchan, const int uplink_target,
- const uint8_t ms_power, const float rxLevel);
-
-static inline struct lc15l1_hdl *trx_lc15l1_hdl(const struct gsm_bts_trx *trx)
-{
- const struct phy_instance *pinst = trx_phy_instance(trx);
- OSMO_ASSERT(pinst);
- return pinst->u.lc15.hdl;
-}
-
-static inline struct gsm_bts_trx *lc15l1_hdl_trx(const struct lc15l1_hdl *fl1h)
-{
- OSMO_ASSERT(fl1h->phy_inst);
- return fl1h->phy_inst->trx;
-}
-
-#endif /* _L1_IF_H */
diff --git a/src/osmo-bts-litecell15/l1_transp.h b/src/osmo-bts-litecell15/l1_transp.h
deleted file mode 100644
index 7d6772e8..00000000
--- a/src/osmo-bts-litecell15/l1_transp.h
+++ /dev/null
@@ -1,14 +0,0 @@
-#ifndef _L1_TRANSP_H
-#define _L1_TRANSP_H
-
-#include <osmocom/core/msgb.h>
-
-/* functions a transport calls on arrival of primitive from BTS */
-int l1if_handle_l1prim(int wq, struct lc15l1_hdl *fl1h, struct msgb *msg);
-int l1if_handle_sysprim(struct lc15l1_hdl *fl1h, struct msgb *msg);
-
-/* functions exported by a transport */
-int l1if_transport_open(int q, struct lc15l1_hdl *fl1h);
-int l1if_transport_close(int q, struct lc15l1_hdl *fl1h);
-
-#endif /* _L1_TRANSP_H */
diff --git a/src/osmo-bts-litecell15/l1_transp_hw.c b/src/osmo-bts-litecell15/l1_transp_hw.c
deleted file mode 100644
index ffe8613e..00000000
--- a/src/osmo-bts-litecell15/l1_transp_hw.c
+++ /dev/null
@@ -1,318 +0,0 @@
-/* Interface handler for Nuran Wireless Litecell 1.5 L1 (real hardware) */
-
-/* Copyright (C) 2015 by Yves Godin <support@nuranwireless.com>
- *
- * Based on sysmoBTS:
- * (C) 2011 by Harald Welte <laforge@gnumonks.org>
- *
- * 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 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/licenses/>.
- *
- */
-
-#include <assert.h>
-#include <stdint.h>
-#include <unistd.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <limits.h>
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/uio.h>
-
-#include <osmocom/core/talloc.h>
-#include <osmocom/core/utils.h>
-#include <osmocom/core/select.h>
-#include <osmocom/core/write_queue.h>
-#include <osmocom/gsm/gsm_utils.h>
-
-#include <osmo-bts/logging.h>
-#include <osmo-bts/gsm_data.h>
-
-#include <nrw/litecell15/litecell15.h>
-#include <nrw/litecell15/gsml1prim.h>
-#include <nrw/litecell15/gsml1const.h>
-#include <nrw/litecell15/gsml1types.h>
-
-#include "lc15bts.h"
-#include "l1_if.h"
-#include "l1_transp.h"
-
-
-#define DEV_SYS_DSP2ARM_NAME "/dev/msgq/litecell15_dsp2arm_trx"
-#define DEV_SYS_ARM2DSP_NAME "/dev/msgq/litecell15_arm2dsp_trx"
-#define DEV_L1_DSP2ARM_NAME "/dev/msgq/gsml1_sig_dsp2arm_trx"
-#define DEV_L1_ARM2DSP_NAME "/dev/msgq/gsml1_sig_arm2dsp_trx"
-
-#define DEV_TCH_DSP2ARM_NAME "/dev/msgq/gsml1_tch_dsp2arm_trx"
-#define DEV_TCH_ARM2DSP_NAME "/dev/msgq/gsml1_tch_arm2dsp_trx"
-#define DEV_PDTCH_DSP2ARM_NAME "/dev/msgq/gsml1_pdtch_dsp2arm_trx"
-#define DEV_PDTCH_ARM2DSP_NAME "/dev/msgq/gsml1_pdtch_arm2dsp_trx"
-
-static const char *rd_devnames[] = {
- [MQ_SYS_READ] = DEV_SYS_DSP2ARM_NAME,
- [MQ_L1_READ] = DEV_L1_DSP2ARM_NAME,
- [MQ_TCH_READ] = DEV_TCH_DSP2ARM_NAME,
- [MQ_PDTCH_READ] = DEV_PDTCH_DSP2ARM_NAME,
-};
-
-static const char *wr_devnames[] = {
- [MQ_SYS_WRITE] = DEV_SYS_ARM2DSP_NAME,
- [MQ_L1_WRITE] = DEV_L1_ARM2DSP_NAME,
- [MQ_TCH_WRITE] = DEV_TCH_ARM2DSP_NAME,
- [MQ_PDTCH_WRITE]= DEV_PDTCH_ARM2DSP_NAME,
-};
-
-/*
- * Make sure that all structs we read fit into the LC15BTS_PRIM_SIZE
- */
-osmo_static_assert(sizeof(GsmL1_Prim_t) + 128 <= LC15BTS_PRIM_SIZE, l1_prim)
-osmo_static_assert(sizeof(Litecell15_Prim_t) + 128 <= LC15BTS_PRIM_SIZE, super_prim)
-
-static int wqueue_vector_cb(struct osmo_fd *fd, unsigned int what)
-{
- struct osmo_wqueue *queue;
-
- queue = container_of(fd, struct osmo_wqueue, bfd);
-
- if (what & OSMO_FD_READ)
- queue->read_cb(fd);
-
- if (what & OSMO_FD_EXCEPT)
- queue->except_cb(fd);
-
- if (what & OSMO_FD_WRITE) {
- struct iovec iov[5];
- struct msgb *msg, *tmp;
- int written, count = 0;
-
- fd->when &= ~OSMO_FD_WRITE;
-
- llist_for_each_entry(msg, &queue->msg_queue, list) {
- /* more writes than we have */
- if (count >= ARRAY_SIZE(iov))
- break;
-
- iov[count].iov_base = msg->l1h;
- iov[count].iov_len = msgb_l1len(msg);
- count += 1;
- }
-
- /* TODO: check if all lengths are the same. */
-
-
- /* Nothing scheduled? This should not happen. */
- if (count == 0) {
- if (!llist_empty(&queue->msg_queue))
- fd->when |= OSMO_FD_WRITE;
- return 0;
- }
-
- written = writev(fd->fd, iov, count);
- if (written < 0) {
- /* nothing written?! */
- if (!llist_empty(&queue->msg_queue))
- fd->when |= OSMO_FD_WRITE;
- return 0;
- }
-
- /* now delete the written entries */
- written = written / iov[0].iov_len;
- count = 0;
- llist_for_each_entry_safe(msg, tmp, &queue->msg_queue, list) {
- queue->current_length -= 1;
-
- llist_del(&msg->list);
- msgb_free(msg);
-
- count += 1;
- if (count >= written)
- break;
- }
-
- if (!llist_empty(&queue->msg_queue))
- fd->when |= OSMO_FD_WRITE;
- }
-
- return 0;
-}
-
-static int prim_size_for_queue(int queue)
-{
- switch (queue) {
- case MQ_SYS_WRITE:
- return sizeof(Litecell15_Prim_t);
- case MQ_L1_WRITE:
- case MQ_TCH_WRITE:
- case MQ_PDTCH_WRITE:
- return sizeof(GsmL1_Prim_t);
- default:
- /* The compiler can't know that priv_nr is an enum. Assist. */
- LOGP(DL1C, LOGL_FATAL, "writing on a wrong queue: %d\n",
- queue);
- assert(false);
- break;
- }
-}
-
-/* callback when there's something to read from the l1 msg_queue */
-static int read_dispatch_one(struct lc15l1_hdl *fl1h, struct msgb *msg, int queue)
-{
- switch (queue) {
- case MQ_SYS_WRITE:
- return l1if_handle_sysprim(fl1h, msg);
- case MQ_L1_WRITE:
- case MQ_TCH_WRITE:
- case MQ_PDTCH_WRITE:
- return l1if_handle_l1prim(queue, fl1h, msg);
- default:
- /* The compiler can't know that priv_nr is an enum. Assist. */
- LOGP(DL1C, LOGL_FATAL, "writing on a wrong queue: %d\n",
- queue);
- assert(false);
- break;
- }
-};
-
-static int l1if_fd_cb(struct osmo_fd *ofd, unsigned int what)
-{
- int i, rc;
-
- const uint32_t prim_size = prim_size_for_queue(ofd->priv_nr);
- uint32_t count;
-
- struct iovec iov[3];
- struct msgb *msg[ARRAY_SIZE(iov)];
-
- for (i = 0; i < ARRAY_SIZE(iov); ++i) {
- msg[i] = msgb_alloc_headroom(prim_size + 128, 128, "1l_fd");
- msg[i]->l1h = msg[i]->data;
-
- iov[i].iov_base = msg[i]->l1h;
- iov[i].iov_len = msgb_tailroom(msg[i]);
- }
-
- rc = readv(ofd->fd, iov, ARRAY_SIZE(iov));
- if (rc < 0) {
- LOGP(DL1C, LOGL_ERROR, "failed to read from fd: %s\n", strerror(errno));
- /* N. B: we do not abort to let the cycle below cleanup allocated memory properly,
- the return value is ignored by the caller anyway.
- TODO: use libexplain's explain_readv() to provide detailed error description */
- count = 0;
- } else
- count = rc / prim_size;
-
- for (i = 0; i < count; ++i) {
- msgb_put(msg[i], prim_size);
- read_dispatch_one(ofd->data, msg[i], ofd->priv_nr);
- }
-
- for (i = count; i < ARRAY_SIZE(iov); ++i)
- msgb_free(msg[i]);
-
- return 1;
-}
-
-/* callback when we can write to one of the l1 msg_queue devices */
-static int l1fd_write_cb(struct osmo_fd *ofd, struct msgb *msg)
-{
- int rc;
-
- rc = write(ofd->fd, msg->l1h, msgb_l1len(msg));
- if (rc < 0) {
- LOGP(DL1C, LOGL_ERROR, "error writing to L1 msg_queue: %s\n",
- strerror(errno));
- return rc;
- } else if (rc < msg->len) {
- LOGP(DL1C, LOGL_ERROR, "short write to L1 msg_queue: "
- "%u < %u\n", rc, msg->len);
- return -EIO;
- }
-
- return 0;
-}
-
-int l1if_transport_open(int q, struct lc15l1_hdl *hdl)
-{
- struct phy_link *plink = hdl->phy_inst->phy_link;
- int rc;
- char buf[PATH_MAX];
-
- /* Step 1: Open all msg_queue file descriptors */
- struct osmo_fd *read_ofd = &hdl->read_ofd[q];
- struct osmo_wqueue *wq = &hdl->write_q[q];
- struct osmo_fd *write_ofd = &hdl->write_q[q].bfd;
-
- snprintf(buf, sizeof(buf)-1, "%s%d", rd_devnames[q], plink->num);
- buf[sizeof(buf)-1] = '\0';
-
- rc = open(buf, O_RDONLY);
- if (rc < 0) {
- LOGP(DL1C, LOGL_FATAL, "unable to open msg_queue %s: %s\n",
- buf, strerror(errno));
- return rc;
- }
- osmo_fd_setup(read_ofd, rc, OSMO_FD_READ, l1if_fd_cb, hdl, q);
- rc = osmo_fd_register(read_ofd);
- if (rc < 0) {
- close(read_ofd->fd);
- read_ofd->fd = -1;
- return rc;
- }
-
- snprintf(buf, sizeof(buf)-1, "%s%d", wr_devnames[q], plink->num);
- buf[sizeof(buf)-1] = '\0';
-
- rc = open(buf, O_WRONLY);
- if (rc < 0) {
- LOGP(DL1C, LOGL_FATAL, "unable to open msg_queue %s: %s\n",
- buf, strerror(errno));
- goto out_read;
- }
- osmo_wqueue_init(wq, 10);
- wq->write_cb = l1fd_write_cb;
- osmo_fd_setup(write_ofd, rc, OSMO_FD_WRITE, wqueue_vector_cb, hdl, q);
- rc = osmo_fd_register(write_ofd);
- if (rc < 0) {
- close(write_ofd->fd);
- write_ofd->fd = -1;
- goto out_read;
- }
-
- return 0;
-
-out_read:
- close(hdl->read_ofd[q].fd);
- osmo_fd_unregister(&hdl->read_ofd[q]);
-
- return rc;
-}
-
-int l1if_transport_close(int q, struct lc15l1_hdl *hdl)
-{
- struct osmo_fd *read_ofd = &hdl->read_ofd[q];
- struct osmo_fd *write_ofd = &hdl->write_q[q].bfd;
-
- osmo_fd_unregister(read_ofd);
- close(read_ofd->fd);
- read_ofd->fd = -1;
-
- osmo_fd_unregister(write_ofd);
- close(write_ofd->fd);
- write_ofd->fd = -1;
-
- return 0;
-}
diff --git a/src/osmo-bts-litecell15/lc15bts.c b/src/osmo-bts-litecell15/lc15bts.c
deleted file mode 100644
index 0ba89a11..00000000
--- a/src/osmo-bts-litecell15/lc15bts.c
+++ /dev/null
@@ -1,353 +0,0 @@
-/* NuRAN Wireless Litecell 1.5 L1 API related definitions */
-
-/* Copyright (C) 2015 by Yves Godin <support@nuranwireless.com>
- * based on:
- * sysmobts.c
- * (C) 2011 by Harald Welte <laforge@gnumonks.org>
- *
- * 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 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/licenses/>.
- *
- */
-
-#include <nrw/litecell15/litecell15.h>
-#include <nrw/litecell15/gsml1const.h>
-#include <nrw/litecell15/gsml1dbg.h>
-
-#include "lc15bts.h"
-
-enum l1prim_type lc15bts_get_l1prim_type(GsmL1_PrimId_t id)
-{
- switch (id) {
- case GsmL1_PrimId_MphInitReq: return L1P_T_REQ;
- case GsmL1_PrimId_MphCloseReq: return L1P_T_REQ;
- case GsmL1_PrimId_MphConnectReq: return L1P_T_REQ;
- case GsmL1_PrimId_MphDisconnectReq: return L1P_T_REQ;
- case GsmL1_PrimId_MphActivateReq: return L1P_T_REQ;
- case GsmL1_PrimId_MphDeactivateReq: return L1P_T_REQ;
- case GsmL1_PrimId_MphConfigReq: return L1P_T_REQ;
- case GsmL1_PrimId_MphMeasureReq: return L1P_T_REQ;
- case GsmL1_PrimId_MphInitCnf: return L1P_T_CONF;
- case GsmL1_PrimId_MphCloseCnf: return L1P_T_CONF;
- case GsmL1_PrimId_MphConnectCnf: return L1P_T_CONF;
- case GsmL1_PrimId_MphDisconnectCnf: return L1P_T_CONF;
- case GsmL1_PrimId_MphActivateCnf: return L1P_T_CONF;
- case GsmL1_PrimId_MphDeactivateCnf: return L1P_T_CONF;
- case GsmL1_PrimId_MphConfigCnf: return L1P_T_CONF;
- case GsmL1_PrimId_MphMeasureCnf: return L1P_T_CONF;
- case GsmL1_PrimId_PhEmptyFrameReq: return L1P_T_REQ;
- case GsmL1_PrimId_PhDataReq: return L1P_T_REQ;
- case GsmL1_PrimId_MphTimeInd: return L1P_T_IND;
- case GsmL1_PrimId_MphSyncInd: return L1P_T_IND;
- case GsmL1_PrimId_PhConnectInd: return L1P_T_IND;
- case GsmL1_PrimId_PhReadyToSendInd: return L1P_T_IND;
- case GsmL1_PrimId_PhDataInd: return L1P_T_IND;
- case GsmL1_PrimId_PhRaInd: return L1P_T_IND;
- default: return L1P_T_INVALID;
- }
-}
-
-const struct value_string lc15bts_l1prim_names[GsmL1_PrimId_NUM+1] = {
- { GsmL1_PrimId_MphInitReq, "MPH-INIT.req" },
- { GsmL1_PrimId_MphCloseReq, "MPH-CLOSE.req" },
- { GsmL1_PrimId_MphConnectReq, "MPH-CONNECT.req" },
- { GsmL1_PrimId_MphDisconnectReq,"MPH-DISCONNECT.req" },
- { GsmL1_PrimId_MphActivateReq, "MPH-ACTIVATE.req" },
- { GsmL1_PrimId_MphDeactivateReq,"MPH-DEACTIVATE.req" },
- { GsmL1_PrimId_MphConfigReq, "MPH-CONFIG.req" },
- { GsmL1_PrimId_MphMeasureReq, "MPH-MEASURE.req" },
- { GsmL1_PrimId_MphInitCnf, "MPH-INIT.conf" },
- { GsmL1_PrimId_MphCloseCnf, "MPH-CLOSE.conf" },
- { GsmL1_PrimId_MphConnectCnf, "MPH-CONNECT.conf" },
- { GsmL1_PrimId_MphDisconnectCnf,"MPH-DISCONNECT.conf" },
- { GsmL1_PrimId_MphActivateCnf, "MPH-ACTIVATE.conf" },
- { GsmL1_PrimId_MphDeactivateCnf,"MPH-DEACTIVATE.conf" },
- { GsmL1_PrimId_MphConfigCnf, "MPH-CONFIG.conf" },
- { GsmL1_PrimId_MphMeasureCnf, "MPH-MEASURE.conf" },
- { GsmL1_PrimId_MphTimeInd, "MPH-TIME.ind" },
- { GsmL1_PrimId_MphSyncInd, "MPH-SYNC.ind" },
- { GsmL1_PrimId_PhEmptyFrameReq, "PH-EMPTY_FRAME.req" },
- { GsmL1_PrimId_PhDataReq, "PH-DATA.req" },
- { GsmL1_PrimId_PhConnectInd, "PH-CONNECT.ind" },
- { GsmL1_PrimId_PhReadyToSendInd,"PH-READY_TO_SEND.ind" },
- { GsmL1_PrimId_PhDataInd, "PH-DATA.ind" },
- { GsmL1_PrimId_PhRaInd, "PH-RA.ind" },
- { 0, NULL }
-};
-
-GsmL1_PrimId_t lc15bts_get_l1prim_conf(GsmL1_PrimId_t id)
-{
- switch (id) {
- case GsmL1_PrimId_MphInitReq: return GsmL1_PrimId_MphInitCnf;
- case GsmL1_PrimId_MphCloseReq: return GsmL1_PrimId_MphCloseCnf;
- case GsmL1_PrimId_MphConnectReq: return GsmL1_PrimId_MphConnectCnf;
- case GsmL1_PrimId_MphDisconnectReq: return GsmL1_PrimId_MphDisconnectCnf;
- case GsmL1_PrimId_MphActivateReq: return GsmL1_PrimId_MphActivateCnf;
- case GsmL1_PrimId_MphDeactivateReq: return GsmL1_PrimId_MphDeactivateCnf;
- case GsmL1_PrimId_MphConfigReq: return GsmL1_PrimId_MphConfigCnf;
- case GsmL1_PrimId_MphMeasureReq: return GsmL1_PrimId_MphMeasureCnf;
- default: return -1; // Weak
- }
-}
-
-enum l1prim_type lc15bts_get_sysprim_type(Litecell15_PrimId_t id)
-{
- switch (id) {
- case Litecell15_PrimId_SystemInfoReq: return L1P_T_REQ;
- case Litecell15_PrimId_SystemInfoCnf: return L1P_T_CONF;
- case Litecell15_PrimId_SystemFailureInd: return L1P_T_IND;
- case Litecell15_PrimId_ActivateRfReq: return L1P_T_REQ;
- case Litecell15_PrimId_ActivateRfCnf: return L1P_T_CONF;
- case Litecell15_PrimId_DeactivateRfReq: return L1P_T_REQ;
- case Litecell15_PrimId_DeactivateRfCnf: return L1P_T_CONF;
- case Litecell15_PrimId_SetTraceFlagsReq: return L1P_T_REQ;
- case Litecell15_PrimId_Layer1ResetReq: return L1P_T_REQ;
- case Litecell15_PrimId_Layer1ResetCnf: return L1P_T_CONF;
- case Litecell15_PrimId_SetCalibTblReq: return L1P_T_REQ;
- case Litecell15_PrimId_SetCalibTblCnf: return L1P_T_CONF;
- case Litecell15_PrimId_MuteRfReq: return L1P_T_REQ;
- case Litecell15_PrimId_MuteRfCnf: return L1P_T_CONF;
- case Litecell15_PrimId_SetRxAttenReq: return L1P_T_REQ;
- case Litecell15_PrimId_SetRxAttenCnf: return L1P_T_CONF;
-#if LITECELL15_API_VERSION >= LITECELL15_API(2,1,7)
- case Litecell15_PrimId_IsAliveReq: return L1P_T_REQ;
- case Litecell15_PrimId_IsAliveCnf: return L1P_T_CONF;
- case Litecell15_PrimId_SetMaxCellSizeReq: return L1P_T_REQ;
- case Litecell15_PrimId_SetMaxCellSizeCnf: return L1P_T_CONF;
- case Litecell15_PrimId_SetC0IdleSlotPowerReductionReq: return L1P_T_REQ;
- case Litecell15_PrimId_SetC0IdleSlotPowerReductionCnf: return L1P_T_CONF;
-#endif
- default: return L1P_T_INVALID;
- }
-}
-
-const struct value_string lc15bts_sysprim_names[Litecell15_PrimId_NUM+1] = {
- { Litecell15_PrimId_SystemInfoReq, "SYSTEM-INFO.req" },
- { Litecell15_PrimId_SystemInfoCnf, "SYSTEM-INFO.conf" },
- { Litecell15_PrimId_SystemFailureInd, "SYSTEM-FAILURE.ind" },
- { Litecell15_PrimId_ActivateRfReq, "ACTIVATE-RF.req" },
- { Litecell15_PrimId_ActivateRfCnf, "ACTIVATE-RF.conf" },
- { Litecell15_PrimId_DeactivateRfReq, "DEACTIVATE-RF.req" },
- { Litecell15_PrimId_DeactivateRfCnf, "DEACTIVATE-RF.conf" },
- { Litecell15_PrimId_SetTraceFlagsReq, "SET-TRACE-FLAGS.req" },
- { Litecell15_PrimId_Layer1ResetReq, "LAYER1-RESET.req" },
- { Litecell15_PrimId_Layer1ResetCnf, "LAYER1-RESET.conf" },
- { Litecell15_PrimId_SetCalibTblReq, "SET-CALIB.req" },
- { Litecell15_PrimId_SetCalibTblCnf, "SET-CALIB.cnf" },
- { Litecell15_PrimId_MuteRfReq, "MUTE-RF.req" },
- { Litecell15_PrimId_MuteRfCnf, "MUTE-RF.cnf" },
- { Litecell15_PrimId_SetRxAttenReq, "SET-RX-ATTEN.req" },
- { Litecell15_PrimId_SetRxAttenCnf, "SET-RX-ATTEN-CNF.cnf" },
-#if LITECELL15_API_VERSION >= LITECELL15_API(2,1,7)
- { Litecell15_PrimId_IsAliveReq, "IS-ALIVE.req" },
- { Litecell15_PrimId_IsAliveCnf, "IS-ALIVE-CNF.cnf" },
- { Litecell15_PrimId_SetMaxCellSizeReq, "SET-MAX-CELL-SIZE.req" },
- { Litecell15_PrimId_SetMaxCellSizeCnf, "SET-MAX-CELL-SIZE.cnf" },
- { Litecell15_PrimId_SetC0IdleSlotPowerReductionReq, "SET-C0-IDLE-PWR-RED.req" },
- { Litecell15_PrimId_SetC0IdleSlotPowerReductionCnf, "SET-C0-IDLE-PWR-RED.cnf" },
-#endif
- { 0, NULL }
-};
-
-Litecell15_PrimId_t lc15bts_get_sysprim_conf(Litecell15_PrimId_t id)
-{
- switch (id) {
- case Litecell15_PrimId_SystemInfoReq: return Litecell15_PrimId_SystemInfoCnf;
- case Litecell15_PrimId_ActivateRfReq: return Litecell15_PrimId_ActivateRfCnf;
- case Litecell15_PrimId_DeactivateRfReq: return Litecell15_PrimId_DeactivateRfCnf;
- case Litecell15_PrimId_Layer1ResetReq: return Litecell15_PrimId_Layer1ResetCnf;
- case Litecell15_PrimId_SetCalibTblReq: return Litecell15_PrimId_SetCalibTblCnf;
- case Litecell15_PrimId_MuteRfReq: return Litecell15_PrimId_MuteRfCnf;
- case Litecell15_PrimId_SetRxAttenReq: return Litecell15_PrimId_SetRxAttenCnf;
-#if LITECELL15_API_VERSION >= LITECELL15_API(2,1,7)
- case Litecell15_PrimId_IsAliveReq: return Litecell15_PrimId_IsAliveCnf;
- case Litecell15_PrimId_SetMaxCellSizeReq: return Litecell15_PrimId_SetMaxCellSizeCnf;
- case Litecell15_PrimId_SetC0IdleSlotPowerReductionReq: return Litecell15_PrimId_SetC0IdleSlotPowerReductionCnf;
-#endif
- default: return -1; // Weak
- }
-}
-
-const struct value_string lc15bts_l1sapi_names[GsmL1_Sapi_NUM+1] = {
- { GsmL1_Sapi_Idle, "IDLE" },
- { GsmL1_Sapi_Fcch, "FCCH" },
- { GsmL1_Sapi_Sch, "SCH" },
- { GsmL1_Sapi_Sacch, "SACCH" },
- { GsmL1_Sapi_Sdcch, "SDCCH" },
- { GsmL1_Sapi_Bcch, "BCCH" },
- { GsmL1_Sapi_Pch, "PCH" },
- { GsmL1_Sapi_Agch, "AGCH" },
- { GsmL1_Sapi_Cbch, "CBCH" },
- { GsmL1_Sapi_Rach, "RACH" },
- { GsmL1_Sapi_TchF, "TCH/F" },
- { GsmL1_Sapi_FacchF, "FACCH/F" },
- { GsmL1_Sapi_TchH, "TCH/H" },
- { GsmL1_Sapi_FacchH, "FACCH/H" },
- { GsmL1_Sapi_Nch, "NCH" },
- { GsmL1_Sapi_Pdtch, "PDTCH" },
- { GsmL1_Sapi_Pacch, "PACCH" },
- { GsmL1_Sapi_Pbcch, "PBCCH" },
- { GsmL1_Sapi_Pagch, "PAGCH" },
- { GsmL1_Sapi_Ppch, "PPCH" },
- { GsmL1_Sapi_Pnch, "PNCH" },
- { GsmL1_Sapi_Ptcch, "PTCCH" },
- { GsmL1_Sapi_Prach, "PRACH" },
- { 0, NULL }
-};
-
-const struct value_string lc15bts_l1status_names[GSML1_STATUS_NUM+1] = {
- { GsmL1_Status_Success, "Success" },
- { GsmL1_Status_Generic, "Generic error" },
- { GsmL1_Status_NoMemory, "Not enough memory" },
- { GsmL1_Status_Timeout, "Timeout" },
- { GsmL1_Status_InvalidParam, "Invalid parameter" },
- { GsmL1_Status_Busy, "Resource busy" },
- { GsmL1_Status_NoRessource, "No more resources" },
- { GsmL1_Status_Uninitialized, "Trying to use uninitialized resource" },
- { GsmL1_Status_NullInterface, "Trying to call a NULL interface" },
- { GsmL1_Status_NullFctnPtr, "Trying to call a NULL function ptr" },
- { GsmL1_Status_BadCrc, "Bad CRC" },
- { GsmL1_Status_BadUsf, "Bad USF" },
- { GsmL1_Status_InvalidCPS, "Invalid CPS field" },
- { GsmL1_Status_UnexpectedBurst, "Unexpected burst" },
- { GsmL1_Status_UnavailCodec, "AMR codec is unavailable" },
- { GsmL1_Status_CriticalError, "Critical error" },
- { GsmL1_Status_OverheatError, "Overheat error" },
- { GsmL1_Status_DeviceError, "Device error" },
- { GsmL1_Status_FacchError, "FACCH / TCH order error" },
- { GsmL1_Status_AlreadyDeactivated, "Lchan already deactivated" },
- { GsmL1_Status_TxBurstFifoOvrn, "FIFO overrun" },
- { GsmL1_Status_TxBurstFifoUndr, "FIFO underrun" },
- { GsmL1_Status_NotSynchronized, "Not synchronized" },
- { GsmL1_Status_Unsupported, "Unsupported feature" },
- { GsmL1_Status_ClockError, "System clock error" },
- { 0, NULL }
-};
-
-const struct value_string lc15bts_tracef_names[29] = {
- { DBG_DEBUG, "DEBUG" },
- { DBG_L1WARNING, "L1_WARNING" },
- { DBG_ERROR, "ERROR" },
- { DBG_L1RXMSG, "L1_RX_MSG" },
- { DBG_L1RXMSGBYTE, "L1_RX_MSG_BYTE" },
- { DBG_L1TXMSG, "L1_TX_MSG" },
- { DBG_L1TXMSGBYTE, "L1_TX_MSG_BYTE" },
- { DBG_MPHCNF, "MPH_CNF" },
- { DBG_MPHIND, "MPH_IND" },
- { DBG_MPHREQ, "MPH_REQ" },
- { DBG_PHIND, "PH_IND" },
- { DBG_PHREQ, "PH_REQ" },
- { DBG_PHYRF, "PHY_RF" },
- { DBG_PHYRFMSGBYTE, "PHY_MSG_BYTE" },
- { DBG_MODE, "MODE" },
- { DBG_TDMAINFO, "TDMA_INFO" },
- { DBG_BADCRC, "BAD_CRC" },
- { DBG_PHINDBYTE, "PH_IND_BYTE" },
- { DBG_PHREQBYTE, "PH_REQ_BYTE" },
- { DBG_DEVICEMSG, "DEVICE_MSG" },
- { DBG_RACHINFO, "RACH_INFO" },
- { DBG_LOGCHINFO, "LOG_CH_INFO" },
- { DBG_MEMORY, "MEMORY" },
- { DBG_PROFILING, "PROFILING" },
- { DBG_TESTCOMMENT, "TEST_COMMENT" },
- { DBG_TEST, "TEST" },
- { DBG_STATUS, "STATUS" },
- { 0, NULL }
-};
-
-const struct value_string lc15bts_tracef_docs[29] = {
- { DBG_DEBUG, "Debug Region" },
- { DBG_L1WARNING, "L1 Warning Region" },
- { DBG_ERROR, "Error Region" },
- { DBG_L1RXMSG, "L1_RX_MSG Region" },
- { DBG_L1RXMSGBYTE, "L1_RX_MSG_BYTE Region" },
- { DBG_L1TXMSG, "L1_TX_MSG Region" },
- { DBG_L1TXMSGBYTE, "L1_TX_MSG_BYTE Region" },
- { DBG_MPHCNF, "MphConfirmation Region" },
- { DBG_MPHIND, "MphIndication Region" },
- { DBG_MPHREQ, "MphRequest Region" },
- { DBG_PHIND, "PhIndication Region" },
- { DBG_PHREQ, "PhRequest Region" },
- { DBG_PHYRF, "PhyRF Region" },
- { DBG_PHYRFMSGBYTE, "PhyRF Message Region" },
- { DBG_MODE, "Mode Region" },
- { DBG_TDMAINFO, "TDMA Info Region" },
- { DBG_BADCRC, "Bad CRC Region" },
- { DBG_PHINDBYTE, "PH_IND_BYTE" },
- { DBG_PHREQBYTE, "PH_REQ_BYTE" },
- { DBG_DEVICEMSG, "Device Message Region" },
- { DBG_RACHINFO, "RACH Info" },
- { DBG_LOGCHINFO, "LOG_CH_INFO" },
- { DBG_MEMORY, "Memory Region" },
- { DBG_PROFILING, "Profiling Region" },
- { DBG_TESTCOMMENT, "Test Comments" },
- { DBG_TEST, "Test Region" },
- { DBG_STATUS, "Status Region" },
- { 0, NULL }
-};
-
-const struct value_string lc15bts_tch_pl_names[] = {
- { GsmL1_TchPlType_NA, "N/A" },
- { GsmL1_TchPlType_Fr, "FR" },
- { GsmL1_TchPlType_Hr, "HR" },
- { GsmL1_TchPlType_Efr, "EFR" },
- { GsmL1_TchPlType_Amr, "AMR(IF2)" },
- { GsmL1_TchPlType_Amr_SidBad, "AMR(SID BAD)" },
- { GsmL1_TchPlType_Amr_Onset, "AMR(ONSET)" },
- { GsmL1_TchPlType_Amr_Ratscch, "AMR(RATSCCH)" },
- { GsmL1_TchPlType_Amr_SidUpdateInH, "AMR(SID_UPDATE INH)" },
- { GsmL1_TchPlType_Amr_SidFirstP1, "AMR(SID_FIRST P1)" },
- { GsmL1_TchPlType_Amr_SidFirstP2, "AMR(SID_FIRST P2)" },
- { GsmL1_TchPlType_Amr_SidFirstInH, "AMR(SID_FIRST INH)" },
- { GsmL1_TchPlType_Amr_RatscchMarker, "AMR(RATSCCH MARK)" },
- { GsmL1_TchPlType_Amr_RatscchData, "AMR(RATSCCH DATA)" },
- { 0, NULL }
-};
-
-const struct value_string lc15bts_dir_names[] = {
- { GsmL1_Dir_TxDownlink, "TxDL" },
- { GsmL1_Dir_TxUplink, "TxUL" },
- { GsmL1_Dir_RxUplink, "RxUL" },
- { GsmL1_Dir_RxDownlink, "RxDL" },
- { GsmL1_Dir_TxDownlink|GsmL1_Dir_RxUplink, "BOTH" },
- { 0, NULL }
-};
-
-const struct value_string lc15bts_chcomb_names[] = {
- { GsmL1_LogChComb_0, "dummy" },
- { GsmL1_LogChComb_I, "tch_f" },
- { GsmL1_LogChComb_II, "tch_h" },
- { GsmL1_LogChComb_IV, "ccch" },
- { GsmL1_LogChComb_V, "ccch_sdcch4" },
- { GsmL1_LogChComb_VII, "sdcch8" },
- { GsmL1_LogChComb_XIII, "pdtch" },
- { 0, NULL }
-};
-
-const uint8_t pdch_msu_size[_NUM_PDCH_CS] = {
- [PDCH_CS_1] = 23,
- [PDCH_CS_2] = 34,
- [PDCH_CS_3] = 40,
- [PDCH_CS_4] = 54,
- [PDCH_MCS_1] = 27,
- [PDCH_MCS_2] = 33,
- [PDCH_MCS_3] = 42,
- [PDCH_MCS_4] = 49,
- [PDCH_MCS_5] = 60,
- [PDCH_MCS_6] = 78,
- [PDCH_MCS_7] = 118,
- [PDCH_MCS_8] = 142,
- [PDCH_MCS_9] = 154
-};
diff --git a/src/osmo-bts-litecell15/lc15bts.h b/src/osmo-bts-litecell15/lc15bts.h
deleted file mode 100644
index ecfeb3da..00000000
--- a/src/osmo-bts-litecell15/lc15bts.h
+++ /dev/null
@@ -1,101 +0,0 @@
-#ifndef LC15BTS_H
-#define LC15BTS_H
-
-#include <stdlib.h>
-#include <osmocom/core/utils.h>
-
-#include <nrw/litecell15/litecell15.h>
-#include <nrw/litecell15/gsml1const.h>
-
-/*
- * Depending on the firmware version either GsmL1_Prim_t or Litecell15_Prim_t
- * is the bigger struct. For earlier firmware versions the GsmL1_Prim_t was the
- * bigger struct.
- */
-#define LC15BTS_PRIM_SIZE \
- (OSMO_MAX(sizeof(Litecell15_Prim_t), sizeof(GsmL1_Prim_t)) + 128)
-
-enum l1prim_type {
- L1P_T_INVALID, /* this must be 0 to detect uninitialized elements */
- L1P_T_REQ,
- L1P_T_CONF,
- L1P_T_IND,
-};
-
-
-enum lc15_diversity_mode{
- LC15_DIVERSITY_SISO_A = 0,
- LC15_DIVERSITY_SISO_B,
- LC15_DIVERSITY_MRC,
-};
-
-enum lc15_pedestal_mode{
- LC15_PEDESTAL_OFF = 0,
- LC15_PEDESTAL_ON,
-};
-
-enum lc15_led_control_mode{
- LC15_LED_CONTROL_BTS = 0,
- LC15_LED_CONTROL_EXT,
-};
-
-#if LITECELL15_API_VERSION >= LITECELL15_API(2,1,7)
-enum lc15_auto_pwr_adjust_mode{
- LC15_TX_PWR_ADJ_NONE = 0,
- LC15_TX_PWR_ADJ_AUTO,
-};
-#endif
-
-enum l1prim_type lc15bts_get_l1prim_type(GsmL1_PrimId_t id);
-extern const struct value_string lc15bts_l1prim_names[GsmL1_PrimId_NUM+1];
-GsmL1_PrimId_t lc15bts_get_l1prim_conf(GsmL1_PrimId_t id);
-
-enum l1prim_type lc15bts_get_sysprim_type(Litecell15_PrimId_t id);
-extern const struct value_string lc15bts_sysprim_names[Litecell15_PrimId_NUM+1];
-Litecell15_PrimId_t lc15bts_get_sysprim_conf(Litecell15_PrimId_t id);
-
-extern const struct value_string lc15bts_l1sapi_names[GsmL1_Sapi_NUM+1];
-extern const struct value_string lc15bts_l1status_names[GSML1_STATUS_NUM+1];
-
-extern const struct value_string lc15bts_tracef_names[29];
-extern const struct value_string lc15bts_tracef_docs[29];
-
-extern const struct value_string lc15bts_tch_pl_names[15];
-
-extern const struct value_string lc15bts_clksrc_names[10];
-
-extern const struct value_string lc15bts_dir_names[6];
-
-enum pdch_cs {
- PDCH_CS_1,
- PDCH_CS_2,
- PDCH_CS_3,
- PDCH_CS_4,
- PDCH_MCS_1,
- PDCH_MCS_2,
- PDCH_MCS_3,
- PDCH_MCS_4,
- PDCH_MCS_5,
- PDCH_MCS_6,
- PDCH_MCS_7,
- PDCH_MCS_8,
- PDCH_MCS_9,
- _NUM_PDCH_CS
-};
-
-extern const uint8_t pdch_msu_size[_NUM_PDCH_CS];
-
-/* LC15 default parameters */
-#define LC15_BTS_MAX_CELL_SIZE_DEFAULT 166 /* 166 qbits is default value */
-#define LC15_BTS_DIVERSITY_MODE_DEFAULT 0 /* SISO-A is default mode */
-#define LC15_BTS_PEDESTAL_MODE_DEFAULT 0 /* Unused TS is off by default */
-#define LC15_BTS_LED_CTRL_MODE_DEFAULT 0 /* LED is controlled by BTS by default */
-#define LC15_BTS_RTP_DRIFT_THRES_DEFAULT 0 /* Default RTP drift threshold is 0 ms (disabled) */
-#if LITECELL15_API_VERSION >= LITECELL15_API(2,1,7)
-#define LC15_BTS_DSP_ALIVE_TMR_DEFAULT 5 /* Default DSP alive timer is 5 seconds */
-#define LC15_BTS_TX_PWR_ADJ_DEFAULT 0 /* Default Tx power auto adjustment is none */
-#define LC15_BTS_TX_RED_PWR_8PSK_DEFAULT 0 /* Default 8-PSK maximum power level is 0 dB */
-#define LC15_BTS_TX_C0_IDLE_RED_PWR_DEFAULT 0 /* Default C0 idle slot reduction power level is 0 dB */
-#endif
-
-#endif /* LC15BTS_H */
diff --git a/src/osmo-bts-litecell15/lc15bts_vty.c b/src/osmo-bts-litecell15/lc15bts_vty.c
deleted file mode 100644
index 4a9d7908..00000000
--- a/src/osmo-bts-litecell15/lc15bts_vty.c
+++ /dev/null
@@ -1,638 +0,0 @@
-/* VTY interface for NuRAN Wireless Litecell 1.5 */
-
-/* Copyright (C) 2015 by Yves Godin <support@nuranwireless.com>
- * Copyright (C) 2016 by Harald Welte <laforge@gnumonks.org>
- *
- * Based on sysmoBTS:
- * (C) 2011 by Harald Welte <laforge@gnumonks.org>
- * (C) 2012,2013 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 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/licenses/>.
- *
- */
-
-#include <stdlib.h>
-#include <unistd.h>
-#include <errno.h>
-#include <stdint.h>
-#include <ctype.h>
-
-#include <arpa/inet.h>
-
-#include <osmocom/core/msgb.h>
-#include <osmocom/core/talloc.h>
-#include <osmocom/core/select.h>
-#include <osmocom/core/rate_ctr.h>
-
-#include <osmocom/gsm/tlv.h>
-
-#include <osmocom/vty/vty.h>
-#include <osmocom/vty/command.h>
-#include <osmocom/vty/misc.h>
-
-#include <osmocom/ctrl/control_cmd.h>
-#include <osmo-bts/signal.h>
-#include <osmo-bts/oml.h>
-#include <osmo-bts/bts.h>
-
-#include <osmo-bts/gsm_data.h>
-#include <osmo-bts/phy_link.h>
-#include <osmo-bts/logging.h>
-#include <osmo-bts/bts_model.h>
-#include <osmo-bts/vty.h>
-#include <osmo-bts/rsl.h>
-
-#include "lc15bts.h"
-#include "l1_if.h"
-#include "utils.h"
-
-extern int lchan_activate(struct gsm_lchan *lchan);
-extern int rsl_tx_preproc_meas_res(struct gsm_lchan *lchan);
-
-#define TRX_STR "Transceiver related commands\n" "TRX number\n"
-
-#define SHOW_TRX_STR \
- SHOW_STR \
- TRX_STR
-#define DSP_TRACE_F_STR "DSP Trace Flag\n"
-
-static const struct value_string lc15_diversity_mode_strs[] = {
- { LC15_DIVERSITY_SISO_A, "siso-a" },
- { LC15_DIVERSITY_SISO_B, "siso-b" },
- { LC15_DIVERSITY_MRC, "mrc" },
- { 0, NULL }
-};
-
-static const struct value_string lc15_pedestal_mode_strs[] = {
- { LC15_PEDESTAL_OFF, "off" },
- { LC15_PEDESTAL_ON, "on" },
- { 0, NULL }
-};
-
-static const struct value_string lc15_led_mode_strs[] = {
- { LC15_LED_CONTROL_BTS, "bts" },
- { LC15_LED_CONTROL_EXT, "external" },
- { 0, NULL }
-};
-
-#if LITECELL15_API_VERSION >= LITECELL15_API(2,1,7)
-static const struct value_string lc15_auto_adj_pwr_strs[] = {
- { LC15_TX_PWR_ADJ_NONE, "none" },
- { LC15_TX_PWR_ADJ_AUTO, "auto" },
- { 0, NULL }
-};
-#endif
-
-/* configuration */
-
-DEFUN(cfg_phy_cal_path, cfg_phy_cal_path_cmd,
- "trx-calibration-path PATH",
- "Set the path name to TRX calibration data\n" "Path name\n")
-{
- struct phy_instance *pinst = vty->index;
-
- if (pinst->u.lc15.calib_path)
- talloc_free(pinst->u.lc15.calib_path);
-
- pinst->u.lc15.calib_path = talloc_strdup(pinst, argv[0]);
-
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_phy_dsp_trace_f, cfg_phy_dsp_trace_f_cmd,
- "HIDDEN", TRX_STR)
-{
- struct phy_instance *pinst = vty->index;
- unsigned int flag;
-
- flag = get_string_value(lc15bts_tracef_names, argv[0]);
- pinst->u.lc15.dsp_trace_f |= flag;
-
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_phy_no_dsp_trace_f, cfg_phy_no_dsp_trace_f_cmd,
- "HIDDEN", NO_STR TRX_STR)
-{
- struct phy_instance *pinst = vty->index;
- unsigned int flag;
-
- flag = get_string_value(lc15bts_tracef_names, argv[0]);
- pinst->u.lc15.dsp_trace_f &= ~flag;
-
- return CMD_SUCCESS;
-}
-
-
-/* runtime */
-
-DEFUN(show_dsp_trace_f, show_dsp_trace_f_cmd,
- "show trx <0-0> dsp-trace-flags",
- SHOW_TRX_STR "Display the current setting of the DSP trace flags")
-{
- int trx_nr = atoi(argv[0]);
- struct gsm_bts_trx *trx = gsm_bts_trx_num(g_bts, trx_nr);
- struct lc15l1_hdl *fl1h;
- int i;
-
- if (!trx)
- return CMD_WARNING;
-
- fl1h = trx_lc15l1_hdl(trx);
-
- vty_out(vty, "Litecell15 L1 DSP trace flags:%s", VTY_NEWLINE);
- for (i = 0; i < ARRAY_SIZE(lc15bts_tracef_names); i++) {
- const char *endis;
-
- if (lc15bts_tracef_names[i].value == 0 &&
- lc15bts_tracef_names[i].str == NULL)
- break;
-
- if (fl1h->dsp_trace_f & lc15bts_tracef_names[i].value)
- endis = "enabled";
- else
- endis = "disabled";
-
- vty_out(vty, "DSP Trace %-15s %s%s",
- lc15bts_tracef_names[i].str, endis,
- VTY_NEWLINE);
- }
-
- return CMD_SUCCESS;
-
-}
-
-DEFUN(dsp_trace_f, dsp_trace_f_cmd, "HIDDEN", TRX_STR)
-{
- int phy_nr = atoi(argv[0]);
- struct phy_instance *pinst;
- struct lc15l1_hdl *fl1h;
- unsigned int flag ;
-
- pinst = vty_get_phy_instance(vty, phy_nr, 0);
- if (!pinst)
- return CMD_WARNING;
-
- fl1h = pinst->u.lc15.hdl;
- flag = get_string_value(lc15bts_tracef_names, argv[1]);
- l1if_set_trace_flags(fl1h, fl1h->dsp_trace_f | flag);
-
- return CMD_SUCCESS;
-}
-
-DEFUN(no_dsp_trace_f, no_dsp_trace_f_cmd, "HIDDEN", NO_STR TRX_STR)
-{
- int phy_nr = atoi(argv[0]);
- struct phy_instance *pinst;
- struct lc15l1_hdl *fl1h;
- unsigned int flag ;
-
- pinst = vty_get_phy_instance(vty, phy_nr, 0);
- if (!pinst)
- return CMD_WARNING;
-
- fl1h = pinst->u.lc15.hdl;
- flag = get_string_value(lc15bts_tracef_names, argv[1]);
- l1if_set_trace_flags(fl1h, fl1h->dsp_trace_f & ~flag);
-
- return CMD_SUCCESS;
-}
-
-DEFUN(show_sys_info, show_sys_info_cmd,
- "show phy <0-1> instance <0-0> system-information",
- SHOW_TRX_STR "Display information about system\n")
-{
- int phy_nr = atoi(argv[0]);
- int inst_nr = atoi(argv[1]);
- struct phy_link *plink = phy_link_by_num(phy_nr);
- struct phy_instance *pinst;
- struct lc15l1_hdl *fl1h;
- int i;
-
- if (!plink) {
- vty_out(vty, "Cannot find PHY link %u%s",
- phy_nr, VTY_NEWLINE);
- return CMD_WARNING;
- }
- pinst = phy_instance_by_num(plink, inst_nr);
- if (!plink) {
- vty_out(vty, "Cannot find PHY instance %u%s",
- phy_nr, VTY_NEWLINE);
- return CMD_WARNING;
- }
- fl1h = pinst->u.lc15.hdl;
-
- vty_out(vty, "DSP Version: %u.%u.%u, FPGA Version: %u.%u.%u%s",
- fl1h->hw_info.dsp_version[0],
- fl1h->hw_info.dsp_version[1],
- fl1h->hw_info.dsp_version[2],
- fl1h->hw_info.fpga_version[0],
- fl1h->hw_info.fpga_version[1],
- fl1h->hw_info.fpga_version[2], VTY_NEWLINE);
-
- vty_out(vty, "GSM Band Support: ");
- for (i = 0; i < sizeof(fl1h->hw_info.band_support); i++) {
- if (fl1h->hw_info.band_support & (1 << i))
- vty_out(vty, "%s ", gsm_band_name(1 << i));
- }
- vty_out(vty, "%s", VTY_NEWLINE);
- vty_out(vty, "Min Tx Power: %d dBm%s", fl1h->phy_inst->u.lc15.minTxPower, VTY_NEWLINE);
- vty_out(vty, "Max Tx Power: %d dBm%s", fl1h->phy_inst->u.lc15.maxTxPower, VTY_NEWLINE);
-
- return CMD_SUCCESS;
-}
-
-DEFUN(activate_lchan, activate_lchan_cmd,
- "trx <0-0> <0-7> (activate|deactivate) <0-7>",
- TRX_STR
- "Timeslot number\n"
- "Activate Logical Channel\n"
- "Deactivate Logical Channel\n"
- "Logical Channel Number\n" )
-{
- int trx_nr = atoi(argv[0]);
- int ts_nr = atoi(argv[1]);
- int lchan_nr = atoi(argv[3]);
- struct gsm_bts_trx *trx = gsm_bts_trx_num(g_bts, trx_nr);
- struct gsm_bts_trx_ts *ts = &trx->ts[ts_nr];
- struct gsm_lchan *lchan = &ts->lchan[lchan_nr];
-
- if (!strcmp(argv[2], "activate"))
- lchan_activate(lchan);
- else
- lchan_deactivate(lchan);
-
- return CMD_SUCCESS;
-}
-
-DEFUN(set_tx_power, set_tx_power_cmd,
- "trx nr <0-1> tx-power <-110-100>",
- TRX_STR
- "TRX number \n"
- "Set transmit power (override BSC)\n"
- "Transmit power in dBm\n")
-{
- int trx_nr = atoi(argv[0]);
- int power = atoi(argv[1]);
- struct gsm_bts_trx *trx = gsm_bts_trx_num(g_bts, trx_nr);
-
- power_ramp_start(trx, to_mdB(power), 1, NULL);
-
- return CMD_SUCCESS;
-}
-
-DEFUN(loopback, loopback_cmd,
- "trx <0-0> <0-7> loopback <0-1>",
- TRX_STR
- "Timeslot number\n"
- "Set TCH loopback\n"
- "Logical Channel Number\n")
-{
- int trx_nr = atoi(argv[0]);
- int ts_nr = atoi(argv[1]);
- int lchan_nr = atoi(argv[2]);
- struct gsm_bts_trx *trx = gsm_bts_trx_num(g_bts, trx_nr);
- struct gsm_bts_trx_ts *ts = &trx->ts[ts_nr];
- struct gsm_lchan *lchan = &ts->lchan[lchan_nr];
-
- lchan->loopback = 1;
-
- return CMD_SUCCESS;
-}
-
-DEFUN(no_loopback, no_loopback_cmd,
- "no trx <0-0> <0-7> loopback <0-1>",
- NO_STR TRX_STR
- "Timeslot number\n"
- "Set TCH loopback\n"
- "Logical Channel Number\n")
-{
- int trx_nr = atoi(argv[0]);
- int ts_nr = atoi(argv[1]);
- int lchan_nr = atoi(argv[2]);
- struct gsm_bts_trx *trx = gsm_bts_trx_num(g_bts, trx_nr);
- struct gsm_bts_trx_ts *ts = &trx->ts[ts_nr];
- struct gsm_lchan *lchan = &ts->lchan[lchan_nr];
-
- lchan->loopback = 0;
-
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_trx_nominal_power, cfg_trx_nominal_power_cmd,
- "nominal-tx-power <0-40>",
- "Set the nominal transmit output power in dBm\n"
- "Nominal transmit output power level in dBm\n")
-{
- int nominal_power = atoi(argv[0]);
- struct gsm_bts_trx *trx = vty->index;
-
- if (( nominal_power > 40 ) || ( nominal_power < 0 )) {
- vty_out(vty, "Nominal Tx power level must be between 0 and 40 dBm (%d) %s",
- nominal_power, VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- trx->nominal_power = nominal_power;
- trx->power_params.trx_p_max_out_mdBm = to_mdB(nominal_power);
-
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_phy_max_cell_size, cfg_phy_max_cell_size_cmd,
- "max-cell-size <0-166>",
- "Set the maximum cell size in qbits\n")
-{
- struct phy_instance *pinst = vty->index;
- int cell_size = (uint8_t)atoi(argv[0]);
-
- if (( cell_size > 166 ) || ( cell_size < 0 )) {
- vty_out(vty, "Max cell size must be between 0 and 166 qbits (%d) %s",
- cell_size, VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- pinst->u.lc15.max_cell_size = (uint8_t)cell_size;
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_phy_diversity_mode, cfg_phy_diversity_mode_cmd,
- "diversity-mode (siso-a|siso-b|mrc)",
- "Set reception diversity mode \n"
- "Reception diversity mode can be (siso-a, siso-b, mrc)\n")
-{
- struct phy_instance *pinst = vty->index;
- int val = get_string_value(lc15_diversity_mode_strs, argv[0]);
-
- if((val < LC15_DIVERSITY_SISO_A) || (val > LC15_DIVERSITY_MRC)) {
- vty_out(vty, "Invalid reception diversity mode %d%s", val, VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- pinst->u.lc15.diversity_mode = (uint8_t)val;
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_phy_pedestal_mode, cfg_phy_pedestal_mode_cmd,
- "pedestal-mode (on|off)",
- "Set unused time-slot transmission in pedestal mode\n"
- "Transmission pedestal mode can be (off, on)\n")
-{
- struct phy_instance *pinst = vty->index;
- int val = get_string_value(lc15_pedestal_mode_strs, argv[0]);
-
- if((val < LC15_PEDESTAL_OFF) || (val > LC15_PEDESTAL_ON)) {
- vty_out(vty, "Invalid unused time-slot transmission mode %d%s", val, VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- pinst->u.lc15.pedestal_mode = (uint8_t)val;
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_bts_led_mode, cfg_bts_led_mode_cmd,
- "led-control-mode (bts|external)",
- "Set LED controlled by BTS or external software\n"
- "LED can be controlled by (bts, external)\n")
-{
- struct gsm_bts *bts = vty->index;
- int val = get_string_value(lc15_led_mode_strs, argv[0]);
-
- if((val < LC15_LED_CONTROL_BTS) || (val > LC15_LED_CONTROL_EXT)) {
- vty_out(vty, "Invalid LED control mode %d%s", val, VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- struct bts_lc15_priv *bts_lc15 = bts->model_priv;
- bts_lc15->led_ctrl_mode = (uint8_t)val;
- return CMD_SUCCESS;
-}
-
-#if LITECELL15_API_VERSION >= LITECELL15_API(2,1,7)
-DEFUN(cfg_phy_dsp_alive_timer, cfg_phy_dsp_alive_timer_cmd,
- "dsp-alive-period <0-60>",
- "Set DSP alive timer period in second\n")
-{
- struct phy_instance *pinst = vty->index;
- uint8_t period = (uint8_t)atoi(argv[0]);
-
- if (( period > 60 ) || ( period < 0 )) {
- vty_out(vty, "DSP heart beat alive timer period must be between 0 and 60 seconds (%d) %s",
- period, VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- pinst->u.lc15.dsp_alive_period = period;
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_phy_auto_tx_pwr_adj, cfg_phy_auto_tx_pwr_adj_cmd,
- "pwr-adj-mode (none|auto)",
- "Set output power adjustment mode\n")
-{
- struct phy_instance *pinst = vty->index;
- int val = get_string_value(lc15_auto_adj_pwr_strs, argv[0]);
-
- if((val < LC15_TX_PWR_ADJ_NONE) || (val > LC15_TX_PWR_ADJ_AUTO)) {
- vty_out(vty, "Invalid output power adjustment mode %d%s", val, VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- pinst->u.lc15.tx_pwr_adj_mode = (uint8_t)val;
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_phy_tx_red_pwr_8psk, cfg_phy_tx_red_pwr_8psk_cmd,
- "tx-red-pwr-8psk <0-40>",
- "Set reduction output power for 8-PSK scheme in dB unit\n")
-{
- struct phy_instance *pinst = vty->index;
- int val = atoi(argv[0]);
-
- if ((val > 40) || (val < 0)) {
- vty_out(vty, "Reduction Tx power level must be between 0 and 40 dB (%d) %s",
- val, VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- pinst->u.lc15.tx_pwr_red_8psk = (uint8_t)val;
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_phy_c0_idle_red_pwr, cfg_phy_c0_idle_red_pwr_cmd,
- "c0-idle-red-pwr <0-40>",
- "Set reduction output power for C0 idle slot in dB unit\n")
-{
- struct phy_instance *pinst = vty->index;
- int val = atoi(argv[0]);
-
- if ((val > 40) || (val < 0)) {
- vty_out(vty, "Reduction Tx power level must be between 0 and 40 dB (%d) %s",
- val, VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- pinst->u.lc15.tx_c0_idle_pwr_red = (uint8_t)val;
- return CMD_SUCCESS;
-}
-#endif
-
-DEFUN(cfg_bts_rtp_drift_threshold, cfg_bts_rtp_drift_threshold_cmd,
- "rtp-drift-threshold <0-10000>",
- "RTP parameters\n"
- "RTP timestamp drift threshold in ms\n")
-{
- struct gsm_bts *bts = vty->index;
-
- struct bts_lc15_priv *bts_lc15 = bts->model_priv;
- bts_lc15->rtp_drift_thres_ms = (unsigned int) atoi(argv[0]);
-
- return CMD_SUCCESS;
-}
-
-void bts_model_config_write_bts(struct vty *vty, const struct gsm_bts *bts)
-{
- const struct bts_lc15_priv *bts_lc15 = bts->model_priv;
- vty_out(vty, " led-control-mode %s%s",
- get_value_string(lc15_led_mode_strs, bts_lc15->led_ctrl_mode), VTY_NEWLINE);
-
- vty_out(vty, " rtp-drift-threshold %d%s",
- bts_lc15->rtp_drift_thres_ms, VTY_NEWLINE);
-
-}
-
-void bts_model_config_write_trx(struct vty *vty, const struct gsm_bts_trx *trx)
-{
- vty_out(vty, " nominal-tx-power %d%s", trx->nominal_power,VTY_NEWLINE);
-}
-
-void bts_model_config_write_phy(struct vty *vty, const struct phy_link *plink)
-{
-}
-
-void bts_model_config_write_phy_inst(struct vty *vty, const struct phy_instance *pinst)
-{
- int i;
-
- for (i = 0; i < 32; i++) {
- if (pinst->u.lc15.dsp_trace_f & (1 << i)) {
- const char *name;
- name = get_value_string(lc15bts_tracef_names, (1 << i));
- vty_out(vty, " dsp-trace-flag %s%s", name,
- VTY_NEWLINE);
- }
- }
- if (pinst->u.lc15.calib_path)
- vty_out(vty, " trx-calibration-path %s%s",
- pinst->u.lc15.calib_path, VTY_NEWLINE);
-
- vty_out(vty, " max-cell-size %d%s",
- pinst->u.lc15.max_cell_size, VTY_NEWLINE);
-
- vty_out(vty, " diversity-mode %s%s",
- get_value_string(lc15_diversity_mode_strs, pinst->u.lc15.diversity_mode), VTY_NEWLINE);
-
- vty_out(vty, " pedestal-mode %s%s",
- get_value_string(lc15_pedestal_mode_strs, pinst->u.lc15.pedestal_mode) , VTY_NEWLINE);
-
-#if LITECELL15_API_VERSION >= LITECELL15_API(2,1,7)
- vty_out(vty, " dsp-alive-period %d%s",
- pinst->u.lc15.dsp_alive_period, VTY_NEWLINE);
-
- vty_out(vty, " pwr-adj-mode %s%s",
- get_value_string(lc15_auto_adj_pwr_strs, pinst->u.lc15.tx_pwr_adj_mode), VTY_NEWLINE);
-
- vty_out(vty, " tx-red-pwr-8psk %d%s",
- pinst->u.lc15.tx_pwr_red_8psk, VTY_NEWLINE);
-
- vty_out(vty, " c0-idle-red-pwr %d%s",
- pinst->u.lc15.tx_c0_idle_pwr_red, VTY_NEWLINE);
-#endif
-}
-
-int bts_model_vty_init(void *ctx)
-{
- /* runtime-patch the command strings with debug levels */
- dsp_trace_f_cmd.string = vty_cmd_string_from_valstr(ctx, lc15bts_tracef_names,
- "phy <0-0> dsp-trace-flag (",
- "|",")", VTY_DO_LOWER);
- dsp_trace_f_cmd.doc = vty_cmd_string_from_valstr(ctx, lc15bts_tracef_docs,
- TRX_STR DSP_TRACE_F_STR,
- "\n", "", 0);
-
- no_dsp_trace_f_cmd.string = vty_cmd_string_from_valstr(ctx, lc15bts_tracef_names,
- "no phy <0-0> dsp-trace-flag (",
- "|",")", VTY_DO_LOWER);
- no_dsp_trace_f_cmd.doc = vty_cmd_string_from_valstr(ctx, lc15bts_tracef_docs,
- NO_STR TRX_STR DSP_TRACE_F_STR,
- "\n", "", 0);
-
- cfg_phy_dsp_trace_f_cmd.string = vty_cmd_string_from_valstr(ctx,
- lc15bts_tracef_names,
- "dsp-trace-flag (",
- "|",")", VTY_DO_LOWER);
- cfg_phy_dsp_trace_f_cmd.doc = vty_cmd_string_from_valstr(ctx,
- lc15bts_tracef_docs,
- DSP_TRACE_F_STR,
- "\n", "", 0);
-
- cfg_phy_no_dsp_trace_f_cmd.string = vty_cmd_string_from_valstr(ctx,
- lc15bts_tracef_names,
- "no dsp-trace-flag (",
- "|",")", VTY_DO_LOWER);
- cfg_phy_no_dsp_trace_f_cmd.doc = vty_cmd_string_from_valstr(ctx,
- lc15bts_tracef_docs,
- NO_STR DSP_TRACE_F_STR,
- "\n", "", 0);
-
- install_element_ve(&show_dsp_trace_f_cmd);
- install_element_ve(&show_sys_info_cmd);
- install_element_ve(&dsp_trace_f_cmd);
- install_element_ve(&no_dsp_trace_f_cmd);
-
- install_element(ENABLE_NODE, &activate_lchan_cmd);
- install_element(ENABLE_NODE, &set_tx_power_cmd);
-
- install_element(ENABLE_NODE, &loopback_cmd);
- install_element(ENABLE_NODE, &no_loopback_cmd);
-
- install_element(BTS_NODE, &cfg_bts_auto_band_cmd);
- install_element(BTS_NODE, &cfg_bts_no_auto_band_cmd);
- install_element(BTS_NODE, &cfg_bts_led_mode_cmd);
- install_element(BTS_NODE, &cfg_bts_rtp_drift_threshold_cmd);
-
- install_element(TRX_NODE, &cfg_trx_nominal_power_cmd);
-
- install_element(PHY_INST_NODE, &cfg_phy_dsp_trace_f_cmd);
- install_element(PHY_INST_NODE, &cfg_phy_no_dsp_trace_f_cmd);
- install_element(PHY_INST_NODE, &cfg_phy_cal_path_cmd);
-
- install_element(PHY_INST_NODE, &cfg_phy_diversity_mode_cmd);
- install_element(PHY_INST_NODE, &cfg_phy_pedestal_mode_cmd);
- install_element(PHY_INST_NODE, &cfg_phy_max_cell_size_cmd);
-#if LITECELL15_API_VERSION >= LITECELL15_API(2,1,7)
- install_element(PHY_INST_NODE, &cfg_phy_dsp_alive_timer_cmd);
- install_element(PHY_INST_NODE, &cfg_phy_auto_tx_pwr_adj_cmd);
- install_element(PHY_INST_NODE, &cfg_phy_tx_red_pwr_8psk_cmd);
- install_element(PHY_INST_NODE, &cfg_phy_c0_idle_red_pwr_cmd);
-#endif
- return 0;
-}
-
-int bts_model_ctrl_cmds_install(struct gsm_bts *bts)
-{
- return 0;
-}
diff --git a/src/osmo-bts-litecell15/main.c b/src/osmo-bts-litecell15/main.c
deleted file mode 100644
index 985d7dba..00000000
--- a/src/osmo-bts-litecell15/main.c
+++ /dev/null
@@ -1,226 +0,0 @@
-/* Main program for NuRAN Wireless Litecell 1.5 BTS */
-
-/* Copyright (C) 2015 by Yves Godin <support@nuranwireless.com>
- * Copyright (C) 2016 by Harald Welte <laforge@gnumonks.org>
- *
- * Based on sysmoBTS:
- * (C) 2011-2013 by Harald Welte <laforge@gnumonks.org>
- *
- * 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 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/licenses/>.
- *
- */
-
-#include <stdint.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <getopt.h>
-#include <limits.h>
-#include <sys/signal.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sched.h>
-
-#include <netinet/in.h>
-#include <arpa/inet.h>
-
-#include <osmocom/core/talloc.h>
-#include <osmocom/core/application.h>
-#include <osmocom/vty/telnet_interface.h>
-#include <osmocom/vty/logging.h>
-#include <osmocom/vty/ports.h>
-
-#include <osmo-bts/gsm_data.h>
-#include <osmo-bts/logging.h>
-#include <osmo-bts/bts.h>
-#include <osmo-bts/vty.h>
-#include <osmo-bts/bts_model.h>
-#include <osmo-bts/pcu_if.h>
-#include <osmo-bts/l1sap.h>
-
-static int write_status_file(char *status_file, char *status_str)
-{
- FILE *outf;
- char tmp[PATH_MAX+1];
-
- snprintf(tmp, sizeof(tmp)-1, "/var/run/osmo-bts/%s", status_file);
- tmp[PATH_MAX-1] = '\0';
-
- outf = fopen(tmp, "w");
- if (!outf)
- return -1;
-
- fprintf(outf, "%s\n", status_str);
-
- fclose(outf);
-
- return 0;
-}
-
-/*NTQD: Change how rx_nr is handle in multi-trx*/
-#define LC15BTS_RF_LOCK_PATH "/var/lock/bts_rf_lock"
-
-#include "utils.h"
-#include "l1_if.h"
-#include "hw_misc.h"
-#include "misc/lc15bts_bid.h"
-
-unsigned int dsp_trace = 0x00000000;
-
-int bts_model_init(struct gsm_bts *bts)
-{
- struct stat st;
-
- struct bts_lc15_priv *bts_lc15 = talloc(bts, struct bts_lc15_priv);
-
- bts->model_priv = bts_lc15;
- bts->variant = BTS_OSMO_LITECELL15;
- bts->support.ciphers = CIPHER_A5(1) | CIPHER_A5(2) | CIPHER_A5(3);
-
- /* specific default values for LC15 platform */
- bts_lc15->led_ctrl_mode = LC15_BTS_LED_CTRL_MODE_DEFAULT;
- /* RTP drift threshold default */
- bts_lc15->rtp_drift_thres_ms = LC15_BTS_RTP_DRIFT_THRES_DEFAULT;
-
- if (stat(LC15BTS_RF_LOCK_PATH, &st) == 0) {
- LOGP(DL1C, LOGL_NOTICE, "Not starting BTS due to RF_LOCK file present\n");
- exit(23);
- }
-
- osmo_bts_set_feature(bts->features, BTS_FEAT_GPRS);
- osmo_bts_set_feature(bts->features, BTS_FEAT_EGPRS);
- osmo_bts_set_feature(bts->features, BTS_FEAT_OML_ALERTS);
- osmo_bts_set_feature(bts->features, BTS_FEAT_AGCH_PCH_PROP);
- osmo_bts_set_feature(bts->features, BTS_FEAT_SPEECH_F_V1);
- osmo_bts_set_feature(bts->features, BTS_FEAT_SPEECH_H_V1);
- osmo_bts_set_feature(bts->features, BTS_FEAT_SPEECH_F_EFR);
- osmo_bts_set_feature(bts->features, BTS_FEAT_SPEECH_F_AMR);
- osmo_bts_set_feature(bts->features, BTS_FEAT_SPEECH_H_AMR);
-
- bts_internal_flag_set(bts, BTS_INTERNAL_FLAG_MS_PWR_CTRL_DSP);
-
- return 0;
-}
-
-int bts_model_trx_init(struct gsm_bts_trx *trx)
-{
- trx->nominal_power = 40;
- trx->power_params.trx_p_max_out_mdBm = to_mdB(trx->bts->c0->nominal_power);
- return 0;
-}
-
-void bts_model_phy_link_set_defaults(struct phy_link *plink)
-{
-}
-
-void bts_model_phy_instance_set_defaults(struct phy_instance *pinst)
-{
-}
-
-int bts_model_oml_estab(struct gsm_bts *bts)
-{
- /* update status file */
- write_status_file("state", "");
-
- return 0;
-}
-
-void bts_update_status(enum bts_global_status which, int on)
-{
- static uint64_t states = 0;
- uint64_t old_states = states;
-
- if (on)
- states |= (1ULL << which);
- else
- states &= ~(1ULL << which);
-
- LOGP(DL1C, LOGL_INFO,
- "Set global status #%d to %d (%04llx -> %04llx)",
- which, on,
- (long long)old_states, (long long)states);
-}
-
-void bts_model_print_help()
-{
- printf( "\nModel specific options:\n"
- " -w --hw-version Print the targeted HW Version\n"
- " -M --pcu-direct Force PCU to access message queue for "
- "PDCH dchannel directly\n"
- " -p --dsp-trace Set DSP trace flags\n"
- );
-}
-
-static void print_hwversion()
-{
- printf(get_hwversion_desc());
- printf("\n");
-}
-
-int bts_model_handle_options(int argc, char **argv)
-{
- int num_errors = 0;
-
- while (1) {
- int option_idx = 0, c;
- static const struct option long_options[] = {
- { "dsp-trace", 1, 0, 'p' },
- { "hw-version", 0, 0, 'w' },
- { "pcu-direct", 0, 0, 'M' },
- { 0, 0, 0, 0 }
- };
-
- c = getopt_long(argc, argv, "p:wM",
- long_options, &option_idx);
- if (c == -1)
- break;
-
- switch (c) {
- case 'p':
- dsp_trace = strtoul(optarg, NULL, 16);
- break;
- case 'M':
- pcu_direct = 1;
- break;
- case 'w':
- print_hwversion();
- exit(0);
- break;
- default:
- num_errors++;
- break;
- }
- }
-
- return num_errors;
-}
-
-void bts_model_abis_close(struct gsm_bts *bts)
-{
- /* write to status file */
- write_status_file("state", "ABIS DOWN");
-
- /* for now, we simply terminate the program and re-spawn */
- bts_shutdown(bts, "Abis close");
-}
-
-int main(int argc, char **argv)
-{
- /* create status file with initial state */
- write_status_file("state", "ABIS DOWN");
-
- return bts_main(argc, argv);
-}
diff --git a/src/osmo-bts-litecell15/misc/lc15bts_bid.c b/src/osmo-bts-litecell15/misc/lc15bts_bid.c
deleted file mode 100644
index 9284b62e..00000000
--- a/src/osmo-bts-litecell15/misc/lc15bts_bid.c
+++ /dev/null
@@ -1,162 +0,0 @@
-/* Copyright (C) 2015 by Yves Godin <support@nuranwireless.com>
- *
- * 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 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/licenses/>.
- *
- */
-
-#include <stdio.h>
-#include <stdint.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <stdbool.h>
-
-#include "lc15bts_bid.h"
-
-#define BOARD_REV_SYSFS "/var/lc15/platform/revision"
-#define BOARD_OPT_SYSFS "/var/lc15/platform/option"
-
-static const int option_type_mask[_NUM_OPTION_TYPES] = {
- [LC15BTS_OPTION_OCXO] = 0x07,
- [LC15BTS_OPTION_FPGA] = 0x03,
- [LC15BTS_OPTION_PA] = 0x01,
- [LC15BTS_OPTION_BAND] = 0x03,
- [LC15BTS_OPTION_TX_ISO_BYP] = 0x01,
- [LC15BTS_OPTION_RX_DUP_BYP] = 0x01,
- [LC15BTS_OPTION_RX_PB_BYP] = 0x01,
- [LC15BTS_OPTION_RX_DIV] = 0x01,
- [LC15BTS_OPTION_RX1A] = 0x01,
- [LC15BTS_OPTION_RX1B] = 0x01,
- [LC15BTS_OPTION_RX2A] = 0x01,
- [LC15BTS_OPTION_RX2B] = 0x01,
- [LC15BTS_OPTION_DDR_32B] = 0x01,
- [LC15BTS_OPTION_DDR_ECC] = 0x01,
- [LC15BTS_OPTION_LOG_DET] = 0x01,
- [LC15BTS_OPTION_DUAL_LOG_DET] = 0x01,
-};
-
-static const int option_type_shift[_NUM_OPTION_TYPES] = {
- [LC15BTS_OPTION_OCXO] = 0,
- [LC15BTS_OPTION_FPGA] = 3,
- [LC15BTS_OPTION_PA] = 5,
- [LC15BTS_OPTION_BAND] = 6,
- [LC15BTS_OPTION_TX_ISO_BYP] = 8,
- [LC15BTS_OPTION_RX_DUP_BYP] = 9,
- [LC15BTS_OPTION_RX_PB_BYP] = 10,
- [LC15BTS_OPTION_RX_DIV] = 11,
- [LC15BTS_OPTION_RX1A] = 12,
- [LC15BTS_OPTION_RX1B] = 13,
- [LC15BTS_OPTION_RX2A] = 14,
- [LC15BTS_OPTION_RX2B] = 15,
- [LC15BTS_OPTION_DDR_32B] = 16,
- [LC15BTS_OPTION_DDR_ECC] = 17,
- [LC15BTS_OPTION_LOG_DET] = 18,
- [LC15BTS_OPTION_DUAL_LOG_DET] = 19,
-};
-
-
-static int board_rev = -1;
-static int board_option = -1;
-
-static inline bool read_board(const char *src, const char *spec, void *dst)
-{
- FILE *fp = fopen(src, "r");
- if (!fp) {
- fprintf(stderr, "Failed to open %s due to '%s' error\n", src, strerror(errno));
- return false;
- }
-
- if (fscanf(fp, spec, dst) != 1) {
- fclose(fp);
- fprintf(stderr, "Failed to read %s due to '%s' error\n", src, strerror(errno));
- return false;
- }
- fclose(fp);
- return true;
-}
-
-int lc15bts_rev_get(void)
-{
- char rev;
-
- if (board_rev != -1) {
- return board_rev;
- }
-
- if (!read_board(BOARD_REV_SYSFS, "%c", &rev))
- return -1;
-
- board_rev = rev;
- return board_rev;
-}
-
-int lc15bts_model_get(void)
-{
- int opt;
-
- if (board_option != -1)
- return board_option;
-
- if (!read_board(BOARD_OPT_SYSFS, "%X", &opt))
- return -1;
-
- board_option = opt;
- return board_option;
-}
-
-int lc15bts_option_get(enum lc15bts_option_type type)
-{
- int rc;
- int option;
-
- if (type >= _NUM_OPTION_TYPES) {
- return -EINVAL;
- }
-
- if (board_option == -1) {
- rc = lc15bts_model_get();
- if (rc < 0) return rc;
- }
-
- option = (board_option >> option_type_shift[type])
- & option_type_mask[type];
-
- return option;
-}
-
-const char* get_hwversion_desc()
-{
- int rev;
- int model;
- size_t len;
- static char model_name[64] = {0, };
- len = snprintf(model_name, sizeof(model_name), "NuRAN Litecell 1.5 BTS");
-
- rev = lc15bts_rev_get();
- if (rev >= 0) {
- len += snprintf(model_name + len, sizeof(model_name) - len,
- " Rev %c", (char)rev);
- }
-
- model = lc15bts_model_get();
- if (model >= 0) {
- snprintf(model_name + len, sizeof(model_name) - len,
- "%s (%05X)", model_name, model);
- }
- return model_name;
-}
diff --git a/src/osmo-bts-litecell15/misc/lc15bts_bid.h b/src/osmo-bts-litecell15/misc/lc15bts_bid.h
deleted file mode 100644
index a71fdd7e..00000000
--- a/src/osmo-bts-litecell15/misc/lc15bts_bid.h
+++ /dev/null
@@ -1,52 +0,0 @@
-#ifndef _LC15BTS_BOARD_H
-#define _LC15BTS_BOARD_H
-
-#include <stdint.h>
-
-enum lc15bts_option_type {
- LC15BTS_OPTION_OCXO,
- LC15BTS_OPTION_FPGA,
- LC15BTS_OPTION_PA,
- LC15BTS_OPTION_BAND,
- LC15BTS_OPTION_TX_ISO_BYP,
- LC15BTS_OPTION_RX_DUP_BYP,
- LC15BTS_OPTION_RX_PB_BYP,
- LC15BTS_OPTION_RX_DIV,
- LC15BTS_OPTION_RX1A,
- LC15BTS_OPTION_RX1B,
- LC15BTS_OPTION_RX2A,
- LC15BTS_OPTION_RX2B,
- LC15BTS_OPTION_DDR_32B,
- LC15BTS_OPTION_DDR_ECC,
- LC15BTS_OPTION_LOG_DET,
- LC15BTS_OPTION_DUAL_LOG_DET,
- _NUM_OPTION_TYPES
-};
-
-enum lc15bts_ocxo_type {
- LC15BTS_OCXO_BILAY_NVG45AV2072,
- LC15BTS_OCXO_TAITIEN_NJ26M003,
- _NUM_OCXO_TYPES
-};
-
-enum lc15bts_fpga_type {
- LC15BTS_FPGA_35T,
- LC15BTS_FPGA_50T,
- LC15BTS_FPGA_75T,
- LC15BTS_FPGA_100T,
- _NUM_FPGA_TYPES
-};
-
-enum lc15bts_gsm_band {
- LC15BTS_BAND_850,
- LC15BTS_BAND_900,
- LC15BTS_BAND_1800,
- LC15BTS_BAND_1900,
-};
-
-int lc15bts_rev_get(void);
-int lc15bts_model_get(void);
-int lc15bts_option_get(enum lc15bts_option_type type);
-const char* get_hwversion_desc();
-
-#endif
diff --git a/src/osmo-bts-litecell15/misc/lc15bts_bts.c b/src/osmo-bts-litecell15/misc/lc15bts_bts.c
deleted file mode 100644
index 0343e930..00000000
--- a/src/osmo-bts-litecell15/misc/lc15bts_bts.c
+++ /dev/null
@@ -1,131 +0,0 @@
-/* Copyright (C) 2016 by NuRAN Wireless <support@nuranwireless.com>
- *
- * 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 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/licenses/>.
- *
- */
-
-#include <sys/ioctl.h>
-#include <net/if.h>
-#include <netdb.h>
-#include <ifaddrs.h>
-#include <netinet/in.h>
-#include <netinet/ip.h>
-#include "lc15bts_mgr.h"
-#include "lc15bts_bts.h"
-
-static int check_eth_status(char *dev_name)
-{
- int fd, rc;
- struct ifreq ifr;
-
- fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP);
- if (fd < 0)
- return fd;
-
- memset(&ifr, 0, sizeof(ifr));
- memcpy(&ifr.ifr_name, dev_name, sizeof(ifr.ifr_name));
- rc = ioctl(fd, SIOCGIFFLAGS, &ifr);
- close(fd);
-
- if (rc < 0)
- return rc;
-
- if ((ifr.ifr_flags & IFF_UP) && (ifr.ifr_flags & IFF_RUNNING))
- return 0;
-
- return 1;
-}
-
-void check_bts_led_pattern(uint8_t *led)
-{
- FILE *fp;
- char str[64] = "\0";
- int rc;
-
- /* check for existing of BTS state file */
- if ((fp = fopen("/var/run/osmo-bts/state", "r")) == NULL) {
- led[BLINK_PATTERN_INIT] = 1;
- return;
- }
-
- /* check Ethernet interface status */
- rc = check_eth_status("eth0");
- if (rc > 0) {
- LOGP(DTEMP, LOGL_DEBUG,"External link is DOWN\n");
- led[BLINK_PATTERN_EXT_LINK_MALFUNC] = 1;
- fclose(fp);
- return;
- }
-
- /* check for BTS is still alive */
- if (system("pidof osmo-bts-lc15 > /dev/null")) {
- LOGP(DTEMP, LOGL_DEBUG,"BTS process has stopped\n");
- led[BLINK_PATTERN_INT_PROC_MALFUNC] = 1;
- fclose(fp);
- return;
- }
-
- /* check for BTS state */
- while (fgets(str, 64, fp) != NULL) {
- LOGP(DTEMP, LOGL_DEBUG,"BTS state is %s\n", (strstr(str, "ABIS DOWN") != NULL) ? "DOWN" : "UP");
- if (strstr(str, "ABIS DOWN") != NULL)
- led[BLINK_PATTERN_INT_PROC_MALFUNC] = 1;
- }
- fclose(fp);
-
- return;
-}
-
-int check_sensor_led_pattern( struct lc15bts_mgr_instance *mgr, uint8_t *led)
-{
- if(mgr->alarms.temp_high == 1)
- led[BLINK_PATTERN_TEMP_HIGH] = 1;
-
- if(mgr->alarms.temp_max == 1)
- led[BLINK_PATTERN_TEMP_MAX] = 1;
-
- if(mgr->alarms.supply_low == 1)
- led[BLINK_PATTERN_SUPPLY_VOLT_LOW] = 1;
-
- if(mgr->alarms.supply_min == 1)
- led[BLINK_PATTERN_SUPPLY_VOLT_MIN] = 1;
-
- if(mgr->alarms.vswr_high == 1)
- led[BLINK_PATTERN_VSWR_HIGH] = 1;
-
- if(mgr->alarms.vswr_max == 1)
- led[BLINK_PATTERN_VSWR_MAX] = 1;
-
- if(mgr->alarms.supply_pwr_high == 1)
- led[BLINK_PATTERN_SUPPLY_PWR_HIGH] = 1;
-
- if(mgr->alarms.supply_pwr_max == 1)
- led[BLINK_PATTERN_SUPPLY_PWR_MAX] = 1;
-
- if(mgr->alarms.supply_pwr_max2 == 1)
- led[BLINK_PATTERN_SUPPLY_PWR_MAX2] = 1;
-
- if(mgr->alarms.pa_pwr_high == 1)
- led[BLINK_PATTERN_PA_PWR_HIGH] = 1;
-
- if(mgr->alarms.pa_pwr_max == 1)
- led[BLINK_PATTERN_PA_PWR_MAX] = 1;
-
- if(mgr->alarms.gps_fix_lost == 1)
- led[BLINK_PATTERN_GPS_FIX_LOST] = 1;
-
- return 0;
-}
diff --git a/src/osmo-bts-litecell15/misc/lc15bts_bts.h b/src/osmo-bts-litecell15/misc/lc15bts_bts.h
deleted file mode 100644
index 3918b870..00000000
--- a/src/osmo-bts-litecell15/misc/lc15bts_bts.h
+++ /dev/null
@@ -1,21 +0,0 @@
-#ifndef _LC15BTS_BTS_H_
-#define _LC15BTS_BTS_H_
-
-#include <stdlib.h>
-#include <unistd.h>
-#include <errno.h>
-#include <stdint.h>
-#include <ctype.h>
-#include <string.h>
-#include <sys/signal.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-
-#include <osmo-bts/logging.h>
-
-/* public function prototypes */
-void check_bts_led_pattern(uint8_t *led);
-int check_sensor_led_pattern( struct lc15bts_mgr_instance *mgr, uint8_t *led);
-
-#endif
diff --git a/src/osmo-bts-litecell15/misc/lc15bts_clock.c b/src/osmo-bts-litecell15/misc/lc15bts_clock.c
deleted file mode 100644
index 71701496..00000000
--- a/src/osmo-bts-litecell15/misc/lc15bts_clock.c
+++ /dev/null
@@ -1,260 +0,0 @@
-/* Copyright (C) 2015 by Yves Godin <support@nuranwireless.com>
- *
- * 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 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/licenses/>.
- *
- */
-
-#include <stdio.h>
-#include <stdint.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <fcntl.h>
-
-#include "lc15bts_clock.h"
-
-#define CLKERR_ERR_SYSFS "/var/lc15/clkerr/clkerr1_average"
-#define CLKERR_ACC_SYSFS "/var/lc15/clkerr/clkerr1_average_accuracy"
-#define CLKERR_INT_SYSFS "/var/lc15/clkerr/clkerr1_average_interval"
-#define CLKERR_FLT_SYSFS "/var/lc15/clkerr/clkerr1_fault"
-#define CLKERR_RFS_SYSFS "/var/lc15/clkerr/refresh"
-#define CLKERR_RST_SYSFS "/var/lc15/clkerr/reset"
-
-#define OCXODAC_VAL_SYSFS "/var/lc15/ocxo/voltage"
-#define OCXODAC_ROM_SYSFS "/var/lc15/ocxo/eeprom"
-
-/* clock error */
-static int clkerr_fd_err = -1;
-static int clkerr_fd_accuracy = -1;
-static int clkerr_fd_interval = -1;
-static int clkerr_fd_fault = -1;
-static int clkerr_fd_refresh = -1;
-static int clkerr_fd_reset = -1;
-
-/* ocxo dac */
-static int ocxodac_fd_value = -1;
-static int ocxodac_fd_save = -1;
-
-
-static int sysfs_read_val(int fd, int *val)
-{
- int rc;
- char szVal[32] = {0};
-
- lseek( fd, 0, SEEK_SET );
-
- rc = read(fd, szVal, sizeof(szVal) - 1);
- if (rc < 0) {
- return -errno;
- }
-
- rc = sscanf(szVal, "%d", val);
- if (rc != 1) {
- return -1;
- }
-
- return 0;
-}
-
-static int sysfs_write_val(int fd, int val)
-{
- int n, rc;
- char szVal[32] = {0};
-
- n = sprintf(szVal, "%d", val);
-
- lseek(fd, 0, SEEK_SET);
- rc = write(fd, szVal, n+1);
- if (rc < 0) {
- return -errno;
- }
- return 0;
-}
-
-static int sysfs_write_str(int fd, const char *str)
-{
- int rc;
-
- lseek( fd, 0, SEEK_SET );
- rc = write(fd, str, strlen(str)+1);
- if (rc < 0) {
- return -errno;
- }
- return 0;
-}
-
-
-int lc15bts_clock_err_open(void)
-{
- if (clkerr_fd_err < 0) {
- clkerr_fd_err = open(CLKERR_ERR_SYSFS, O_RDONLY);
- if (clkerr_fd_err < 0) {
- lc15bts_clock_err_close();
- return clkerr_fd_err;
- }
- }
-
- if (clkerr_fd_accuracy < 0) {
- clkerr_fd_accuracy = open(CLKERR_ACC_SYSFS, O_RDONLY);
- if (clkerr_fd_accuracy < 0) {
- lc15bts_clock_err_close();
- return clkerr_fd_accuracy;
- }
- }
-
- if (clkerr_fd_interval < 0) {
- clkerr_fd_interval = open(CLKERR_INT_SYSFS, O_RDONLY);
- if (clkerr_fd_interval < 0) {
- lc15bts_clock_err_close();
- return clkerr_fd_interval;
- }
- }
-
- if (clkerr_fd_fault < 0) {
- clkerr_fd_fault = open(CLKERR_FLT_SYSFS, O_RDONLY);
- if (clkerr_fd_fault < 0) {
- lc15bts_clock_err_close();
- return clkerr_fd_fault;
- }
- }
-
- if (clkerr_fd_refresh < 0) {
- clkerr_fd_refresh = open(CLKERR_RFS_SYSFS, O_WRONLY);
- if (clkerr_fd_refresh < 0) {
- lc15bts_clock_err_close();
- return clkerr_fd_refresh;
- }
- }
-
- if (clkerr_fd_reset < 0) {
- clkerr_fd_reset = open(CLKERR_RST_SYSFS, O_WRONLY);
- if (clkerr_fd_reset < 0) {
- lc15bts_clock_err_close();
- return clkerr_fd_reset;
- }
- }
- return 0;
-}
-
-void lc15bts_clock_err_close(void)
-{
- if (clkerr_fd_err >= 0) {
- close(clkerr_fd_err);
- clkerr_fd_err = -1;
- }
-
- if (clkerr_fd_accuracy >= 0) {
- close(clkerr_fd_accuracy);
- clkerr_fd_accuracy = -1;
- }
-
- if (clkerr_fd_interval >= 0) {
- close(clkerr_fd_interval);
- clkerr_fd_interval = -1;
- }
-
- if (clkerr_fd_fault >= 0) {
- close(clkerr_fd_fault);
- clkerr_fd_fault = -1;
- }
-
- if (clkerr_fd_refresh >= 0) {
- close(clkerr_fd_refresh);
- clkerr_fd_refresh = -1;
- }
-
- if (clkerr_fd_reset >= 0) {
- close(clkerr_fd_reset);
- clkerr_fd_reset = -1;
- }
-}
-
-int lc15bts_clock_err_reset(void)
-{
- return sysfs_write_val(clkerr_fd_reset, 1);
-}
-
-int lc15bts_clock_err_get(int *fault, int *error_ppt,
- int *accuracy_ppq, int *interval_sec)
-{
- int rc;
-
- rc = sysfs_write_str(clkerr_fd_refresh, "once");
- if (rc < 0) {
- return -1;
- }
-
- rc = sysfs_read_val(clkerr_fd_fault, fault);
- rc |= sysfs_read_val(clkerr_fd_err, error_ppt);
- rc |= sysfs_read_val(clkerr_fd_accuracy, accuracy_ppq);
- rc |= sysfs_read_val(clkerr_fd_interval, interval_sec);
- if (rc) {
- return -1;
- }
- return 0;
-}
-
-
-int lc15bts_clock_dac_open(void)
-{
- if (ocxodac_fd_value < 0) {
- ocxodac_fd_value = open(OCXODAC_VAL_SYSFS, O_RDWR);
- if (ocxodac_fd_value < 0) {
- lc15bts_clock_dac_close();
- return ocxodac_fd_value;
- }
- }
-
- if (ocxodac_fd_save < 0) {
- ocxodac_fd_save = open(OCXODAC_ROM_SYSFS, O_WRONLY);
- if (ocxodac_fd_save < 0) {
- lc15bts_clock_dac_close();
- return ocxodac_fd_save;
- }
- }
- return 0;
-}
-
-void lc15bts_clock_dac_close(void)
-{
- if (ocxodac_fd_value >= 0) {
- close(ocxodac_fd_value);
- ocxodac_fd_value = -1;
- }
-
- if (ocxodac_fd_save >= 0) {
- close(ocxodac_fd_save);
- ocxodac_fd_save = -1;
- }
-}
-
-int lc15bts_clock_dac_get(int *dac_value)
-{
- return sysfs_read_val(ocxodac_fd_value, dac_value);
-}
-
-int lc15bts_clock_dac_set(int dac_value)
-{
- return sysfs_write_val(ocxodac_fd_value, dac_value);
-}
-
-int lc15bts_clock_dac_save(void)
-{
- return sysfs_write_val(ocxodac_fd_save, 1);
-}
-
-
diff --git a/src/osmo-bts-litecell15/misc/lc15bts_clock.h b/src/osmo-bts-litecell15/misc/lc15bts_clock.h
deleted file mode 100644
index d9673598..00000000
--- a/src/osmo-bts-litecell15/misc/lc15bts_clock.h
+++ /dev/null
@@ -1,16 +0,0 @@
-#ifndef _LC15BTS_CLOCK_H
-#define _LC15BTS_CLOCK_H
-
-int lc15bts_clock_err_open(void);
-void lc15bts_clock_err_close(void);
-int lc15bts_clock_err_reset(void);
-int lc15bts_clock_err_get(int *fault, int *error_ppt,
- int *accuracy_ppq, int *interval_sec);
-
-int lc15bts_clock_dac_open(void);
-void lc15bts_clock_dac_close(void);
-int lc15bts_clock_dac_get(int *dac_value);
-int lc15bts_clock_dac_set(int dac_value);
-int lc15bts_clock_dac_save(void);
-
-#endif
diff --git a/src/osmo-bts-litecell15/misc/lc15bts_led.c b/src/osmo-bts-litecell15/misc/lc15bts_led.c
deleted file mode 100644
index a93d3fb0..00000000
--- a/src/osmo-bts-litecell15/misc/lc15bts_led.c
+++ /dev/null
@@ -1,333 +0,0 @@
-/* Copyright (C) 2016 by NuRAN Wireless <support@nuranwireless.com>
- *
- * 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 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/licenses/>.
- *
- */
-#include "lc15bts_led.h"
-#include "lc15bts_bts.h"
-#include <osmocom/core/talloc.h>
-#include <osmocom/core/linuxlist.h>
-
-static struct lc15bts_led led_entries[] = {
- {
- .name = "led0",
- .fullname = "led red",
- .path = "/var/lc15/leds/led0/brightness"
- },
- {
- .name = "led1",
- .fullname = "led green",
- .path = "/var/lc15/leds/led1/brightness"
- }
-};
-
-static const struct value_string lc15bts_led_strs[] = {
- { LC15BTS_LED_RED, "LED red" },
- { LC15BTS_LED_GREEN, "LED green" },
- { LC15BTS_LED_ORANGE, "LED orange" },
- { LC15BTS_LED_OFF, "LED off" },
- { 0, NULL }
-};
-
-static uint8_t led_priority[] = {
- BLINK_PATTERN_INIT,
- BLINK_PATTERN_INT_PROC_MALFUNC,
- BLINK_PATTERN_SUPPLY_PWR_MAX,
- BLINK_PATTERN_PA_PWR_MAX,
- BLINK_PATTERN_VSWR_MAX,
- BLINK_PATTERN_SUPPLY_VOLT_MIN,
- BLINK_PATTERN_TEMP_MAX,
- BLINK_PATTERN_SUPPLY_PWR_MAX2,
- BLINK_PATTERN_EXT_LINK_MALFUNC,
- BLINK_PATTERN_SUPPLY_VOLT_LOW,
- BLINK_PATTERN_TEMP_HIGH,
- BLINK_PATTERN_VSWR_HIGH,
- BLINK_PATTERN_SUPPLY_PWR_HIGH,
- BLINK_PATTERN_PA_PWR_HIGH,
- BLINK_PATTERN_GPS_FIX_LOST,
- BLINK_PATTERN_NORMAL
-};
-
-
-char *blink_pattern_command[] = BLINK_PATTERN_COMMAND;
-
-static int lc15bts_led_write(char *path, char *str)
-{
- int fd;
-
- if ((fd = open(path, O_WRONLY)) == -1)
- {
- return 0;
- }
-
- write(fd, str, strlen(str)+1);
- close(fd);
- return 1;
-}
-
-static void led_set_red()
-{
- lc15bts_led_write(led_entries[0].path, "1");
- lc15bts_led_write(led_entries[1].path, "0");
-}
-
-static void led_set_green()
-{
- lc15bts_led_write(led_entries[0].path, "0");
- lc15bts_led_write(led_entries[1].path, "1");
-}
-
-static void led_set_orange()
-{
- lc15bts_led_write(led_entries[0].path, "1");
- lc15bts_led_write(led_entries[1].path, "1");
-}
-
-static void led_set_off()
-{
- lc15bts_led_write(led_entries[0].path, "0");
- lc15bts_led_write(led_entries[1].path, "0");
-}
-
-static void led_sleep( struct lc15bts_mgr_instance *mgr, struct lc15bts_led_timer *led_timer, void (*led_timer_cb)(void *_data)) {
- /* Cancel any pending timer */
- osmo_timer_del(&led_timer->timer);
- /* Start LED timer */
- led_timer->timer.cb = led_timer_cb;
- led_timer->timer.data = mgr;
- mgr->lc15bts_leds.active_timer = led_timer->idx;
- osmo_timer_schedule(&led_timer->timer, led_timer->param.sleep_sec, led_timer->param.sleep_usec);
- LOGP(DTEMP, LOGL_DEBUG,"%s timer scheduled for %d sec + %d usec\n",
- get_value_string(lc15bts_led_strs, led_timer->idx),
- led_timer->param.sleep_sec,
- led_timer->param.sleep_usec);
-
- switch (led_timer->idx) {
- case LC15BTS_LED_RED:
- led_set_red();
- break;
- case LC15BTS_LED_GREEN:
- led_set_green();
- break;
- case LC15BTS_LED_ORANGE:
- led_set_orange();
- break;
- case LC15BTS_LED_OFF:
- led_set_off();
- break;
- default:
- led_set_off();
- }
-}
-
-static void led_sleep_cb(void *_data) {
- struct lc15bts_mgr_instance *mgr = _data;
- struct lc15bts_led_timer_list *led_list;
-
- /* make sure the timer list is not empty */
- if (llist_empty(&mgr->lc15bts_leds.list))
- return;
-
- llist_for_each_entry(led_list, &mgr->lc15bts_leds.list, list) {
- if (led_list->led_timer.idx == mgr->lc15bts_leds.active_timer) {
- LOGP(DTEMP, LOGL_DEBUG,"Delete expired %s timer %d sec + %d usec\n",
- get_value_string(lc15bts_led_strs, led_list->led_timer.idx),
- led_list->led_timer.param.sleep_sec,
- led_list->led_timer.param.sleep_usec);
-
- /* Delete current timer */
- osmo_timer_del(&led_list->led_timer.timer);
- /* Rotate the timer list */
- llist_move_tail(&led_list->list, &mgr->lc15bts_leds.list);
- break;
- }
- }
-
- /* Execute next timer */
- led_list = llist_first_entry(&mgr->lc15bts_leds.list, struct lc15bts_led_timer_list, list);
- if (led_list) {
- LOGP(DTEMP, LOGL_DEBUG,"Execute %s timer %d sec + %d usec, total entries=%d\n",
- get_value_string(lc15bts_led_strs, led_list->led_timer.idx),
- led_list->led_timer.param.sleep_sec,
- led_list->led_timer.param.sleep_usec,
- llist_count(&mgr->lc15bts_leds.list));
-
- led_sleep(mgr, &led_list->led_timer, led_sleep_cb);
- }
-
-}
-
-static void delete_led_timer_entries(struct lc15bts_mgr_instance *mgr)
-{
- struct lc15bts_led_timer_list *led_list, *led_list2;
-
- if (llist_empty(&mgr->lc15bts_leds.list))
- return;
-
- llist_for_each_entry_safe(led_list, led_list2, &mgr->lc15bts_leds.list, list) {
- /* Delete the timer in list */
- if (led_list) {
- LOGP(DTEMP, LOGL_DEBUG,"Delete %s timer entry from list, %d sec + %d usec\n",
- get_value_string(lc15bts_led_strs, led_list->led_timer.idx),
- led_list->led_timer.param.sleep_sec,
- led_list->led_timer.param.sleep_usec);
-
- /* Delete current timer */
- osmo_timer_del(&led_list->led_timer.timer);
- llist_del(&led_list->list);
- talloc_free(led_list);
- }
- }
- return;
-}
-
-static int add_led_timer_entry(struct lc15bts_mgr_instance *mgr, char *cmdstr)
-{
- double sec, int_sec, frac_sec;
- struct lc15bts_sleep_time led_param;
-
- led_param.sleep_sec = 0;
- led_param.sleep_usec = 0;
-
- if (strstr(cmdstr, "set red") != NULL)
- mgr->lc15bts_leds.led_idx = LC15BTS_LED_RED;
- else if (strstr(cmdstr, "set green") != NULL)
- mgr->lc15bts_leds.led_idx = LC15BTS_LED_GREEN;
- else if (strstr(cmdstr, "set orange") != NULL)
- mgr->lc15bts_leds.led_idx = LC15BTS_LED_ORANGE;
- else if (strstr(cmdstr, "set off") != NULL)
- mgr->lc15bts_leds.led_idx = LC15BTS_LED_OFF;
- else if (strstr(cmdstr, "sleep") != NULL) {
- sec = atof(cmdstr + 6);
- /* split time into integer and fractional of seconds */
- frac_sec = modf(sec, &int_sec) * 1000000.0;
- led_param.sleep_sec = (int)int_sec;
- led_param.sleep_usec = (int)frac_sec;
-
- if ((mgr->lc15bts_leds.led_idx >= LC15BTS_LED_RED) && (mgr->lc15bts_leds.led_idx < _LC15BTS_LED_MAX)) {
- struct lc15bts_led_timer_list *led_list;
-
- /* allocate timer entry */
- led_list = talloc_zero(tall_mgr_ctx, struct lc15bts_led_timer_list);
- if (led_list) {
- led_list->led_timer.idx = mgr->lc15bts_leds.led_idx;
- led_list->led_timer.param.sleep_sec = led_param.sleep_sec;
- led_list->led_timer.param.sleep_usec = led_param.sleep_usec;
- llist_add_tail(&led_list->list, &mgr->lc15bts_leds.list);
-
- LOGP(DTEMP, LOGL_DEBUG,"Add %s timer to list, %d sec + %d usec, total entries=%d\n",
- get_value_string(lc15bts_led_strs, mgr->lc15bts_leds.led_idx),
- led_list->led_timer.param.sleep_sec,
- led_list->led_timer.param.sleep_usec,
- llist_count(&mgr->lc15bts_leds.list));
- }
- }
- } else
- return -1;
-
- return 0;
-}
-
-static int parse_led_pattern(char *pattern, struct lc15bts_mgr_instance *mgr)
-{
- char str[1024];
- char *pstr;
- char *sep;
- int rc = 0;
-
- strcpy(str, pattern);
- pstr = str;
- while ((sep = strsep(&pstr, ";")) != NULL) {
- rc = add_led_timer_entry(mgr, sep);
- if (rc < 0) {
- break;
- }
-
- }
- return rc;
-}
-
-/*** led interface ***/
-
-void led_set(struct lc15bts_mgr_instance *mgr, int pattern_id)
-{
- int rc;
- struct lc15bts_led_timer_list *led_list;
-
- if (pattern_id > BLINK_PATTERN_MAX_ITEM - 1) {
- LOGP(DTEMP, LOGL_ERROR, "Invalid LED pattern : %d. LED pattern must be between %d..%d\n",
- pattern_id,
- BLINK_PATTERN_POWER_ON,
- BLINK_PATTERN_MAX_ITEM - 1);
- return;
- }
- if (pattern_id == mgr->lc15bts_leds.last_pattern_id)
- return;
-
- mgr->lc15bts_leds.last_pattern_id = pattern_id;
-
- LOGP(DTEMP, LOGL_NOTICE, "blink pattern command : %d\n", pattern_id);
- LOGP(DTEMP, LOGL_NOTICE, "%s\n", blink_pattern_command[pattern_id]);
-
- /* Empty existing LED timer in the list */
- delete_led_timer_entries(mgr);
-
- /* parse LED pattern */
- rc = parse_led_pattern(blink_pattern_command[pattern_id], mgr);
- if (rc < 0) {
- LOGP(DTEMP, LOGL_ERROR,"LED pattern not found or invalid LED pattern\n");
- return;
- }
-
- /* make sure the timer list is not empty */
- if (llist_empty(&mgr->lc15bts_leds.list))
- return;
-
- /* Start the first LED timer in the list */
- led_list = llist_first_entry(&mgr->lc15bts_leds.list, struct lc15bts_led_timer_list, list);
- if (led_list) {
- LOGP(DTEMP, LOGL_DEBUG,"Execute timer %s for %d sec + %d usec\n",
- get_value_string(lc15bts_led_strs, led_list->led_timer.idx),
- led_list->led_timer.param.sleep_sec,
- led_list->led_timer.param.sleep_usec);
-
- led_sleep(mgr, &led_list->led_timer, led_sleep_cb);
- }
-
-}
-
-void select_led_pattern(struct lc15bts_mgr_instance *mgr)
-{
- int i;
- uint8_t led[BLINK_PATTERN_MAX_ITEM] = {0};
-
- /* set normal LED pattern at first */
- led[BLINK_PATTERN_NORMAL] = 1;
-
- /* check on-board sensors for new LED pattern */
- check_sensor_led_pattern(mgr, led);
-
- /* check BTS status for new LED pattern */
- check_bts_led_pattern(led);
-
- /* check by priority */
- for (i = 0; i < sizeof(led_priority)/sizeof(uint8_t); i++) {
- if(led[led_priority[i]] == 1) {
- led_set(mgr, led_priority[i]);
- break;
- }
- }
-}
diff --git a/src/osmo-bts-litecell15/misc/lc15bts_led.h b/src/osmo-bts-litecell15/misc/lc15bts_led.h
deleted file mode 100644
index b6d9d28b..00000000
--- a/src/osmo-bts-litecell15/misc/lc15bts_led.h
+++ /dev/null
@@ -1,22 +0,0 @@
-#ifndef _LC15BTS_LED_H
-#define _LC15BTS_LED_H
-
-#include <stdint.h>
-#include <unistd.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <math.h>
-#include <sys/stat.h>
-
-#include <osmo-bts/logging.h>
-#include <osmocom/core/timer.h>
-#include <osmocom/core/utils.h>
-
-#include "lc15bts_mgr.h"
-
-/* public function prototypes */
-void led_set(struct lc15bts_mgr_instance *mgr, int pattern_id);
-
-void select_led_pattern(struct lc15bts_mgr_instance *mgr);
-
-#endif
diff --git a/src/osmo-bts-litecell15/misc/lc15bts_mgr.c b/src/osmo-bts-litecell15/misc/lc15bts_mgr.c
deleted file mode 100644
index da21c9d0..00000000
--- a/src/osmo-bts-litecell15/misc/lc15bts_mgr.c
+++ /dev/null
@@ -1,366 +0,0 @@
-/* Main program for NuRAN Wireless Litecell 1.5 BTS management daemon */
-
-/* Copyright (C) 2015 by Yves Godin <support@nuranwireless.com>
- *
- * Based on sysmoBTS:
- * sysmobts_mgr.c
- * (C) 2012 by Harald Welte <laforge@gnumonks.org>
- * (C) 2014 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 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 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/licenses/>.
- *
- */
-
-#include <stdint.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <getopt.h>
-#include <limits.h>
-#include <sys/signal.h>
-#include <sys/stat.h>
-
-#include <osmocom/core/talloc.h>
-#include <osmocom/core/application.h>
-#include <osmocom/core/timer.h>
-#include <osmocom/core/msgb.h>
-#include <osmocom/vty/telnet_interface.h>
-#include <osmocom/vty/logging.h>
-#include <osmocom/vty/ports.h>
-
-#include "misc/lc15bts_misc.h"
-#include "misc/lc15bts_mgr.h"
-#include "misc/lc15bts_par.h"
-#include "misc/lc15bts_bid.h"
-#include "misc/lc15bts_power.h"
-#include "misc/lc15bts_swd.h"
-
-#include "lc15bts_led.h"
-
-static int no_rom_write = 0;
-static int daemonize = 0;
-void *tall_mgr_ctx;
-
-/* every 6 hours means 365*4 = 1460 rom writes per year (max) */
-#define SENSOR_TIMER_SECS (6 * 3600)
-
-/* every 1 hours means 365*24 = 8760 rom writes per year (max) */
-#define HOURS_TIMER_SECS (1 * 3600)
-
-
-/* the initial state */
-static struct lc15bts_mgr_instance manager = {
- .config_file = "lc15bts-mgr.cfg",
- .temp = {
- .supply_temp_limit = {
- .thresh_warn_max = 80,
- .thresh_crit_max = 85,
- .thresh_warn_min = -40,
- },
- .soc_temp_limit = {
- .thresh_warn_max = 95,
- .thresh_crit_max = 100,
- .thresh_warn_min = -40,
- },
- .fpga_temp_limit = {
- .thresh_warn_max = 95,
- .thresh_crit_max = 100,
- .thresh_warn_min = -40,
- },
- .rmsdet_temp_limit = {
- .thresh_warn_max = 80,
- .thresh_crit_max = 85,
- .thresh_warn_min = -40,
- },
- .ocxo_temp_limit = {
- .thresh_warn_max = 80,
- .thresh_crit_max = 85,
- .thresh_warn_min = -40,
- },
- .tx0_temp_limit = {
- .thresh_warn_max = 80,
- .thresh_crit_max = 85,
- .thresh_warn_min = -20,
- },
- .tx1_temp_limit = {
- .thresh_warn_max = 80,
- .thresh_crit_max = 85,
- .thresh_warn_min = -20,
- },
- .pa0_temp_limit = {
- .thresh_warn_max = 80,
- .thresh_crit_max = 85,
- .thresh_warn_min = -40,
- },
- .pa1_temp_limit = {
- .thresh_warn_max = 80,
- .thresh_crit_max = 85,
- .thresh_warn_min = -40,
- }
- },
- .volt = {
- .supply_volt_limit = {
- .thresh_warn_max = 30000,
- .thresh_crit_max = 30500,
- .thresh_warn_min = 19000,
- .thresh_crit_min = 17500,
- }
- },
- .pwr = {
- .supply_pwr_limit = {
- .thresh_warn_max = 110,
- .thresh_crit_max = 120,
- },
- .pa0_pwr_limit = {
- .thresh_warn_max = 50,
- .thresh_crit_max = 60,
- },
- .pa1_pwr_limit = {
- .thresh_warn_max = 50,
- .thresh_crit_max = 60,
- }
- },
- .vswr = {
- .tx0_vswr_limit = {
- .thresh_warn_max = 3000,
- .thresh_crit_max = 5000,
- },
- .tx1_vswr_limit = {
- .thresh_warn_max = 3000,
- .thresh_crit_max = 5000,
- }
- },
- .gps = {
- .gps_fix_limit = {
- .thresh_warn_max = 7,
- }
- },
- .state = {
- .action_norm = SENSOR_ACT_NORM_PA0_ON | SENSOR_ACT_NORM_PA1_ON,
- .action_warn = 0,
- .action_crit = 0,
- .action_comb = 0,
- .state = STATE_NORMAL,
- }
-};
-
-static struct osmo_timer_list sensor_timer;
-static void check_sensor_timer_cb(void *unused)
-{
- lc15bts_check_temp(no_rom_write);
- lc15bts_check_power(no_rom_write);
- lc15bts_check_vswr(no_rom_write);
- osmo_timer_schedule(&sensor_timer, SENSOR_TIMER_SECS, 0);
- /* TODO checks if lc15bts_check_temp/lc15bts_check_power/lc15bts_check_vswr went ok */
- lc15bts_swd_event(&manager, SWD_CHECK_SENSOR);
-}
-
-static struct osmo_timer_list hours_timer;
-static void hours_timer_cb(void *unused)
-{
- lc15bts_update_hours(no_rom_write);
-
- osmo_timer_schedule(&hours_timer, HOURS_TIMER_SECS, 0);
- /* TODO: validates if lc15bts_update_hours went correctly */
- lc15bts_swd_event(&manager, SWD_UPDATE_HOURS);
-}
-
-static void print_help(void)
-{
- printf("lc15bts-mgr [-nsD] [-d cat]\n");
- printf(" -n Do not write to ROM\n");
- printf(" -s Disable color\n");
- printf(" -d CAT enable debugging\n");
- printf(" -D daemonize\n");
- printf(" -c Specify the filename of the config file\n");
-}
-
-static int parse_options(int argc, char **argv)
-{
- int opt;
-
- while ((opt = getopt(argc, argv, "nhsd:c:")) != -1) {
- switch (opt) {
- case 'n':
- no_rom_write = 1;
- break;
- case 'h':
- print_help();
- return -1;
- case 's':
- log_set_use_color(osmo_stderr_target, 0);
- break;
- case 'd':
- log_parse_category_mask(osmo_stderr_target, optarg);
- break;
- case 'D':
- daemonize = 1;
- break;
- case 'c':
- manager.config_file = optarg;
- break;
- default:
- return -1;
- }
- }
-
- return 0;
-}
-
-static void signal_handler(int signal)
-{
- fprintf(stderr, "signal %u received\n", signal);
-
- switch (signal) {
- case SIGINT:
- case SIGTERM:
- lc15bts_check_temp(no_rom_write);
- lc15bts_check_power(no_rom_write);
- lc15bts_check_vswr(no_rom_write);
- lc15bts_update_hours(no_rom_write);
- exit(0);
- break;
- case SIGABRT:
- case SIGUSR1:
- case SIGUSR2:
- talloc_report_full(tall_mgr_ctx, stderr);
- break;
- default:
- break;
- }
-}
-
-static struct log_info_cat mgr_log_info_cat[] = {
- [DTEMP] = {
- .name = "DTEMP",
- .description = "Temperature monitoring",
- .color = "\033[1;35m",
- .enabled = 1, .loglevel = LOGL_NOTICE,
- },
- [DFW] = {
- .name = "DFW",
- .description = "Firmware management",
- .color = "\033[1;36m",
- .enabled = 1, .loglevel = LOGL_NOTICE,
- },
- [DFIND] = {
- .name = "DFIND",
- .description = "ipaccess-find handling",
- .color = "\033[1;37m",
- .enabled = 1, .loglevel = LOGL_NOTICE,
- },
- [DCALIB] = {
- .name = "DCALIB",
- .description = "Calibration handling",
- .color = "\033[1;37m",
- .enabled = 1, .loglevel = LOGL_NOTICE,
- },
- [DSWD] = {
- .name = "DSWD",
- .description = "Software Watchdog",
- .color = "\033[1;37m",
- .enabled = 1, .loglevel = LOGL_NOTICE,
- },
-};
-
-static const struct log_info mgr_log_info = {
- .cat = mgr_log_info_cat,
- .num_cat = ARRAY_SIZE(mgr_log_info_cat),
-};
-
-int main(int argc, char **argv)
-{
- int rc;
-
- tall_mgr_ctx = talloc_named_const(NULL, 1, "bts manager");
- msgb_talloc_ctx_init(tall_mgr_ctx, 0);
-
- osmo_init_logging2(tall_mgr_ctx, &mgr_log_info);
-
- osmo_init_ignore_signals();
- signal(SIGINT, &signal_handler);
- signal(SIGTERM, &signal_handler);
- signal(SIGUSR1, &signal_handler);
- signal(SIGUSR2, &signal_handler);
-
- rc = parse_options(argc, argv);
- if (rc < 0)
- exit(2);
-
- lc15bts_mgr_vty_init();
- logging_vty_add_cmds();
- rc = lc15bts_mgr_parse_config(&manager);
- if (rc < 0) {
- LOGP(DFIND, LOGL_FATAL, "Cannot parse config file\n");
- exit(1);
- }
-
- rc = telnet_init(tall_mgr_ctx, NULL, OSMO_VTY_PORT_BTSMGR);
- if (rc < 0) {
- fprintf(stderr, "Error initializing telnet\n");
- exit(1);
- }
-
- INIT_LLIST_HEAD(&manager.lc15bts_leds.list);
- INIT_LLIST_HEAD(&manager.alarms.list);
-
- /* Initialize the service watchdog notification for SWD_LAST event(s) */
- if (lc15bts_swd_init(&manager, (int)(SWD_LAST)) != 0)
- exit(3);
-
- /* start temperature check timer */
- sensor_timer.cb = check_sensor_timer_cb;
- check_sensor_timer_cb(NULL);
-
- /* start operational hours timer */
- hours_timer.cb = hours_timer_cb;
- hours_timer_cb(NULL);
-
- /* Enable the PAs */
- rc = lc15bts_power_set(LC15BTS_POWER_PA0, 1);
- if (rc < 0) {
- exit(3);
- }
-
- rc = lc15bts_power_set(LC15BTS_POWER_PA1, 1);
- if (rc < 0) {
- exit(3);
- }
-
- /* handle broadcast messages for ipaccess-find */
- if (lc15bts_mgr_nl_init() != 0)
- exit(3);
-
- /* Initialize the sensor control */
- lc15bts_mgr_sensor_init(&manager);
-
- if (lc15bts_mgr_calib_init(&manager) != 0)
- exit(3);
-
- if (daemonize) {
- rc = osmo_daemonize();
- if (rc < 0) {
- perror("Error during daemonize");
- exit(1);
- }
- }
-
- while (1) {
- log_reset_context();
- osmo_select_main(0);
- lc15bts_swd_event(&manager, SWD_MAINLOOP);
- }
-}
diff --git a/src/osmo-bts-litecell15/misc/lc15bts_mgr.h b/src/osmo-bts-litecell15/misc/lc15bts_mgr.h
deleted file mode 100644
index 4bfbdbc9..00000000
--- a/src/osmo-bts-litecell15/misc/lc15bts_mgr.h
+++ /dev/null
@@ -1,422 +0,0 @@
-#ifndef _LC15BTS_MGR_H
-#define _LC15BTS_MGR_H
-
-#include <osmocom/vty/vty.h>
-#include <osmocom/vty/command.h>
-
-#include <osmocom/core/select.h>
-#include <osmocom/core/timer.h>
-
-#include <stdint.h>
-
-#define LC15BTS_SENSOR_TIMER_DURATION 60
-#define LC15BTS_PREVENT_TIMER_DURATION 15 * 60
-#define LC15BTS_PREVENT_TIMER_SHORT_DURATION 5 * 60
-#define LC15BTS_PREVENT_TIMER_NONE 0
-#define LC15BTS_PREVENT_RETRY INT_MAX - 1
-
-enum BLINK_PATTERN {
- BLINK_PATTERN_POWER_ON = 0, //hardware set
- BLINK_PATTERN_INIT,
- BLINK_PATTERN_NORMAL,
- BLINK_PATTERN_EXT_LINK_MALFUNC,
- BLINK_PATTERN_INT_PROC_MALFUNC,
- BLINK_PATTERN_SUPPLY_VOLT_LOW,
- BLINK_PATTERN_SUPPLY_VOLT_MIN,
- BLINK_PATTERN_VSWR_HIGH,
- BLINK_PATTERN_VSWR_MAX,
- BLINK_PATTERN_TEMP_HIGH,
- BLINK_PATTERN_TEMP_MAX,
- BLINK_PATTERN_SUPPLY_PWR_HIGH,
- BLINK_PATTERN_SUPPLY_PWR_MAX,
- BLINK_PATTERN_SUPPLY_PWR_MAX2,
- BLINK_PATTERN_PA_PWR_HIGH,
- BLINK_PATTERN_PA_PWR_MAX,
- BLINK_PATTERN_GPS_FIX_LOST,
- BLINK_PATTERN_MAX_ITEM
-};
-
-#define BLINK_PATTERN_COMMAND {\
- "set red; sleep 5.0",\
- "set orange; sleep 5.0",\
- "set green; sleep 2.5; set off; sleep 2.5",\
- "set red; sleep 0.5; set off; sleep 0.5",\
- "set red; sleep 2.5; set off; sleep 2.5",\
- "set green; sleep 2.5; set off; sleep 0.5; set red; sleep 0.5; set off; sleep 0.5; set green; sleep 0.5; set off; sleep 0.5",\
- "set red; sleep 2.5; set off; sleep 0.5; set red; sleep 0.5; set off; sleep 0.5; set green; sleep 0.5; set off; sleep 0.5 ",\
- "set green; sleep 2.5; set off; sleep 0.5; set orange; sleep 0.5; set off; sleep 0.5; set orange; sleep 0.5; set off; sleep 0.5",\
- "set red; sleep 2.5; set off; sleep 0.5; set orange; sleep 0.5; set off; sleep 0.5; set orange; sleep 0.5; set off; sleep 0.5",\
- "set orange; sleep 2.5; set off; sleep 0.5; set red; sleep 0.5; set off; sleep 0.5; set red; sleep 0.5; set off; sleep 0.5 ",\
- "set red; sleep 2.5; set off; sleep 0.5; set red; sleep 0.5; set off; sleep 0.5; set red; sleep 0.5; set off; sleep 0.5",\
- "set green; sleep 2.5; set off; sleep 0.5; set orange; sleep 0.5; set off; sleep 0.5; set red; sleep 0.5; set off; sleep 0.5",\
- "set red; sleep 2.5; set off; sleep 0.5; set orange; sleep 0.5; set off; sleep 0.5; set red; sleep 0.5; set off; sleep 0.5",\
- "set orange; sleep 2.5; set off; sleep 0.5; set orange; sleep 0.5; set off; sleep 0.5; set red; sleep 0.5; set off; sleep 0.5",\
- "set green; sleep 2.5; set off; sleep 0.5; set red; sleep 0.5; set off; sleep 0.5; set orange; sleep 0.5; set off; sleep 0.5",\
- "set red; sleep 2.5; set off; sleep 0.5; set red; sleep 0.5; set off; sleep 0.5; set orange; sleep 0.5; set off; sleep 0.5",\
- "set green; sleep 2.5; set off; sleep 0.5; set green; sleep 0.5; set off; sleep 0.5; set orange; sleep 0.5; set off; sleep 0.5",\
-}
-
-enum {
- DTEMP,
- DFW,
- DFIND,
- DCALIB,
- DSWD,
-};
-
-// TODO NTQD: Define new actions like reducing output power, limit ARM core speed, shutdown second TRX/PA, ...
-enum {
-#if 0
- SENSOR_ACT_PWR_CONTRL = 0x1,
-#endif
- SENSOR_ACT_PA0_OFF = 0x2,
- SENSOR_ACT_PA1_OFF = 0x4,
- SENSOR_ACT_BTS_SRV_OFF = 0x10,
-};
-
-/* actions only for normal state */
-enum {
-#if 0
- SENSOR_ACT_NORM_PW_CONTRL = 0x1,
-#endif
- SENSOR_ACT_NORM_PA0_ON = 0x2,
- SENSOR_ACT_NORM_PA1_ON = 0x4,
- SENSOR_ACT_NORM_BTS_SRV_ON= 0x10,
-};
-
-enum lc15bts_sensor_state {
- STATE_NORMAL, /* Everything is fine */
- STATE_WARNING_HYST, /* Go back to normal next? */
- STATE_WARNING, /* We are above the warning threshold */
- STATE_CRITICAL, /* We have an issue. Wait for below warning */
-};
-
-enum lc15bts_leds_name {
- LC15BTS_LED_RED = 0,
- LC15BTS_LED_GREEN,
- LC15BTS_LED_ORANGE,
- LC15BTS_LED_OFF,
- _LC15BTS_LED_MAX
-};
-
-struct lc15bts_led{
- char *name;
- char *fullname;
- char *path;
-};
-
-/**
- * Temperature Limits. We separate from a threshold
- * that will generate a warning and one that is so
- * severe that an action will be taken.
- */
-struct lc15bts_temp_limit {
- int thresh_warn_max;
- int thresh_crit_max;
- int thresh_warn_min;
-};
-
-struct lc15bts_volt_limit {
- int thresh_warn_max;
- int thresh_crit_max;
- int thresh_warn_min;
- int thresh_crit_min;
-};
-
-struct lc15bts_pwr_limit {
- int thresh_warn_max;
- int thresh_crit_max;
-};
-
-struct lc15bts_vswr_limit {
- int thresh_warn_max;
- int thresh_crit_max;
-};
-
-struct lc15bts_gps_fix_limit {
- int thresh_warn_max;
-};
-
-struct lc15bts_sleep_time {
- int sleep_sec;
- int sleep_usec;
-};
-
-struct lc15bts_led_timer {
- uint8_t idx;
- struct osmo_timer_list timer;
- struct lc15bts_sleep_time param;
-};
-
-struct lc15bts_led_timer_list {
- struct llist_head list;
- struct lc15bts_led_timer led_timer;
-};
-
-struct lc15bts_preventive_list {
- struct llist_head list;
- struct lc15bts_sleep_time param;
- int action_flag;
-};
-
-enum mgr_vty_node {
- MGR_NODE = _LAST_OSMOVTY_NODE + 1,
-
- ACT_NORM_NODE,
- ACT_WARN_NODE,
- ACT_CRIT_NODE,
- LIMIT_SUPPLY_TEMP_NODE,
- LIMIT_SOC_NODE,
- LIMIT_FPGA_NODE,
- LIMIT_RMSDET_NODE,
- LIMIT_OCXO_NODE,
- LIMIT_TX0_TEMP_NODE,
- LIMIT_TX1_TEMP_NODE,
- LIMIT_PA0_TEMP_NODE,
- LIMIT_PA1_TEMP_NODE,
- LIMIT_SUPPLY_VOLT_NODE,
- LIMIT_TX0_VSWR_NODE,
- LIMIT_TX1_VSWR_NODE,
- LIMIT_SUPPLY_PWR_NODE,
- LIMIT_PA0_PWR_NODE,
- LIMIT_PA1_PWR_NODE,
- LIMIT_GPS_FIX_NODE,
-};
-
-enum mgr_vty_limit_type {
- MGR_LIMIT_TYPE_TEMP = 0,
- MGR_LIMIT_TYPE_VOLT,
- MGR_LIMIT_TYPE_VSWR,
- MGR_LIMIT_TYPE_PWR,
- _MGR_LIMIT_TYPE_MAX,
-};
-
-struct lc15bts_mgr_instance {
- const char *config_file;
-
- struct {
- struct lc15bts_temp_limit supply_temp_limit;
- struct lc15bts_temp_limit soc_temp_limit;
- struct lc15bts_temp_limit fpga_temp_limit;
- struct lc15bts_temp_limit rmsdet_temp_limit;
- struct lc15bts_temp_limit ocxo_temp_limit;
- struct lc15bts_temp_limit tx0_temp_limit;
- struct lc15bts_temp_limit tx1_temp_limit;
- struct lc15bts_temp_limit pa0_temp_limit;
- struct lc15bts_temp_limit pa1_temp_limit;
- } temp;
-
- struct {
- struct lc15bts_volt_limit supply_volt_limit;
- } volt;
-
- struct {
- struct lc15bts_pwr_limit supply_pwr_limit;
- struct lc15bts_pwr_limit pa0_pwr_limit;
- struct lc15bts_pwr_limit pa1_pwr_limit;
- } pwr;
-
- struct {
- struct lc15bts_vswr_limit tx0_vswr_limit;
- struct lc15bts_vswr_limit tx1_vswr_limit;
- int tx0_last_vswr;
- int tx1_last_vswr;
- } vswr;
-
- struct {
- struct lc15bts_gps_fix_limit gps_fix_limit;
- time_t last_update;
- } gps;
-
- struct {
- int action_norm;
- int action_warn;
- int action_crit;
- int action_comb;
-
- enum lc15bts_sensor_state state;
- } state;
-
- struct {
- int state;
- int calib_from_loop;
- struct osmo_timer_list calib_timeout;
- } calib;
-
- struct {
- int state;
- int swd_from_loop;
- unsigned long long int swd_events;
- unsigned long long int swd_events_cache;
- unsigned long long int swd_eventmasks;
- int num_events;
- struct osmo_timer_list swd_timeout;
- } swd;
-
- struct {
- uint8_t led_idx;
- uint8_t last_pattern_id;
- uint8_t active_timer;
- struct llist_head list;
- } lc15bts_leds;
-
- struct {
- int is_up;
- uint32_t last_seqno;
- struct osmo_timer_list recon_timer;
- struct ipa_client_conn *bts_conn;
- uint32_t crit_flags;
- uint32_t warn_flags;
- } lc15bts_ctrl;
-
- struct lc15bts_alarms {
- int temp_high;
- int temp_max;
- int supply_low;
- int supply_min;
- int vswr_high;
- int vswr_max;
- int supply_pwr_high;
- int supply_pwr_max;
- int supply_pwr_max2;
- int pa_pwr_high;
- int pa_pwr_max;
- int gps_fix_lost;
- struct llist_head list;
- struct osmo_timer_list preventive_timer;
- int preventive_duration;
- int preventive_retry;
- } alarms;
-
-};
-
-enum lc15bts_mgr_fail_evt_rep_crit_sig {
- /* Critical alarms */
- S_MGR_TEMP_SUPPLY_CRIT_MAX_ALARM = (1 << 0),
- S_MGR_TEMP_SOC_CRIT_MAX_ALARM = (1 << 1),
- S_MGR_TEMP_FPGA_CRIT_MAX_ALARM = (1 << 2),
- S_MGR_TEMP_RMS_DET_CRIT_MAX_ALARM = (1 << 3),
- S_MGR_TEMP_OCXO_CRIT_MAX_ALARM = (1 << 4),
- S_MGR_TEMP_TRX0_CRIT_MAX_ALARM = (1 << 5),
- S_MGR_TEMP_TRX1_CRIT_MAX_ALARM = (1 << 6),
- S_MGR_TEMP_PA0_CRIT_MAX_ALARM = (1 << 7),
- S_MGR_TEMP_PA1_CRIT_MAX_ALARM = (1 << 8),
- S_MGR_SUPPLY_CRIT_MAX_ALARM = (1 << 9),
- S_MGR_SUPPLY_CRIT_MIN_ALARM = (1 << 10),
- S_MGR_VSWR0_CRIT_MAX_ALARM = (1 << 11),
- S_MGR_VSWR1_CRIT_MAX_ALARM = (1 << 12),
- S_MGR_PWR_SUPPLY_CRIT_MAX_ALARM = (1 << 13),
- S_MGR_PWR_PA0_CRIT_MAX_ALARM = (1 << 14),
- S_MGR_PWR_PA1_CRIT_MAX_ALARM = (1 << 15),
- _S_MGR_CRIT_ALARM_MAX,
-};
-
-enum lc15bts_mgr_fail_evt_rep_warn_sig {
- /* Warning alarms */
- S_MGR_TEMP_SUPPLY_WARN_MIN_ALARM = (1 << 0),
- S_MGR_TEMP_SUPPLY_WARN_MAX_ALARM = (1 << 2),
- S_MGR_TEMP_SOC_WARN_MIN_ALARM = (1 << 3),
- S_MGR_TEMP_SOC_WARN_MAX_ALARM = (1 << 4),
- S_MGR_TEMP_FPGA_WARN_MIN_ALARM = (1 << 5),
- S_MGR_TEMP_FPGA_WARN_MAX_ALARM = (1 << 6),
- S_MGR_TEMP_RMS_DET_WARN_MIN_ALARM = (1 << 7),
- S_MGR_TEMP_RMS_DET_WARN_MAX_ALARM = (1 << 8),
- S_MGR_TEMP_OCXO_WARN_MIN_ALARM = (1 << 9),
- S_MGR_TEMP_OCXO_WARN_MAX_ALARM = (1 << 10),
- S_MGR_TEMP_TRX0_WARN_MIN_ALARM = (1 << 11),
- S_MGR_TEMP_TRX0_WARN_MAX_ALARM = (1 << 12),
- S_MGR_TEMP_TRX1_WARN_MIN_ALARM = (1 << 13),
- S_MGR_TEMP_TRX1_WARN_MAX_ALARM = (1 << 14),
- S_MGR_TEMP_PA0_WARN_MIN_ALARM = (1 << 15),
- S_MGR_TEMP_PA0_WARN_MAX_ALARM = (1 << 16),
- S_MGR_TEMP_PA1_WARN_MIN_ALARM = (1 << 17),
- S_MGR_TEMP_PA1_WARN_MAX_ALARM = (1 << 18),
- S_MGR_SUPPLY_WARN_MIN_ALARM = (1 << 19),
- S_MGR_SUPPLY_WARN_MAX_ALARM = (1 << 20),
- S_MGR_VSWR0_WARN_MAX_ALARM = (1 << 21),
- S_MGR_VSWR1_WARN_MAX_ALARM = (1 << 22),
- S_MGR_PWR_SUPPLY_WARN_MAX_ALARM = (1 << 23),
- S_MGR_PWR_PA0_WARN_MAX_ALARM = (1 << 24),
- S_MGR_PWR_PA1_WARN_MAX_ALARM = (1 << 25),
- S_MGR_GPS_FIX_WARN_ALARM = (1 << 26),
- _S_MGR_WARN_ALARM_MAX,
-};
-
-enum lc15bts_mgr_failure_event_causes {
- /* Critical causes */
- NM_EVT_CAUSE_CRIT_TEMP_SUPPLY_MAX_FAIL = 0x4100,
- NM_EVT_CAUSE_CRIT_TEMP_FPGA_MAX_FAIL = 0x4101,
- NM_EVT_CAUSE_CRIT_TEMP_SOC_MAX_FAIL = 0x4102,
- NM_EVT_CAUSE_CRIT_TEMP_RMS_DET_MAX_FAIL = 0x4103,
- NM_EVT_CAUSE_CRIT_TEMP_OCXO_MAX_FAIL = 0x4104,
- NM_EVT_CAUSE_CRIT_TEMP_TRX0_MAX_FAIL = 0x4105,
- NM_EVT_CAUSE_CRIT_TEMP_TRX1_MAX_FAIL = 0x4106,
- NM_EVT_CAUSE_CRIT_TEMP_PA0_MAX_FAIL = 0x4107,
- NM_EVT_CAUSE_CRIT_TEMP_PA1_MAX_FAIL = 0x4108,
- NM_EVT_CAUSE_CRIT_SUPPLY_MAX_FAIL = 0x4109,
- NM_EVT_CAUSE_CRIT_SUPPLY_MIN_FAIL = 0x410A,
- NM_EVT_CAUSE_CRIT_VSWR0_MAX_FAIL = 0x410B,
- NM_EVT_CAUSE_CRIT_VSWR1_MAX_FAIL = 0x410C,
- NM_EVT_CAUSE_CRIT_PWR_SUPPLY_MAX_FAIL = 0x410D,
- NM_EVT_CAUSE_CRIT_PWR_PA0_MAX_FAIL = 0x410E,
- NM_EVT_CAUSE_CRIT_PWR_PA1_MAX_FAIL = 0x410F,
- /* Warning causes */
- NM_EVT_CAUSE_WARN_TEMP_SUPPLY_LOW_FAIL = 0x4400,
- NM_EVT_CAUSE_WARN_TEMP_SUPPLY_HIGH_FAIL = 0x4401,
- NM_EVT_CAUSE_WARN_TEMP_FPGA_LOW_FAIL = 0x4402,
- NM_EVT_CAUSE_WARN_TEMP_FPGA_HIGH_FAIL = 0x4403,
- NM_EVT_CAUSE_WARN_TEMP_SOC_LOW_FAIL = 0x4404,
- NM_EVT_CAUSE_WARN_TEMP_SOC_HIGH_FAIL = 0x4405,
- NM_EVT_CAUSE_WARN_TEMP_RMS_DET_LOW_FAIL = 0x4406,
- NM_EVT_CAUSE_WARN_TEMP_RMS_DET_HIGH_FAIL= 0x4407,
- NM_EVT_CAUSE_WARN_TEMP_OCXO_LOW_FAIL = 0x4408,
- NM_EVT_CAUSE_WARN_TEMP_OCXO_HIGH_FAIL = 0x4409,
- NM_EVT_CAUSE_WARN_TEMP_TRX0_LOW_FAIL = 0x440A,
- NM_EVT_CAUSE_WARN_TEMP_TRX0_HIGH_FAIL = 0x440B,
- NM_EVT_CAUSE_WARN_TEMP_TRX1_LOW_FAIL = 0x440C,
- NM_EVT_CAUSE_WARN_TEMP_TRX1_HIGH_FAIL = 0x440D,
- NM_EVT_CAUSE_WARN_TEMP_PA0_LOW_FAIL = 0x440E,
- NM_EVT_CAUSE_WARN_TEMP_PA0_HIGH_FAIL = 0x440F,
- NM_EVT_CAUSE_WARN_TEMP_PA1_LOW_FAIL = 0x4410,
- NM_EVT_CAUSE_WARN_TEMP_PA1_HIGH_FAIL = 0x4411,
- NM_EVT_CAUSE_WARN_SUPPLY_LOW_FAIL = 0x4412,
- NM_EVT_CAUSE_WARN_SUPPLY_HIGH_FAIL = 0x4413,
- NM_EVT_CAUSE_WARN_VSWR0_HIGH_FAIL = 0x4414,
- NM_EVT_CAUSE_WANR_VSWR1_HIGH_FAIL = 0x4415,
- NM_EVT_CAUSE_WARN_PWR_SUPPLY_HIGH_FAIL = 0x4416,
- NM_EVT_CAUSE_WARN_PWR_PA0_HIGH_FAIL = 0x4417,
- NM_EVT_CAUSE_WARN_PWR_PA1_HIGH_FAIL = 0x4418,
- NM_EVT_CAUSE_WARN_GPS_FIX_FAIL = 0x4419,
-};
-
-/* This defines the list of notification events for systemd service watchdog.
- all these events must be notified in a certain service defined timeslot
- or the service (this app) would be restarted (only if related systemd service
- unit file has WatchdogSec!=0).
- WARNING: swd events must begin with event 0. Last events must be
- SWD_LAST (max 64 events in this list).
-*/
-enum mgr_swd_events {
- SWD_MAINLOOP = 0,
- SWD_CHECK_SENSOR,
- SWD_UPDATE_HOURS,
- SWD_CHECK_TEMP_SENSOR,
- SWD_CHECK_LED_CTRL,
- SWD_CHECK_CALIB,
- SWD_CHECK_BTS_CONNECTION,
- SWD_LAST
-};
-
-int lc15bts_mgr_vty_init(void);
-int lc15bts_mgr_parse_config(struct lc15bts_mgr_instance *mgr);
-int lc15bts_mgr_nl_init(void);
-int lc15bts_mgr_sensor_init(struct lc15bts_mgr_instance *mgr);
-const char *lc15bts_mgr_sensor_get_state(enum lc15bts_sensor_state state);
-
-int lc15bts_mgr_calib_init(struct lc15bts_mgr_instance *mgr);
-int lc15bts_mgr_control_init(struct lc15bts_mgr_instance *mgr);
-int lc15bts_mgr_calib_run(struct lc15bts_mgr_instance *mgr);
-void lc15bts_mgr_dispatch_alarm(struct lc15bts_mgr_instance *mgr, const int cause, const char *key, const char *text);
-extern void *tall_mgr_ctx;
-
-#endif
diff --git a/src/osmo-bts-litecell15/misc/lc15bts_mgr_calib.c b/src/osmo-bts-litecell15/misc/lc15bts_mgr_calib.c
deleted file mode 100644
index badb5455..00000000
--- a/src/osmo-bts-litecell15/misc/lc15bts_mgr_calib.c
+++ /dev/null
@@ -1,292 +0,0 @@
-/* OCXO calibration control for Litecell 1.5 BTS management daemon */
-
-/* Copyright (C) 2015 by Yves Godin <support@nuranwireless.com>
- *
- * Based on sysmoBTS:
- * sysmobts_mgr_calib.c
- * (C) 2014,2015 by Holger Hans Peter Freyther
- * (C) 2014 by Harald Welte for the IPA code from the oml router
- *
- * 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 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/licenses/>.
- *
- */
-
-#include "misc/lc15bts_mgr.h"
-#include "misc/lc15bts_misc.h"
-#include "misc/lc15bts_clock.h"
-#include "misc/lc15bts_swd.h"
-#include "misc/lc15bts_par.h"
-#include "misc/lc15bts_led.h"
-#include "osmo-bts/msg_utils.h"
-
-#include <osmocom/core/logging.h>
-#include <osmocom/core/select.h>
-
-#include <osmocom/ctrl/control_cmd.h>
-
-#include <osmocom/gsm/ipa.h>
-#include <osmocom/gsm/protocol/ipaccess.h>
-
-#include <osmocom/abis/abis.h>
-#include <osmocom/abis/e1_input.h>
-#include <osmocom/abis/ipa.h>
-
-#include <time.h>
-
-static void calib_adjust(struct lc15bts_mgr_instance *mgr);
-static void calib_state_reset(struct lc15bts_mgr_instance *mgr, int reason);
-static void calib_loop_run(void *_data);
-
-static int ocxodac_saved_value = -1;
-
-enum calib_state {
- CALIB_INITIAL,
- CALIB_IN_PROGRESS,
-};
-
-enum calib_result {
- CALIB_FAIL_START,
- CALIB_FAIL_GPSFIX,
- CALIB_FAIL_CLKERR,
- CALIB_FAIL_OCXODAC,
- CALIB_SUCCESS,
-};
-
-static void calib_start(struct lc15bts_mgr_instance *mgr)
-{
- int rc;
-
- rc = lc15bts_clock_err_open();
- if (rc != 0) {
- LOGP(DCALIB, LOGL_ERROR, "Failed to open clock error module %d\n", rc);
- calib_state_reset(mgr, CALIB_FAIL_CLKERR);
- return;
- }
-
- rc = lc15bts_clock_dac_open();
- if (rc != 0) {
- LOGP(DCALIB, LOGL_ERROR, "Failed to open OCXO dac module %d\n", rc);
- calib_state_reset(mgr, CALIB_FAIL_OCXODAC);
- return;
- }
-
- calib_adjust(mgr);
-}
-
-static void calib_adjust(struct lc15bts_mgr_instance *mgr)
-{
- int rc;
- int fault;
- int error_ppt;
- int accuracy_ppq;
- int interval_sec;
- int dac_value;
- int new_dac_value;
- int dac_correction;
- time_t now;
- time_t last_gps_fix;
-
- rc = lc15bts_clock_err_get(&fault, &error_ppt,
- &accuracy_ppq, &interval_sec);
- if (rc < 0) {
- LOGP(DCALIB, LOGL_ERROR,
- "Failed to get clock error measurement %d\n", rc);
- calib_state_reset(mgr, CALIB_FAIL_CLKERR);
- return;
- }
-
- /* get current time */
- now = time(NULL);
-
- /* first time after start of manager program */
- if (mgr->gps.last_update == 0)
- mgr->gps.last_update = now;
-
- /* read last GPS 3D fix from storage */
- rc = lc15bts_par_get_gps_fix(&last_gps_fix);
- if (rc < 0) {
- LOGP(DCALIB, LOGL_NOTICE, "Last GPS 3D fix can not read (%d). Last GPS 3D fix sets to zero\n", rc);
- last_gps_fix = 0;
- }
-
- if (fault) {
- LOGP(DCALIB, LOGL_NOTICE, "GPS has no fix\n");
- calib_state_reset(mgr, CALIB_FAIL_GPSFIX);
- return;
- }
-
- /* We got GPS 3D fix */
- LOGP(DCALIB, LOGL_DEBUG, "Got GPS 3D fix warn_flags=0x%08x, last=%lld, now=%lld\n",
- mgr->lc15bts_ctrl.warn_flags,
- (long long)last_gps_fix,
- (long long)now);
-
- rc = lc15bts_clock_dac_get(&dac_value);
- if (rc < 0) {
- LOGP(DCALIB, LOGL_ERROR,
- "Failed to get OCXO dac value %d\n", rc);
- calib_state_reset(mgr, CALIB_FAIL_OCXODAC);
- return;
- }
-
- /* Set OCXO initial dac value */
- if (ocxodac_saved_value < 0)
- ocxodac_saved_value = dac_value;
-
- LOGP(DCALIB, LOGL_NOTICE,
- "Calibration ERR(%f PPB) ACC(%f PPB) INT(%d) DAC(%d)\n",
- error_ppt / 1000., accuracy_ppq / 1000000., interval_sec, dac_value);
-
- /* Need integration time to correct */
- if (interval_sec) {
- /* 1 unit of correction equal about 0.5 - 1 PPB correction */
- dac_correction = (int)(-error_ppt * 0.0015);
- new_dac_value = dac_value + dac_correction;
-
- if (new_dac_value > 4095)
- new_dac_value = 4095;
- else if (new_dac_value < 0)
- new_dac_value = 0;
-
- /* We have a fix, make sure the measured error is
- meaningful (10 times the accuracy) */
- if ((new_dac_value != dac_value) && ((100l * abs(error_ppt)) > accuracy_ppq)) {
-
- LOGP(DCALIB, LOGL_NOTICE,
- "Going to apply %d as new clock setting.\n",
- new_dac_value);
-
- rc = lc15bts_clock_dac_set(new_dac_value);
- if (rc < 0) {
- LOGP(DCALIB, LOGL_ERROR,
- "Failed to set OCXO dac value %d\n", rc);
- calib_state_reset(mgr, CALIB_FAIL_OCXODAC);
- return;
- }
- rc = lc15bts_clock_err_reset();
- if (rc < 0) {
- LOGP(DCALIB, LOGL_ERROR,
- "Failed to reset clock error module %d\n", rc);
- calib_state_reset(mgr, CALIB_FAIL_CLKERR);
- return;
- }
- }
- /* New conditions to store DAC value:
- * - Resolution accuracy less or equal than 0.01PPB (or 10000 PPQ)
- * - Error less or equal than 2PPB (or 2000PPT)
- * - Solution different than the last one */
- else if (accuracy_ppq <= 10000) {
- if((dac_value != ocxodac_saved_value) && (abs(error_ppt) < 2000)) {
- LOGP(DCALIB, LOGL_NOTICE, "Saving OCXO DAC value to memory... val = %d\n", dac_value);
- rc = lc15bts_clock_dac_save();
- if (rc < 0) {
- LOGP(DCALIB, LOGL_ERROR,
- "Failed to save OCXO dac value %d\n", rc);
- calib_state_reset(mgr, CALIB_FAIL_OCXODAC);
- } else {
- ocxodac_saved_value = dac_value;
- }
- }
-
- rc = lc15bts_clock_err_reset();
- if (rc < 0) {
- LOGP(DCALIB, LOGL_ERROR,
- "Failed to reset clock error module %d\n", rc);
- calib_state_reset(mgr, CALIB_FAIL_CLKERR);
- }
- }
- } else {
- LOGP(DCALIB, LOGL_NOTICE, "Skipping this iteration, no integration time\n");
- }
-
- calib_state_reset(mgr, CALIB_SUCCESS);
- return;
-}
-
-static void calib_close(struct lc15bts_mgr_instance *mgr)
-{
- lc15bts_clock_err_close();
- lc15bts_clock_dac_close();
-}
-
-static void calib_state_reset(struct lc15bts_mgr_instance *mgr, int outcome)
-{
- if (mgr->calib.calib_from_loop) {
- /*
- * In case of success calibrate in two hours again
- * and in case of a failure in some minutes.
- *
- * TODO NTQ: Select timeout based on last error and accuracy
- */
- int timeout = 60;
- //int timeout = 2 * 60 * 60;
- //if (outcome != CALIB_SUCESS) }
- // timeout = 5 * 60;
- //}
-
- mgr->calib.calib_timeout.data = mgr;
- mgr->calib.calib_timeout.cb = calib_loop_run;
- osmo_timer_schedule(&mgr->calib.calib_timeout, timeout, 0);
- /* TODO: do we want to notify if we got a calibration error, like no gps fix? */
- lc15bts_swd_event(mgr, SWD_CHECK_CALIB);
- }
-
- mgr->calib.state = CALIB_INITIAL;
- calib_close(mgr);
-}
-
-static int calib_run(struct lc15bts_mgr_instance *mgr, int from_loop)
-{
- if (mgr->calib.state != CALIB_INITIAL) {
- LOGP(DCALIB, LOGL_ERROR, "Calib is already in progress.\n");
- return -1;
- }
-
- mgr->calib.calib_from_loop = from_loop;
-
- /* From now on everything will be handled from the failure */
- mgr->calib.state = CALIB_IN_PROGRESS;
- calib_start(mgr);
- return 0;
-}
-
-static void calib_loop_run(void *_data)
-{
- int rc;
- struct lc15bts_mgr_instance *mgr = _data;
-
- LOGP(DCALIB, LOGL_NOTICE, "Going to calibrate the system.\n");
- rc = calib_run(mgr, 1);
- if (rc != 0) {
- calib_state_reset(mgr, CALIB_FAIL_START);
- }
-}
-
-int lc15bts_mgr_calib_run(struct lc15bts_mgr_instance *mgr)
-{
- return calib_run(mgr, 0);
-}
-
-int lc15bts_mgr_calib_init(struct lc15bts_mgr_instance *mgr)
-{
- mgr->calib.state = CALIB_INITIAL;
- mgr->calib.calib_timeout.data = mgr;
- mgr->calib.calib_timeout.cb = calib_loop_run;
- osmo_timer_schedule(&mgr->calib.calib_timeout, 0, 0);
-
- return 0;
-}
-
diff --git a/src/osmo-bts-litecell15/misc/lc15bts_mgr_nl.c b/src/osmo-bts-litecell15/misc/lc15bts_mgr_nl.c
deleted file mode 100644
index 3a617dd7..00000000
--- a/src/osmo-bts-litecell15/misc/lc15bts_mgr_nl.c
+++ /dev/null
@@ -1,195 +0,0 @@
-/* NetworkListen for NuRAN Litecell 1.5 BTS management daemon */
-
-/* Copyright (C) 2015 by Yves Godin <support@nuranwireless.com>
- *
- * Based on sysmoBTS:
- * sysmobts_mgr_nl.c
- * (C) 2014 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 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 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/licenses/>.
- *
- */
-
-#include "misc/lc15bts_mgr.h"
-#include "misc/lc15bts_misc.h"
-#include "misc/lc15bts_nl.h"
-#include "misc/lc15bts_par.h"
-#include "misc/lc15bts_bid.h"
-
-#include <osmo-bts/logging.h>
-
-#include <osmocom/gsm/protocol/ipaccess.h>
-
-#include <osmocom/core/msgb.h>
-#include <osmocom/core/socket.h>
-#include <osmocom/core/select.h>
-
-#include <arpa/inet.h>
-
-#include <sys/types.h>
-#include <sys/socket.h>
-
-#include <errno.h>
-#include <string.h>
-#include <fcntl.h>
-#include <unistd.h>
-
-#define ETH0_ADDR_SYSFS "/var/lc15/net/eth0/address"
-
-static struct osmo_fd nl_fd;
-
-/*
- * The TLV structure in IPA messages in UDP packages is a bit
- * weird. First the header appears to have an extra NULL byte
- * and second the L16 of the L16TV needs to include +1 for the
- * tag. The default msgb/tlv and libosmo-abis routines do not
- * provide this.
- */
-
-static void ipaccess_prepend_header_quirk(struct msgb *msg, int proto)
-{
- struct ipaccess_head *hh;
-
- /* prepend the ip.access header */
- hh = (struct ipaccess_head *) msgb_push(msg, sizeof(*hh) + 1);
- hh->len = htons(msg->len - sizeof(*hh) - 1);
- hh->proto = proto;
-}
-
-static void quirk_l16tv_put(struct msgb *msg, uint16_t len, uint8_t tag,
- const uint8_t *val)
-{
- uint8_t *buf = msgb_put(msg, len + 2 + 1);
-
- *buf++ = (len + 1) >> 8;
- *buf++ = (len + 1) & 0xff;
- *buf++ = tag;
- memcpy(buf, val, len);
-}
-
-/*
- * We don't look at the content of the request yet and lie
- * about most of the responses.
- */
-static void respond_to(struct sockaddr_in *src, struct osmo_fd *fd,
- uint8_t *data, size_t len)
-{
- static int fetched_info = 0;
- static char mac_str[20] = {0, };
- static char model_name[64] = {0, };
- static char ser_str[20] = {0, };
-
- struct sockaddr_in loc_addr;
- int rc;
- char loc_ip[INET_ADDRSTRLEN];
- struct msgb *msg = msgb_alloc_headroom(512, 128, "ipa get response");
- if (!msg) {
- LOGP(DFIND, LOGL_ERROR, "Failed to allocate msgb\n");
- return;
- }
-
- if (!fetched_info) {
- int fd_eth;
- int serno;
-
- /* fetch the MAC */
- fd_eth = open(ETH0_ADDR_SYSFS, O_RDONLY);
- if (fd_eth >= 0) {
- read(fd_eth, mac_str, sizeof(mac_str)-1);
- mac_str[sizeof(mac_str)-1] = '\0';
- close(fd_eth);
- }
-
- /* fetch the serial number */
- lc15bts_par_get_int(tall_mgr_ctx, LC15BTS_PAR_SERNR, &serno);
- snprintf(ser_str, sizeof(ser_str), "%d", serno);
-
- strncpy(model_name, get_hwversion_desc(), sizeof(model_name)-1);
- fetched_info = 1;
- }
-
- if (source_for_dest(&src->sin_addr, &loc_addr.sin_addr) != 0) {
- LOGP(DFIND, LOGL_ERROR, "Failed to determine local source\n");
- return;
- }
-
- msgb_put_u8(msg, IPAC_MSGT_ID_RESP);
-
- /* append MAC addr */
- quirk_l16tv_put(msg, strlen(mac_str) + 1, IPAC_IDTAG_MACADDR, (uint8_t *) mac_str);
-
- /* append ip address */
- inet_ntop(AF_INET, &loc_addr.sin_addr, loc_ip, sizeof(loc_ip));
- quirk_l16tv_put(msg, strlen(loc_ip) + 1, IPAC_IDTAG_IPADDR, (uint8_t *) loc_ip);
-
- /* append the serial number */
- quirk_l16tv_put(msg, strlen(ser_str) + 1, IPAC_IDTAG_SERNR, (uint8_t *) ser_str);
-
- /* abuse some flags */
- quirk_l16tv_put(msg, strlen(model_name) + 1, IPAC_IDTAG_UNIT, (uint8_t *) model_name);
-
- /* ip.access nanoBTS would reply to port==3006 */
- ipaccess_prepend_header_quirk(msg, IPAC_PROTO_IPACCESS);
- rc = sendto(fd->fd, msg->data, msg->len, 0, (struct sockaddr *)src, sizeof(*src));
- if (rc != msg->len)
- LOGP(DFIND, LOGL_ERROR,
- "Failed to send with rc(%d) errno(%d)\n", rc, errno);
-}
-
-static int ipaccess_bcast(struct osmo_fd *fd, unsigned int what)
-{
- uint8_t data[2048];
- char src[INET_ADDRSTRLEN];
- struct sockaddr_in addr = {};
- socklen_t len = sizeof(addr);
- int rc;
-
- rc = recvfrom(fd->fd, data, sizeof(data), 0,
- (struct sockaddr *) &addr, &len);
- if (rc <= 0) {
- LOGP(DFIND, LOGL_ERROR,
- "Failed to read from socket errno(%d)\n", errno);
- return -1;
- }
-
- LOGP(DFIND, LOGL_DEBUG,
- "Received request from: %s size %d\n",
- inet_ntop(AF_INET, &addr.sin_addr, src, sizeof(src)), rc);
-
- if (rc < 6)
- return 0;
-
- if (data[2] != IPAC_PROTO_IPACCESS || data[4] != IPAC_MSGT_ID_GET)
- return 0;
-
- respond_to(&addr, fd, data + 6, rc - 6);
- return 0;
-}
-
-int lc15bts_mgr_nl_init(void)
-{
- int rc;
-
- nl_fd.cb = ipaccess_bcast;
- rc = osmo_sock_init_ofd(&nl_fd, AF_INET, SOCK_DGRAM, IPPROTO_UDP,
- "0.0.0.0", 3006, OSMO_SOCK_F_BIND);
- if (rc < 0) {
- perror("Socket creation");
- return -1;
- }
-
- return 0;
-}
diff --git a/src/osmo-bts-litecell15/misc/lc15bts_mgr_temp.c b/src/osmo-bts-litecell15/misc/lc15bts_mgr_temp.c
deleted file mode 100644
index 9665e1db..00000000
--- a/src/osmo-bts-litecell15/misc/lc15bts_mgr_temp.c
+++ /dev/null
@@ -1,378 +0,0 @@
-/* Temperature control for NuRAN Litecell 1.5 BTS management daemon */
-
-/* Copyright (C) 2015 by Yves Godin <support@nuranwireless.com>
- *
- * Based on sysmoBTS:
- * sysmobts_mgr_temp.c
- * (C) 2014 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 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 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/licenses/>.
- *
- */
-#include <inttypes.h>
-#include "misc/lc15bts_mgr.h"
-#include "misc/lc15bts_misc.h"
-#include "misc/lc15bts_temp.h"
-#include "misc/lc15bts_power.h"
-#include "misc/lc15bts_led.h"
-#include "misc/lc15bts_swd.h"
-#include "limits.h"
-
-#include <osmo-bts/logging.h>
-
-#include <osmocom/core/timer.h>
-#include <osmocom/core/utils.h>
-#include <osmocom/core/linuxlist.h>
-
-struct lc15bts_mgr_instance *s_mgr;
-static struct osmo_timer_list sensor_ctrl_timer;
-
-static const struct value_string state_names[] = {
- { STATE_NORMAL, "NORMAL" },
- { STATE_WARNING_HYST, "WARNING (HYST)" },
- { STATE_WARNING, "WARNING" },
- { STATE_CRITICAL, "CRITICAL" },
- { 0, NULL }
-};
-
-const char *lc15bts_mgr_sensor_get_state(enum lc15bts_sensor_state state)
-{
- return get_value_string(state_names, state);
-}
-
-static int next_state(enum lc15bts_sensor_state current_state, int critical, int warning)
-{
- int next_state = -1;
- switch (current_state) {
- case STATE_NORMAL:
- if (critical)
- next_state = STATE_CRITICAL;
- else if (warning)
- next_state = STATE_WARNING;
- break;
- case STATE_WARNING_HYST:
- if (critical)
- next_state = STATE_CRITICAL;
- else if (warning)
- next_state = STATE_WARNING;
- else
- next_state = STATE_NORMAL;
- break;
- case STATE_WARNING:
- if (critical)
- next_state = STATE_CRITICAL;
- else if (!warning)
- next_state = STATE_WARNING_HYST;
- break;
- case STATE_CRITICAL:
- if (!critical && !warning)
- next_state = STATE_WARNING;
- break;
- };
-
- return next_state;
-}
-
-static void handle_normal_actions(int actions)
-{
- /* switch on the PA */
- if (actions & SENSOR_ACT_NORM_PA0_ON) {
- if (lc15bts_power_set(LC15BTS_POWER_PA0, 1) != 0) {
- LOGP(DTEMP, LOGL_ERROR,
- "Failed to switch on the PA #0\n");
- } else {
- LOGP(DTEMP, LOGL_NOTICE,
- "Switched on the PA #0 as normal action.\n");
- }
- }
-
- if (actions & SENSOR_ACT_NORM_PA1_ON) {
- if (lc15bts_power_set(LC15BTS_POWER_PA1, 1) != 0) {
- LOGP(DTEMP, LOGL_ERROR,
- "Failed to switch on the PA #1\n");
- } else {
- LOGP(DTEMP, LOGL_NOTICE,
- "Switched on the PA #1 as normal action.\n");
- }
- }
-
- if (actions & SENSOR_ACT_NORM_BTS_SRV_ON) {
- LOGP(DTEMP, LOGL_NOTICE,
- "Going to switch on the BTS service\n");
- /*
- * TODO: use/create something like nspawn that serializes
- * and used SIGCHLD/waitpid to pick up the dead processes
- * without invoking shell.
- */
- system("/bin/systemctl start osmo-bts.service");
- }
-}
-
-static void handle_actions(int actions)
-{
- /* switch off the PA */
- if (actions & SENSOR_ACT_PA1_OFF) {
- if (lc15bts_power_set(LC15BTS_POWER_PA1, 0) != 0) {
- LOGP(DTEMP, LOGL_ERROR,
- "Failed to switch off the PA #1. Stop BTS?\n");
- } else {
- LOGP(DTEMP, LOGL_NOTICE,
- "Switched off the PA #1 due temperature.\n");
- }
- }
-
- if (actions & SENSOR_ACT_PA0_OFF) {
- if (lc15bts_power_set(LC15BTS_POWER_PA0, 0) != 0) {
- LOGP(DTEMP, LOGL_ERROR,
- "Failed to switch off the PA #0. Stop BTS?\n");
- } else {
- LOGP(DTEMP, LOGL_NOTICE,
- "Switched off the PA #0 due temperature.\n");
- }
- }
-
- if (actions & SENSOR_ACT_BTS_SRV_OFF) {
- LOGP(DTEMP, LOGL_NOTICE,
- "Going to switch off the BTS service\n");
- /*
- * TODO: use/create something like nspawn that serializes
- * and used SIGCHLD/waitpid to pick up the dead processes
- * without invoking shell.
- */
- system("/bin/systemctl stop osmo-bts.service");
- }
-}
-
-/**
- * Go back to normal! Depending on the configuration execute the normal
- * actions that could (start to) undo everything we did in the other
- * states. What is still missing is the power increase/decrease depending
- * on the state. E.g. starting from WARNING_HYST we might want to slowly
- * ramp up the output power again.
- */
-static void execute_normal_act(struct lc15bts_mgr_instance *manager)
-{
- LOGP(DTEMP, LOGL_NOTICE, "System is back to normal state.\n");
- handle_normal_actions(manager->state.action_norm);
-}
-
-static void execute_warning_act(struct lc15bts_mgr_instance *manager)
-{
- LOGP(DTEMP, LOGL_NOTICE, "System has reached warning state.\n");
- handle_actions(manager->state.action_warn);
-}
-
-static void execute_critical_act(struct lc15bts_mgr_instance *manager)
-{
- LOGP(DTEMP, LOGL_NOTICE, "System has reached critical warning.\n");
- handle_actions(manager->state.action_crit);
-}
-
-static void lc15bts_mgr_sensor_handle(struct lc15bts_mgr_instance *manager,
- int critical, int warning)
-{
- int new_state = next_state(manager->state.state, critical, warning);
-
- /* Nothing changed */
- if (new_state < 0)
- return;
-
- LOGP(DTEMP, LOGL_NOTICE, "Moving from state %s to %s.\n",
- get_value_string(state_names, manager->state.state),
- get_value_string(state_names, new_state));
- manager->state.state = new_state;
- switch (manager->state.state) {
- case STATE_NORMAL:
- execute_normal_act(manager);
- break;
- case STATE_WARNING_HYST:
- /* do nothing? Maybe start to increase transmit power? */
- break;
- case STATE_WARNING:
- execute_warning_act(manager);
- break;
- case STATE_CRITICAL:
- execute_critical_act(manager);
- break;
- };
-}
-
-static void sensor_ctrl_check(struct lc15bts_mgr_instance *mgr)
-{
- int rc;
- int temp = 0;
- int warn_thresh_passed = 0;
- int crit_thresh_passed = 0;
-
- LOGP(DTEMP, LOGL_DEBUG, "Going to check the temperature.\n");
-
- /* Read the current supply temperature */
- rc = lc15bts_temp_get(LC15BTS_TEMP_SUPPLY, &temp);
- if (rc < 0) {
- LOGP(DTEMP, LOGL_ERROR,
- "Failed to read the supply temperature. rc=%d\n", rc);
- warn_thresh_passed = crit_thresh_passed = 1;
- } else {
- temp = temp / 1000;
- if (temp > mgr->temp.supply_temp_limit.thresh_warn_max)
- warn_thresh_passed = 1;
- if (temp > mgr->temp.supply_temp_limit.thresh_crit_max)
- crit_thresh_passed = 1;
- LOGP(DTEMP, LOGL_DEBUG, "Supply temperature is: %d\n", temp);
- }
-
- /* Read the current SoC temperature */
- rc = lc15bts_temp_get(LC15BTS_TEMP_SOC, &temp);
- if (rc < 0) {
- LOGP(DTEMP, LOGL_ERROR,
- "Failed to read the SoC temperature. rc=%d\n", rc);
- warn_thresh_passed = crit_thresh_passed = 1;
- } else {
- temp = temp / 1000;
- if (temp > mgr->temp.soc_temp_limit.thresh_warn_max)
- warn_thresh_passed = 1;
- if (temp > mgr->temp.soc_temp_limit.thresh_crit_max)
- crit_thresh_passed = 1;
- LOGP(DTEMP, LOGL_DEBUG, "SoC temperature is: %d\n", temp);
- }
-
- /* Read the current fpga temperature */
- rc = lc15bts_temp_get(LC15BTS_TEMP_FPGA, &temp);
- if (rc < 0) {
- LOGP(DTEMP, LOGL_ERROR,
- "Failed to read the fpga temperature. rc=%d\n", rc);
- warn_thresh_passed = crit_thresh_passed = 1;
- } else {
- temp = temp / 1000;
- if (temp > mgr->temp.fpga_temp_limit.thresh_warn_max)
- warn_thresh_passed = 1;
- if (temp > mgr->temp.fpga_temp_limit.thresh_crit_max)
- crit_thresh_passed = 1;
- LOGP(DTEMP, LOGL_DEBUG, "FPGA temperature is: %d\n", temp);
- }
-
- /* Read the current RMS detector temperature */
- rc = lc15bts_temp_get(LC15BTS_TEMP_RMSDET, &temp);
- if (rc < 0) {
- LOGP(DTEMP, LOGL_ERROR,
- "Failed to read the RMS detector temperature. rc=%d\n", rc);
- warn_thresh_passed = crit_thresh_passed = 1;
- } else {
- temp = temp / 1000;
- if (temp > mgr->temp.rmsdet_temp_limit.thresh_warn_max)
- warn_thresh_passed = 1;
- if (temp > mgr->temp.rmsdet_temp_limit.thresh_crit_max)
- crit_thresh_passed = 1;
- LOGP(DTEMP, LOGL_DEBUG, "RMS detector temperature is: %d\n", temp);
- }
-
- /* Read the current OCXO temperature */
- rc = lc15bts_temp_get(LC15BTS_TEMP_OCXO, &temp);
- if (rc < 0) {
- LOGP(DTEMP, LOGL_ERROR,
- "Failed to read the OCXO temperature. rc=%d\n", rc);
- warn_thresh_passed = crit_thresh_passed = 1;
- } else {
- temp = temp / 1000;
- if (temp > mgr->temp.ocxo_temp_limit.thresh_warn_max)
- warn_thresh_passed = 1;
- if (temp > mgr->temp.ocxo_temp_limit.thresh_crit_max)
- crit_thresh_passed = 1;
- LOGP(DTEMP, LOGL_DEBUG, "OCXO temperature is: %d\n", temp);
- }
-
- /* Read the current TX #0 temperature */
- rc = lc15bts_temp_get(LC15BTS_TEMP_TX0, &temp);
- if (rc < 0) {
- LOGP(DTEMP, LOGL_ERROR,
- "Failed to read the TX #0 temperature. rc=%d\n", rc);
- warn_thresh_passed = crit_thresh_passed = 1;
- } else {
- temp = temp / 1000;
- if (temp > mgr->temp.tx0_temp_limit.thresh_warn_max)
- warn_thresh_passed = 1;
- if (temp > mgr->temp.tx0_temp_limit.thresh_crit_max)
- crit_thresh_passed = 1;
- LOGP(DTEMP, LOGL_DEBUG, "TX #0 temperature is: %d\n", temp);
- }
-
- /* Read the current TX #1 temperature */
- rc = lc15bts_temp_get(LC15BTS_TEMP_TX1, &temp);
- if (rc < 0) {
- LOGP(DTEMP, LOGL_ERROR,
- "Failed to read the TX #1 temperature. rc=%d\n", rc);
- warn_thresh_passed = crit_thresh_passed = 1;
- } else {
- temp = temp / 1000;
- if (temp > mgr->temp.tx1_temp_limit.thresh_warn_max)
- warn_thresh_passed = 1;
- if (temp > mgr->temp.tx1_temp_limit.thresh_crit_max)
- crit_thresh_passed = 1;
- LOGP(DTEMP, LOGL_DEBUG, "TX #1 temperature is: %d\n", temp);
- }
-
- /* Read the current PA #0 temperature */
- rc = lc15bts_temp_get(LC15BTS_TEMP_PA0, &temp);
- if (rc < 0) {
- LOGP(DTEMP, LOGL_ERROR,
- "Failed to read the PA #0 temperature. rc=%d\n", rc);
- warn_thresh_passed = crit_thresh_passed = 1;
- } else {
- temp = temp / 1000;
- if (temp > mgr->temp.pa0_temp_limit.thresh_warn_max)
- warn_thresh_passed = 1;
- if (temp > mgr->temp.pa0_temp_limit.thresh_crit_max)
- crit_thresh_passed = 1;
- LOGP(DTEMP, LOGL_DEBUG, "PA #0 temperature is: %d\n", temp);
- }
-
- /* Read the current PA #1 temperature */
- rc = lc15bts_temp_get(LC15BTS_TEMP_PA1, &temp);
- if (rc < 0) {
- LOGP(DTEMP, LOGL_ERROR,
- "Failed to read the PA #1 temperature. rc=%d\n", rc);
- warn_thresh_passed = crit_thresh_passed = 1;
- } else {
- temp = temp / 1000;
- if (temp > mgr->temp.pa1_temp_limit.thresh_warn_max)
- warn_thresh_passed = 1;
- if (temp > mgr->temp.pa1_temp_limit.thresh_crit_max)
- crit_thresh_passed = 1;
- LOGP(DTEMP, LOGL_DEBUG, "PA #1 temperature is: %d\n", temp);
- }
-
- lc15bts_mgr_sensor_handle(mgr, crit_thresh_passed, warn_thresh_passed);
-}
-
-static void sensor_ctrl_check_cb(void *_data)
-{
- struct lc15bts_mgr_instance *mgr = _data;
- sensor_ctrl_check(mgr);
- /* Check every minute? XXX make it configurable! */
- osmo_timer_schedule(&sensor_ctrl_timer, LC15BTS_SENSOR_TIMER_DURATION, 0);
- LOGP(DTEMP, LOGL_DEBUG,"Check sensors timer expired\n");
- /* TODO: do we want to notify if some sensors could not be read? */
- lc15bts_swd_event(mgr, SWD_CHECK_TEMP_SENSOR);
-}
-
-int lc15bts_mgr_sensor_init(struct lc15bts_mgr_instance *mgr)
-{
- s_mgr = mgr;
- sensor_ctrl_timer.cb = sensor_ctrl_check_cb;
- sensor_ctrl_timer.data = s_mgr;
- sensor_ctrl_check_cb(s_mgr);
- return 0;
-}
diff --git a/src/osmo-bts-litecell15/misc/lc15bts_mgr_vty.c b/src/osmo-bts-litecell15/misc/lc15bts_mgr_vty.c
deleted file mode 100644
index 424ff18f..00000000
--- a/src/osmo-bts-litecell15/misc/lc15bts_mgr_vty.c
+++ /dev/null
@@ -1,1074 +0,0 @@
-/* Copyright (C) 2015 by Yves Godin <support@nuranwireless.com>
- *
- * Based on sysmoBTS:
- * sysmobts_mgr_vty.c
- * (C) 2014 by sysmocom - s.f.m.c. GmbH
- *
- * All Rights Reserved
- *
- * Author: Alvaro Neira Ayuso <anayuso@sysmocom.de>
- *
- * 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 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/licenses/>.
- *
- */
-
-#include <stdlib.h>
-#include <unistd.h>
-#include <errno.h>
-#include <stdint.h>
-#include <ctype.h>
-#include <string.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <inttypes.h>
-
-#include <osmocom/vty/vty.h>
-#include <osmocom/vty/command.h>
-#include <osmocom/vty/misc.h>
-
-#include <osmo-bts/logging.h>
-
-#include "lc15bts_misc.h"
-#include "lc15bts_mgr.h"
-#include "lc15bts_temp.h"
-#include "lc15bts_power.h"
-#include "lc15bts_led.h"
-#include "btsconfig.h"
-
-static struct lc15bts_mgr_instance *s_mgr;
-
-static const char copyright[] =
- "(C) 2012 by Harald Welte <laforge@gnumonks.org>\r\n"
- "(C) 2014 by Holger Hans Peter Freyther\r\n"
- "(C) 2015 by Yves Godin <support@nuranwireless.com>\r\n"
- "License AGPLv3+: GNU AGPL version 2 or later <http://gnu.org/licenses/agpl-3.0.html>\r\n"
- "This is free software: you are free to change and redistribute it.\r\n"
- "There is NO WARRANTY, to the extent permitted by law.\r\n";
-
-static int go_to_parent(struct vty *vty)
-{
- switch (vty->node) {
- case MGR_NODE:
- vty->node = CONFIG_NODE;
- break;
- case ACT_NORM_NODE:
- case ACT_WARN_NODE:
- case ACT_CRIT_NODE:
- case LIMIT_SUPPLY_TEMP_NODE:
- case LIMIT_SOC_NODE:
- case LIMIT_FPGA_NODE:
- case LIMIT_RMSDET_NODE:
- case LIMIT_OCXO_NODE:
- case LIMIT_TX0_TEMP_NODE:
- case LIMIT_TX1_TEMP_NODE:
- case LIMIT_PA0_TEMP_NODE:
- case LIMIT_PA1_TEMP_NODE:
- case LIMIT_SUPPLY_VOLT_NODE:
- case LIMIT_TX0_VSWR_NODE:
- case LIMIT_TX1_VSWR_NODE:
- case LIMIT_SUPPLY_PWR_NODE:
- case LIMIT_PA0_PWR_NODE:
- case LIMIT_PA1_PWR_NODE:
- vty->node = MGR_NODE;
- break;
- default:
- vty->node = CONFIG_NODE;
- }
- return vty->node;
-}
-
-static int is_config_node(struct vty *vty, int node)
-{
- switch (node) {
- case MGR_NODE:
- case ACT_NORM_NODE:
- case ACT_WARN_NODE:
- case ACT_CRIT_NODE:
- case LIMIT_SUPPLY_TEMP_NODE:
- case LIMIT_SOC_NODE:
- case LIMIT_FPGA_NODE:
- case LIMIT_RMSDET_NODE:
- case LIMIT_OCXO_NODE:
- case LIMIT_TX0_TEMP_NODE:
- case LIMIT_TX1_TEMP_NODE:
- case LIMIT_PA0_TEMP_NODE:
- case LIMIT_PA1_TEMP_NODE:
- case LIMIT_SUPPLY_VOLT_NODE:
- case LIMIT_TX0_VSWR_NODE:
- case LIMIT_TX1_VSWR_NODE:
- case LIMIT_SUPPLY_PWR_NODE:
- case LIMIT_PA0_PWR_NODE:
- case LIMIT_PA1_PWR_NODE:
- return 1;
- default:
- return 0;
- }
-}
-
-static struct vty_app_info vty_info = {
- .name = "lc15bts-mgr",
- .version = PACKAGE_VERSION,
- .go_parent_cb = go_to_parent,
- .is_config_node = is_config_node,
- .copyright = copyright,
-};
-
-
-#define MGR_STR "Configure lc15bts-mgr\n"
-
-static struct cmd_node mgr_node = {
- MGR_NODE,
- "%s(lc15bts-mgr)# ",
- 1,
-};
-
-static struct cmd_node act_norm_node = {
- ACT_NORM_NODE,
- "%s(actions-normal)# ",
- 1,
-};
-
-static struct cmd_node act_warn_node = {
- ACT_WARN_NODE,
- "%s(actions-warn)# ",
- 1,
-};
-
-static struct cmd_node act_crit_node = {
- ACT_CRIT_NODE,
- "%s(actions-critical)# ",
- 1,
-};
-
-static struct cmd_node limit_supply_temp_node = {
- LIMIT_SUPPLY_TEMP_NODE,
- "%s(limit-supply-temp)# ",
- 1,
-};
-
-static struct cmd_node limit_soc_node = {
- LIMIT_SOC_NODE,
- "%s(limit-soc)# ",
- 1,
-};
-
-static struct cmd_node limit_fpga_node = {
- LIMIT_FPGA_NODE,
- "%s(limit-fpga)# ",
- 1,
-};
-
-static struct cmd_node limit_rmsdet_node = {
- LIMIT_RMSDET_NODE,
- "%s(limit-rmsdet)# ",
- 1,
-};
-
-static struct cmd_node limit_ocxo_node = {
- LIMIT_OCXO_NODE,
- "%s(limit-ocxo)# ",
- 1,
-};
-
-static struct cmd_node limit_tx0_temp_node = {
- LIMIT_TX0_TEMP_NODE,
- "%s(limit-tx0-temp)# ",
- 1,
-};
-static struct cmd_node limit_tx1_temp_node = {
- LIMIT_TX1_TEMP_NODE,
- "%s(limit-tx1-temp)# ",
- 1,
-};
-static struct cmd_node limit_pa0_temp_node = {
- LIMIT_PA0_TEMP_NODE,
- "%s(limit-pa0-temp)# ",
- 1,
-};
-static struct cmd_node limit_pa1_temp_node = {
- LIMIT_PA1_TEMP_NODE,
- "%s(limit-pa1-temp)# ",
- 1,
-};
-static struct cmd_node limit_supply_volt_node = {
- LIMIT_SUPPLY_VOLT_NODE,
- "%s(limit-supply-volt)# ",
- 1,
-};
-static struct cmd_node limit_tx0_vswr_node = {
- LIMIT_TX0_VSWR_NODE,
- "%s(limit-tx0-vswr)# ",
- 1,
-};
-static struct cmd_node limit_tx1_vswr_node = {
- LIMIT_TX1_VSWR_NODE,
- "%s(limit-tx1-vswr)# ",
- 1,
-};
-static struct cmd_node limit_supply_pwr_node = {
- LIMIT_SUPPLY_PWR_NODE,
- "%s(limit-supply-pwr)# ",
- 1,
-};
-static struct cmd_node limit_pa0_pwr_node = {
- LIMIT_PA0_PWR_NODE,
- "%s(limit-pa0-pwr)# ",
- 1,
-};
-static struct cmd_node limit_pa1_pwr_node = {
- LIMIT_PA1_PWR_NODE,
- "%s(limit-pa1-pwr)# ",
- 1,
-};
-
-static struct cmd_node limit_gps_fix_node = {
- LIMIT_GPS_FIX_NODE,
- "%s(limit-gps-fix)# ",
- 1,
-};
-
-DEFUN(cfg_mgr, cfg_mgr_cmd,
- "lc15bts-mgr",
- MGR_STR)
-{
- vty->node = MGR_NODE;
- return CMD_SUCCESS;
-}
-
-static void write_volt_limit(struct vty *vty, const char *name,
- struct lc15bts_volt_limit *limit)
-{
- vty_out(vty, " %s%s", name, VTY_NEWLINE);
- vty_out(vty, " threshold warning min %d%s",
- limit->thresh_warn_min, VTY_NEWLINE);
- vty_out(vty, " threshold critical min %d%s",
- limit->thresh_crit_min, VTY_NEWLINE);
-}
-
-static void write_vswr_limit(struct vty *vty, const char *name,
- struct lc15bts_vswr_limit *limit)
-{
- vty_out(vty, " %s%s", name, VTY_NEWLINE);
- vty_out(vty, " threshold warning max %d%s",
- limit->thresh_warn_max, VTY_NEWLINE);
-}
-
-static void write_pwr_limit(struct vty *vty, const char *name,
- struct lc15bts_pwr_limit *limit)
-{
- vty_out(vty, " %s%s", name, VTY_NEWLINE);
- vty_out(vty, " threshold warning max %d%s",
- limit->thresh_warn_max, VTY_NEWLINE);
- vty_out(vty, " threshold critical max %d%s",
- limit->thresh_crit_max, VTY_NEWLINE);
-}
-
-static void write_norm_action(struct vty *vty, const char *name, int actions)
-{
- vty_out(vty, " %s%s", name, VTY_NEWLINE);
- vty_out(vty, " %spa0-on%s",
- (actions & SENSOR_ACT_NORM_PA0_ON) ? "" : "no ", VTY_NEWLINE);
- vty_out(vty, " %spa1-on%s",
- (actions & SENSOR_ACT_NORM_PA1_ON) ? "" : "no ", VTY_NEWLINE);
- vty_out(vty, " %sbts-service-on%s",
- (actions & SENSOR_ACT_NORM_BTS_SRV_ON) ? "" : "no ", VTY_NEWLINE);
-}
-
-static void write_action(struct vty *vty, const char *name, int actions)
-{
- vty_out(vty, " %s%s", name, VTY_NEWLINE);
- vty_out(vty, " %spa0-off%s",
- (actions & SENSOR_ACT_PA0_OFF) ? "" : "no ", VTY_NEWLINE);
- vty_out(vty, " %spa1-off%s",
- (actions & SENSOR_ACT_PA1_OFF) ? "" : "no ", VTY_NEWLINE);
- vty_out(vty, " %sbts-service-off%s",
- (actions & SENSOR_ACT_BTS_SRV_OFF) ? "" : "no ", VTY_NEWLINE);
-}
-
-static int config_write_mgr(struct vty *vty)
-{
- vty_out(vty, "lc15bts-mgr%s", VTY_NEWLINE);
-
- write_volt_limit(vty, "limits supply_volt", &s_mgr->volt.supply_volt_limit);
- write_pwr_limit(vty, "limits supply_pwr", &s_mgr->pwr.supply_pwr_limit);
- write_vswr_limit(vty, "limits tx0_vswr", &s_mgr->vswr.tx0_vswr_limit);
- write_vswr_limit(vty, "limits tx1_vswr", &s_mgr->vswr.tx1_vswr_limit);
-
- write_norm_action(vty, "actions normal", s_mgr->state.action_norm);
- write_action(vty, "actions warn", s_mgr->state.action_warn);
- write_action(vty, "actions critical", s_mgr->state.action_crit);
-
- return CMD_SUCCESS;
-}
-
-static int config_write_dummy(struct vty *vty)
-{
- return CMD_SUCCESS;
-}
-
-#define CFG_LIMIT_TEMP(name, expl, switch_to, variable) \
-DEFUN(cfg_limit_##name, cfg_limit_##name##_cmd, \
- "limits " #name, \
- "Configure Limits\n" expl) \
-{ \
- vty->node = switch_to; \
- vty->index = &s_mgr->temp.variable; \
- return CMD_SUCCESS; \
-}
-
-CFG_LIMIT_TEMP(supply_temp, "SUPPLY TEMP\n", LIMIT_SUPPLY_TEMP_NODE, supply_temp_limit)
-CFG_LIMIT_TEMP(soc_temp, "SOC TEMP\n", LIMIT_SOC_NODE, soc_temp_limit)
-CFG_LIMIT_TEMP(fpga_temp, "FPGA TEMP\n", LIMIT_FPGA_NODE, fpga_temp_limit)
-CFG_LIMIT_TEMP(rmsdet_temp, "RMSDET TEMP\n", LIMIT_RMSDET_NODE, rmsdet_temp_limit)
-CFG_LIMIT_TEMP(ocxo_temp, "OCXO TEMP\n", LIMIT_OCXO_NODE, ocxo_temp_limit)
-CFG_LIMIT_TEMP(tx0_temp, "TX0 TEMP\n", LIMIT_TX0_TEMP_NODE, tx0_temp_limit)
-CFG_LIMIT_TEMP(tx1_temp, "TX1 TEMP\n", LIMIT_TX1_TEMP_NODE, tx1_temp_limit)
-CFG_LIMIT_TEMP(pa0_temp, "PA0 TEMP\n", LIMIT_PA0_TEMP_NODE, pa0_temp_limit)
-CFG_LIMIT_TEMP(pa1_temp, "PA1 TEMP\n", LIMIT_PA1_TEMP_NODE, pa1_temp_limit)
-#undef CFG_LIMIT_TEMP
-
-#define CFG_LIMIT_VOLT(name, expl, switch_to, variable) \
-DEFUN(cfg_limit_##name, cfg_limit_##name##_cmd, \
- "limits " #name, \
- "Configure Limits\n" expl) \
-{ \
- vty->node = switch_to; \
- vty->index = &s_mgr->volt.variable; \
- return CMD_SUCCESS; \
-}
-
-CFG_LIMIT_VOLT(supply_volt, "SUPPLY VOLT\n", LIMIT_SUPPLY_VOLT_NODE, supply_volt_limit)
-#undef CFG_LIMIT_VOLT
-
-#define CFG_LIMIT_VSWR(name, expl, switch_to, variable) \
-DEFUN(cfg_limit_##name, cfg_limit_##name##_cmd, \
- "limits " #name, \
- "Configure Limits\n" expl) \
-{ \
- vty->node = switch_to; \
- vty->index = &s_mgr->vswr.variable; \
- return CMD_SUCCESS; \
-}
-
-CFG_LIMIT_VSWR(tx0_vswr, "TX0 VSWR\n", LIMIT_TX0_VSWR_NODE, tx0_vswr_limit)
-CFG_LIMIT_VSWR(tx1_vswr, "TX1 VSWR\n", LIMIT_TX1_VSWR_NODE, tx1_vswr_limit)
-#undef CFG_LIMIT_VSWR
-
-#define CFG_LIMIT_PWR(name, expl, switch_to, variable) \
-DEFUN(cfg_limit_##name, cfg_limit_##name##_cmd, \
- "limits " #name, \
- "Configure Limits\n" expl) \
-{ \
- vty->node = switch_to; \
- vty->index = &s_mgr->pwr.variable; \
- return CMD_SUCCESS; \
-}
-
-CFG_LIMIT_PWR(supply_pwr, "SUPPLY PWR\n", LIMIT_SUPPLY_PWR_NODE, supply_pwr_limit)
-CFG_LIMIT_PWR(pa0_pwr, "PA0 PWR\n", LIMIT_PA0_PWR_NODE, pa0_pwr_limit)
-CFG_LIMIT_PWR(pa1_pwr, "PA1 PWR\n", LIMIT_PA1_PWR_NODE, pa1_pwr_limit)
-#undef CFG_LIMIT_PWR
-
-#define CFG_LIMIT_GPS_FIX(name, expl, switch_to, variable) \
-DEFUN(cfg_limit_##name, cfg_limit_##name##_cmd, \
- "limits " #name, \
- "Configure Limits\n" expl) \
-{ \
- vty->node = switch_to; \
- vty->index = &s_mgr->gps.variable; \
- return CMD_SUCCESS; \
-}
-
-CFG_LIMIT_GPS_FIX(gps_fix, "GPS FIX\n", LIMIT_GPS_FIX_NODE, gps_fix_limit)
-#undef CFG_LIMIT_GPS_FIX
-
-DEFUN(cfg_limit_volt_warn_min, cfg_thresh_volt_warn_min_cmd,
- "threshold warning min <0-48000>",
- "Threshold to reach\n" "Warning level\n" "Range\n")
-{
- struct lc15bts_volt_limit *limit = vty->index;
- limit->thresh_warn_min = atoi(argv[0]);
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_limit_volt_crit_min, cfg_thresh_volt_crit_min_cmd,
- "threshold critical min <0-48000>",
- "Threshold to reach\n" "Critical level\n" "Range\n")
-{
- struct lc15bts_volt_limit *limit = vty->index;
- limit->thresh_crit_min = atoi(argv[0]);
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_limit_vswr_warn_max, cfg_thresh_vswr_warn_max_cmd,
- "threshold warning max <1000-200000>",
- "Threshold to reach\n" "Warning level\n" "Range\n")
-{
- struct lc15bts_vswr_limit *limit = vty->index;
- limit->thresh_warn_max = atoi(argv[0]);
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_limit_vswr_crit_max, cfg_thresh_vswr_crit_max_cmd,
- "threshold critical max <1000-200000>",
- "Threshold to reach\n" "Critical level\n" "Range\n")
-{
- struct lc15bts_vswr_limit *limit = vty->index;
- limit->thresh_crit_max = atoi(argv[0]);
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_limit_pwr_warn_max, cfg_thresh_pwr_warn_max_cmd,
- "threshold warning max <0-200>",
- "Threshold to reach\n" "Warning level\n" "Range\n")
-{
- struct lc15bts_pwr_limit *limit = vty->index;
- limit->thresh_warn_max = atoi(argv[0]);
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_limit_pwr_crit_max, cfg_thresh_pwr_crit_max_cmd,
- "threshold critical max <0-200>",
- "Threshold to reach\n" "Critical level\n" "Range\n")
-{
- struct lc15bts_pwr_limit *limit = vty->index;
- limit->thresh_crit_max = atoi(argv[0]);
- return CMD_SUCCESS;
-}
-
-#define CFG_ACTION(name, expl, switch_to, variable) \
-DEFUN(cfg_action_##name, cfg_action_##name##_cmd, \
- "actions " #name, \
- "Configure Actions\n" expl) \
-{ \
- vty->node = switch_to; \
- vty->index = &s_mgr->state.variable; \
- return CMD_SUCCESS; \
-}
-CFG_ACTION(normal, "Normal Actions\n", ACT_NORM_NODE, action_norm)
-CFG_ACTION(warn, "Warning Actions\n", ACT_WARN_NODE, action_warn)
-CFG_ACTION(critical, "Critical Actions\n", ACT_CRIT_NODE, action_crit)
-#undef CFG_ACTION
-
-DEFUN(cfg_action_pa0_on, cfg_action_pa0_on_cmd,
- "pa0-on",
- "Switch the Power Amplifier #0 on\n")
-{
- int *action = vty->index;
- *action |= SENSOR_ACT_NORM_PA0_ON;
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_no_action_pa0_on, cfg_no_action_pa0_on_cmd,
- "no pa0-on",
- NO_STR "Switch the Power Amplifieri #0 on\n")
-{
- int *action = vty->index;
- *action &= ~SENSOR_ACT_NORM_PA0_ON;
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_action_pa1_on, cfg_action_pa1_on_cmd,
- "pa1-on",
- "Switch the Power Amplifier #1 on\n")
-{
- int *action = vty->index;
- *action |= SENSOR_ACT_NORM_PA1_ON;
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_no_action_pa1_on, cfg_no_action_pa1_on_cmd,
- "no pa1-on",
- NO_STR "Switch the Power Amplifieri #1 on\n")
-{
- int *action = vty->index;
- *action &= ~SENSOR_ACT_NORM_PA1_ON;
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_action_bts_srv_on, cfg_action_bts_srv_on_cmd,
- "bts-service-on",
- "Start the systemd lc15bts.service\n")
-{
- int *action = vty->index;
- *action |= SENSOR_ACT_NORM_BTS_SRV_ON;
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_no_action_bts_srv_on, cfg_no_action_bts_srv_on_cmd,
- "no bts-service-on",
- NO_STR "Start the systemd lc15bts.service\n")
-{
- int *action = vty->index;
- *action &= ~SENSOR_ACT_NORM_BTS_SRV_ON;
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_action_pa0_off, cfg_action_pa0_off_cmd,
- "pa0-off",
- "Switch the Power Amplifier #0 off\n")
-{
- int *action = vty->index;
- *action |= SENSOR_ACT_PA0_OFF;
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_no_action_pa0_off, cfg_no_action_pa0_off_cmd,
- "no pa0-off",
- NO_STR "Do not switch off the Power Amplifier #0\n")
-{
- int *action = vty->index;
- *action &= ~SENSOR_ACT_PA0_OFF;
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_action_pa1_off, cfg_action_pa1_off_cmd,
- "pa1-off",
- "Switch the Power Amplifier #1 off\n")
-{
- int *action = vty->index;
- *action |= SENSOR_ACT_PA1_OFF;
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_no_action_pa1_off, cfg_no_action_pa1_off_cmd,
- "no pa1-off",
- NO_STR "Do not switch off the Power Amplifier #1\n")
-{
- int *action = vty->index;
- *action &= ~SENSOR_ACT_PA1_OFF;
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_action_bts_srv_off, cfg_action_bts_srv_off_cmd,
- "bts-service-off",
- "Stop the systemd lc15bts.service\n")
-{
- int *action = vty->index;
- *action |= SENSOR_ACT_BTS_SRV_OFF;
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_no_action_bts_srv_off, cfg_no_action_bts_srv_off_cmd,
- "no bts-service-off",
- NO_STR "Stop the systemd lc15bts.service\n")
-{
- int *action = vty->index;
- *action &= ~SENSOR_ACT_BTS_SRV_OFF;
- return CMD_SUCCESS;
-}
-
-DEFUN(show_mgr, show_mgr_cmd, "show manager",
- SHOW_STR "Display information about the manager")
-{
- int temp, volt, current, power, vswr;
- vty_out(vty, "Warning alarm flags: 0x%08x%s",
- s_mgr->lc15bts_ctrl.warn_flags, VTY_NEWLINE);
- vty_out(vty, "Critical alarm flags: 0x%08x%s",
- s_mgr->lc15bts_ctrl.crit_flags, VTY_NEWLINE);
- vty_out(vty, "Preventive action retried: %d%s",
- s_mgr->alarms.preventive_retry, VTY_NEWLINE);
- vty_out(vty, "Temperature control state: %s%s",
- lc15bts_mgr_sensor_get_state(s_mgr->state.state), VTY_NEWLINE);
- vty_out(vty, "Current Temperatures%s", VTY_NEWLINE);
- lc15bts_temp_get(LC15BTS_TEMP_SUPPLY, &temp);
- vty_out(vty, " Main Supply : %4.2f Celsius%s",
- temp/ 1000.0f,
- VTY_NEWLINE);
- lc15bts_temp_get(LC15BTS_TEMP_SOC, &temp);
- vty_out(vty, " SoC : %4.2f Celsius%s",
- temp / 1000.0f,
- VTY_NEWLINE);
- lc15bts_temp_get(LC15BTS_TEMP_FPGA, &temp);
- vty_out(vty, " FPGA : %4.2f Celsius%s",
- temp / 1000.0f,
- VTY_NEWLINE);
- lc15bts_temp_get(LC15BTS_TEMP_RMSDET, &temp);
- vty_out(vty, " RMSDet : %4.2f Celsius%s",
- temp / 1000.0f,
- VTY_NEWLINE);
- lc15bts_temp_get(LC15BTS_TEMP_OCXO, &temp);
- vty_out(vty, " OCXO : %4.2f Celsius%s",
- temp / 1000.0f,
- VTY_NEWLINE);
- lc15bts_temp_get(LC15BTS_TEMP_TX0, &temp);
- vty_out(vty, " TX 0 : %4.2f Celsius%s",
- temp / 1000.0f,
- VTY_NEWLINE);
- lc15bts_temp_get(LC15BTS_TEMP_TX1, &temp);
- vty_out(vty, " TX 1 : %4.2f Celsius%s",
- temp / 1000.0f,
- VTY_NEWLINE);
- lc15bts_temp_get(LC15BTS_TEMP_PA0, &temp);
- vty_out(vty, " Power Amp #0: %4.2f Celsius%s",
- temp / 1000.0f,
- VTY_NEWLINE);
- lc15bts_temp_get(LC15BTS_TEMP_PA1, &temp);
- vty_out(vty, " Power Amp #1: %4.2f Celsius%s",
- temp / 1000.0f,
- VTY_NEWLINE);
-
- vty_out(vty, "Power Status%s", VTY_NEWLINE);
- lc15bts_power_sensor_get(LC15BTS_POWER_SUPPLY,
- LC15BTS_POWER_VOLTAGE, &volt);
- lc15bts_power_sensor_get(LC15BTS_POWER_SUPPLY,
- LC15BTS_POWER_CURRENT, &current);
- lc15bts_power_sensor_get(LC15BTS_POWER_SUPPLY,
- LC15BTS_POWER_POWER, &power);
- vty_out(vty, " Main Supply : ON [%6.2f Vdc, %4.2f A, %6.2f W]%s",
- volt /1000.0f,
- current /1000.0f,
- power /1000000.0f,
- VTY_NEWLINE);
- lc15bts_power_sensor_get(LC15BTS_POWER_PA0,
- LC15BTS_POWER_VOLTAGE, &volt);
- lc15bts_power_sensor_get(LC15BTS_POWER_PA0,
- LC15BTS_POWER_CURRENT, &current);
- lc15bts_power_sensor_get(LC15BTS_POWER_PA0,
- LC15BTS_POWER_POWER, &power);
- vty_out(vty, " Power Amp #0: %s [%6.2f Vdc, %4.2f A, %6.2f W]%s",
- lc15bts_power_get(LC15BTS_POWER_PA0) ? "ON " : "OFF",
- volt /1000.0f,
- current /1000.0f,
- power /1000000.0f,
- VTY_NEWLINE);
- lc15bts_power_sensor_get(LC15BTS_POWER_PA1,
- LC15BTS_POWER_VOLTAGE, &volt);
- lc15bts_power_sensor_get(LC15BTS_POWER_PA1,
- LC15BTS_POWER_CURRENT, &current);
- lc15bts_power_sensor_get(LC15BTS_POWER_PA1,
- LC15BTS_POWER_POWER, &power);
- vty_out(vty, " Power Amp #1: %s [%6.2f Vdc, %4.2f A, %6.2f W]%s",
- lc15bts_power_get(LC15BTS_POWER_PA1) ? "ON " : "OFF",
- volt /1000.0f,
- current /1000.0f,
- power /1000000.0f,
- VTY_NEWLINE);
- vty_out(vty, "VSWR Status%s", VTY_NEWLINE);
- lc15bts_vswr_get(LC15BTS_VSWR_TX0, &vswr);
- vty_out(vty, " VSWR TX 0: %f %s",
- vswr / 1000.0f,
- VTY_NEWLINE);
- lc15bts_vswr_get(LC15BTS_VSWR_TX1, &vswr);
- vty_out(vty, " VSWR TX 1: %f %s",
- vswr / 1000.0f,
- VTY_NEWLINE);
-
- return CMD_SUCCESS;
-}
-
-DEFUN(show_thresh, show_thresh_cmd, "show thresholds",
- SHOW_STR "Display information about the thresholds")
-{
- vty_out(vty, "Temperature limits (Celsius)%s", VTY_NEWLINE);
- vty_out(vty, " Main supply%s", VTY_NEWLINE);
- vty_out(vty, " Critical max : %d%s",s_mgr->temp.supply_temp_limit.thresh_crit_max, VTY_NEWLINE);
- vty_out(vty, " Warning max : %d%s",s_mgr->temp.supply_temp_limit.thresh_warn_max, VTY_NEWLINE);
- vty_out(vty, " Warning min : %d%s",s_mgr->temp.supply_temp_limit.thresh_warn_min, VTY_NEWLINE);
- vty_out(vty, " SoC%s", VTY_NEWLINE);
- vty_out(vty, " Critical max : %d%s",s_mgr->temp.soc_temp_limit.thresh_crit_max, VTY_NEWLINE);
- vty_out(vty, " Warning max : %d%s",s_mgr->temp.soc_temp_limit.thresh_warn_max, VTY_NEWLINE);
- vty_out(vty, " Warning min : %d%s",s_mgr->temp.soc_temp_limit.thresh_warn_min, VTY_NEWLINE);
- vty_out(vty, " FPGA%s", VTY_NEWLINE);
- vty_out(vty, " Critical max : %d%s",s_mgr->temp.fpga_temp_limit.thresh_crit_max, VTY_NEWLINE);
- vty_out(vty, " Warning max : %d%s",s_mgr->temp.fpga_temp_limit.thresh_warn_max, VTY_NEWLINE);
- vty_out(vty, " Warning min : %d%s",s_mgr->temp.fpga_temp_limit.thresh_warn_min, VTY_NEWLINE);
- vty_out(vty, " RMSDet%s", VTY_NEWLINE);
- vty_out(vty, " Critical max : %d%s",s_mgr->temp.rmsdet_temp_limit.thresh_crit_max, VTY_NEWLINE);
- vty_out(vty, " Warning max : %d%s",s_mgr->temp.rmsdet_temp_limit.thresh_warn_max, VTY_NEWLINE);
- vty_out(vty, " Warning min : %d%s",s_mgr->temp.rmsdet_temp_limit.thresh_warn_min, VTY_NEWLINE);
- vty_out(vty, " OCXO%s", VTY_NEWLINE);
- vty_out(vty, " Critical max : %d%s",s_mgr->temp.ocxo_temp_limit.thresh_crit_max, VTY_NEWLINE);
- vty_out(vty, " Warning max : %d%s",s_mgr->temp.ocxo_temp_limit.thresh_warn_max, VTY_NEWLINE);
- vty_out(vty, " Warning min : %d%s",s_mgr->temp.ocxo_temp_limit.thresh_warn_min, VTY_NEWLINE);
- vty_out(vty, " TX0%s", VTY_NEWLINE);
- vty_out(vty, " Critical max : %d%s",s_mgr->temp.tx0_temp_limit.thresh_crit_max, VTY_NEWLINE);
- vty_out(vty, " Warning max : %d%s",s_mgr->temp.tx0_temp_limit.thresh_warn_max, VTY_NEWLINE);
- vty_out(vty, " Warning min : %d%s",s_mgr->temp.tx0_temp_limit.thresh_warn_min, VTY_NEWLINE);
- vty_out(vty, " TX1%s", VTY_NEWLINE);
- vty_out(vty, " Critical max : %d%s",s_mgr->temp.tx1_temp_limit.thresh_crit_max, VTY_NEWLINE);
- vty_out(vty, " Warning max : %d%s",s_mgr->temp.tx1_temp_limit.thresh_warn_max, VTY_NEWLINE);
- vty_out(vty, " Warning min : %d%s",s_mgr->temp.tx1_temp_limit.thresh_warn_min, VTY_NEWLINE);
- vty_out(vty, " PA0%s", VTY_NEWLINE);
- vty_out(vty, " Critical max : %d%s",s_mgr->temp.pa0_temp_limit.thresh_crit_max, VTY_NEWLINE);
- vty_out(vty, " Warning max : %d%s",s_mgr->temp.pa0_temp_limit.thresh_warn_max, VTY_NEWLINE);
- vty_out(vty, " Warning min : %d%s",s_mgr->temp.pa0_temp_limit.thresh_warn_min, VTY_NEWLINE);
- vty_out(vty, " PA1%s", VTY_NEWLINE);
- vty_out(vty, " Critical max : %d%s",s_mgr->temp.pa1_temp_limit.thresh_crit_max, VTY_NEWLINE);
- vty_out(vty, " Warning max : %d%s",s_mgr->temp.pa1_temp_limit.thresh_warn_max, VTY_NEWLINE);
- vty_out(vty, " Warning min : %d%s",s_mgr->temp.pa1_temp_limit.thresh_warn_min, VTY_NEWLINE);
- vty_out(vty, "Power limits%s", VTY_NEWLINE);
- vty_out(vty, " Main supply (mV)%s", VTY_NEWLINE);
- vty_out(vty, " Critical max : %d%s",s_mgr->volt.supply_volt_limit.thresh_crit_max, VTY_NEWLINE);
- vty_out(vty, " Warning max : %d%s",s_mgr->volt.supply_volt_limit.thresh_warn_max, VTY_NEWLINE);
- vty_out(vty, " Warning min : %d%s",s_mgr->volt.supply_volt_limit.thresh_warn_min, VTY_NEWLINE);
- vty_out(vty, " Critical min : %d%s",s_mgr->volt.supply_volt_limit.thresh_crit_min, VTY_NEWLINE);
- vty_out(vty, " Main supply power (W)%s", VTY_NEWLINE);
- vty_out(vty, " Critical max : %d%s",s_mgr->pwr.supply_pwr_limit.thresh_crit_max, VTY_NEWLINE);
- vty_out(vty, " Warning max : %d%s",s_mgr->pwr.supply_pwr_limit.thresh_warn_max, VTY_NEWLINE);
- vty_out(vty, " PA0 power (W)%s", VTY_NEWLINE);
- vty_out(vty, " Critical max : %d%s",s_mgr->pwr.pa0_pwr_limit.thresh_crit_max, VTY_NEWLINE);
- vty_out(vty, " Warning max : %d%s",s_mgr->pwr.pa0_pwr_limit.thresh_warn_max, VTY_NEWLINE);
- vty_out(vty, " PA1 power (W)%s", VTY_NEWLINE);
- vty_out(vty, " Critical max : %d%s",s_mgr->pwr.pa1_pwr_limit.thresh_crit_max, VTY_NEWLINE);
- vty_out(vty, " Warning max : %d%s",s_mgr->pwr.pa1_pwr_limit.thresh_warn_max, VTY_NEWLINE);
- vty_out(vty, "VSWR limits%s", VTY_NEWLINE);
- vty_out(vty, " TX0%s", VTY_NEWLINE);
- vty_out(vty, " Critical max : %d%s",s_mgr->vswr.tx0_vswr_limit.thresh_crit_max, VTY_NEWLINE);
- vty_out(vty, " Warning max : %d%s",s_mgr->vswr.tx0_vswr_limit.thresh_warn_max, VTY_NEWLINE);
- vty_out(vty, " TX1%s", VTY_NEWLINE);
- vty_out(vty, " Critical max : %d%s",s_mgr->vswr.tx1_vswr_limit.thresh_crit_max, VTY_NEWLINE);
- vty_out(vty, " Warning max : %d%s",s_mgr->vswr.tx1_vswr_limit.thresh_warn_max, VTY_NEWLINE);
- vty_out(vty, "Days since last GPS 3D fix%s", VTY_NEWLINE);
- vty_out(vty, " Warning max : %d%s",s_mgr->gps.gps_fix_limit.thresh_warn_max, VTY_NEWLINE);
-
- return CMD_SUCCESS;
-}
-
-DEFUN(calibrate_clock, calibrate_clock_cmd,
- "calibrate clock",
- "Calibration commands\n"
- "Calibrate clock against GPS PPS\n")
-{
- if (lc15bts_mgr_calib_run(s_mgr) < 0) {
- vty_out(vty, "%%Failed to start calibration.%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
- return CMD_SUCCESS;
-}
-
-DEFUN(set_led_pattern, set_led_pattern_cmd,
- "set led pattern <0-255>",
- "Set LED pattern\n"
- "Set LED pattern for debugging purpose only. This pattern will be overridden after 60 seconds by LED pattern of actual system state\n")
-{
- int pattern_id = atoi(argv[0]);
-
- if ((pattern_id < 0) || (pattern_id > BLINK_PATTERN_MAX_ITEM)) {
- vty_out(vty, "%%Invalid LED pattern ID. It must be in range of %d..%d %s", 0, BLINK_PATTERN_MAX_ITEM - 1, VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- led_set(s_mgr, pattern_id);
- return CMD_SUCCESS;
-}
-
-DEFUN(force_mgr_state, force_mgr_state_cmd,
- "force manager state <0-255>",
- "Force BTS manager state\n"
- "Force BTS manager state for debugging purpose only\n")
-{
- int state = atoi(argv[0]);
-
- if ((state < 0) || (state > STATE_CRITICAL)) {
- vty_out(vty, "%%Invalid BTS manager state. It must be in range of %d..%d %s", 0, STATE_CRITICAL, VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- s_mgr->state.state = state;
- return CMD_SUCCESS;
-}
-
-#define LIMIT_TEMP(name, limit, expl, variable, criticity, min_max) \
-DEFUN(limit_temp_##name##_##variable, limit_temp_##name##_##variable##_cmd, \
- "limit temp " #name " " #criticity " " #min_max " <-200-200>", \
- "Limit to reach\n" expl) \
-{ \
- s_mgr->temp.limit.variable = atoi(argv[0]); \
- return CMD_SUCCESS; \
-}
-
-LIMIT_TEMP(supply, supply_temp_limit, "SUPPLY TEMP\n", thresh_warn_max, warning, max)
-LIMIT_TEMP(supply, supply_temp_limit, "SUPPLY TEMP\n", thresh_crit_max, critical, max)
-LIMIT_TEMP(supply, supply_temp_limit, "SUPPLY TEMP\n", thresh_warn_min, warning, min)
-LIMIT_TEMP(soc, supply_temp_limit, "SOC TEMP\n", thresh_warn_max, warning, max)
-LIMIT_TEMP(soc, supply_temp_limit, "SOC TEMP\n", thresh_crit_max, critical, max)
-LIMIT_TEMP(soc, supply_temp_limit, "SOC TEMP\n", thresh_warn_min, warning, min)
-LIMIT_TEMP(fpga, fpga_temp_limit, "FPGA TEMP\n", thresh_warn_max, warning, max)
-LIMIT_TEMP(fpga, fpga_temp_limit, "FPGA TEMP\n", thresh_crit_max, critical, max)
-LIMIT_TEMP(fpga, fpga_temp_limit, "FPGA TEMP\n", thresh_warn_min, warning, min)
-LIMIT_TEMP(rmsdet, rmsdet_temp_limit, "RMSDET TEMP\n", thresh_warn_max, warning, max)
-LIMIT_TEMP(rmsdet, rmsdet_temp_limit, "RMSDET TEMP\n", thresh_crit_max, critical, max)
-LIMIT_TEMP(rmsdet, rmsdet_temp_limit, "RMSDET TEMP\n", thresh_warn_min, warning, min)
-LIMIT_TEMP(ocxo, ocxo_temp_limit, "OCXO TEMP\n", thresh_warn_max, warning, max)
-LIMIT_TEMP(ocxo, ocxo_temp_limit, "OCXO TEMP\n", thresh_crit_max, critical, max)
-LIMIT_TEMP(ocxo, ocxo_temp_limit, "OCXO TEMP\n", thresh_warn_min, warning, min)
-LIMIT_TEMP(tx0, tx0_temp_limit, "TX0 TEMP\n", thresh_warn_max, warning, max)
-LIMIT_TEMP(tx0, tx0_temp_limit, "TX0 TEMP\n", thresh_crit_max, critical, max)
-LIMIT_TEMP(tx0, tx0_temp_limit, "TX0 TEMP\n", thresh_warn_min, warning, min)
-LIMIT_TEMP(tx1, tx1_temp_limit, "TX1 TEMP\n", thresh_warn_max, warning, max)
-LIMIT_TEMP(tx1, tx1_temp_limit, "TX1 TEMP\n", thresh_crit_max, critical, max)
-LIMIT_TEMP(tx1, tx1_temp_limit, "TX1 TEMP\n", thresh_warn_min, warning, min)
-LIMIT_TEMP(pa0, pa0_temp_limit, "PA0 TEMP\n", thresh_warn_max, warning, max)
-LIMIT_TEMP(pa0, pa0_temp_limit, "PA0 TEMP\n", thresh_crit_max, critical, max)
-LIMIT_TEMP(pa0, pa0_temp_limit, "PA0 TEMP\n", thresh_warn_min, warning, min)
-LIMIT_TEMP(pa1, pa1_temp_limit, "PA1 TEMP\n", thresh_warn_max, warning, max)
-LIMIT_TEMP(pa1, pa1_temp_limit, "PA1 TEMP\n", thresh_crit_max, critical, max)
-LIMIT_TEMP(pa1, pa1_temp_limit, "PA1 TEMP\n", thresh_warn_min, warning, min)
-#undef LIMIT_TEMP
-
-#define LIMIT_VOLT(name, limit, expl, variable, criticity, min_max) \
-DEFUN(limit_volt_##name##_##variable, limit_volt_##name##_##variable##_cmd, \
- "limit " #name " " #criticity " " #min_max " <0-48000>", \
- "Limit to reach\n" expl) \
-{ \
- s_mgr->volt.limit.variable = atoi(argv[0]); \
- return CMD_SUCCESS; \
-}
-
-LIMIT_VOLT(supply, supply_volt_limit, "SUPPLY VOLT\n", thresh_warn_max, warning, max)
-LIMIT_VOLT(supply, supply_volt_limit, "SUPPLY VOLT\n", thresh_crit_max, critical, max)
-LIMIT_VOLT(supply, supply_volt_limit, "SUPPLY VOLT\n", thresh_warn_min, warning, min)
-LIMIT_VOLT(supply, supply_volt_limit, "SUPPLY VOLT\n", thresh_crit_min, critical, min)
-#undef LIMIT_VOLT
-
-#define LIMIT_PWR(name, limit, expl, variable, criticity, min_max) \
- DEFUN(limit_pwr_##name##_##variable, limit_pwr_##name##_##variable##_cmd, \
- "limit power " #name " " #criticity " " #min_max " <0-200>", \
- "Limit to reach\n" expl) \
-{ \
- s_mgr->pwr.limit.variable = atoi(argv[0]); \
- return CMD_SUCCESS; \
-}
-
-LIMIT_PWR(supply, supply_pwr_limit, "SUPPLY PWR\n", thresh_warn_max, warning, max)
-LIMIT_PWR(supply, supply_pwr_limit, "SUPPLY PWR\n", thresh_crit_max, critical, max)
-LIMIT_PWR(pa0, pa0_pwr_limit, "PA0 PWR\n", thresh_warn_max, warning, max)
-LIMIT_PWR(pa0, pa0_pwr_limit, "PA0 PWR\n", thresh_crit_max, critical, max)
-LIMIT_PWR(pa1, pa1_pwr_limit, "PA1 PWR\n", thresh_warn_max, warning, max)
-LIMIT_PWR(pa1, pa1_pwr_limit, "PA1 PWR\n", thresh_crit_max, critical, max)
-#undef LIMIT_PWR
-
-#define LIMIT_VSWR(name, limit, expl, variable, criticity, min_max) \
-DEFUN(limit_vswr_##name##_##variable, limit_vswr_##name##_##variable##_cmd, \
- "limit vswr " #name " " #criticity " " #min_max " <1000-200000>", \
- "Limit to reach\n" expl) \
-{ \
- s_mgr->vswr.limit.variable = atoi(argv[0]); \
- return CMD_SUCCESS; \
-}
-
-LIMIT_VSWR(tx0, tx0_vswr_limit, "TX0 VSWR\n", thresh_warn_max, warning, max)
-LIMIT_VSWR(tx0, tx0_vswr_limit, "TX0 VSWR\n", thresh_crit_max, critical, max)
-LIMIT_VSWR(tx1, tx1_vswr_limit, "TX1 VSWR\n", thresh_warn_max, warning, max)
-LIMIT_VSWR(tx1, tx1_vswr_limit, "TX1 VSWR\n", thresh_crit_max, critical, max)
-#undef LIMIT_VSWR
-
-#define LIMIT_GPSFIX(limit, expl, variable, criticity, min_max) \
-DEFUN(limit_gpsfix_##variable, limit_gpsfix_##variable##_cmd, \
- "limit gpsfix " #criticity " " #min_max " <0-365>", \
- "Limit to reach\n" expl) \
-{ \
- s_mgr->gps.limit.variable = atoi(argv[0]); \
- return CMD_SUCCESS; \
-}
-
-LIMIT_GPSFIX(gps_fix_limit, "GPS FIX\n", thresh_warn_max, warning, max)
-#undef LIMIT_GPSFIX
-
-static void register_limit(int limit, uint32_t unit)
-{
- switch (unit) {
- case MGR_LIMIT_TYPE_VOLT:
- install_element(limit, &cfg_thresh_volt_warn_min_cmd);
- install_element(limit, &cfg_thresh_volt_crit_min_cmd);
- break;
- case MGR_LIMIT_TYPE_VSWR:
- install_element(limit, &cfg_thresh_vswr_warn_max_cmd);
- install_element(limit, &cfg_thresh_vswr_crit_max_cmd);
- break;
- case MGR_LIMIT_TYPE_PWR:
- install_element(limit, &cfg_thresh_pwr_warn_max_cmd);
- install_element(limit, &cfg_thresh_pwr_crit_max_cmd);
- break;
- default:
- break;
- }
-}
-
-static void register_normal_action(int act)
-{
- install_element(act, &cfg_action_pa0_on_cmd);
- install_element(act, &cfg_no_action_pa0_on_cmd);
- install_element(act, &cfg_action_pa1_on_cmd);
- install_element(act, &cfg_no_action_pa1_on_cmd);
- install_element(act, &cfg_action_bts_srv_on_cmd);
- install_element(act, &cfg_no_action_bts_srv_on_cmd);
-}
-
-static void register_action(int act)
-{
- install_element(act, &cfg_action_pa0_off_cmd);
- install_element(act, &cfg_no_action_pa0_off_cmd);
- install_element(act, &cfg_action_pa1_off_cmd);
- install_element(act, &cfg_no_action_pa1_off_cmd);
- install_element(act, &cfg_action_bts_srv_off_cmd);
- install_element(act, &cfg_no_action_bts_srv_off_cmd);
-}
-
-static void register_hidden_commands()
-{
- install_element(ENABLE_NODE, &limit_temp_supply_thresh_warn_max_cmd);
- install_element(ENABLE_NODE, &limit_temp_supply_thresh_crit_max_cmd);
- install_element(ENABLE_NODE, &limit_temp_supply_thresh_warn_min_cmd);
- install_element(ENABLE_NODE, &limit_temp_soc_thresh_warn_max_cmd);
- install_element(ENABLE_NODE, &limit_temp_soc_thresh_crit_max_cmd);
- install_element(ENABLE_NODE, &limit_temp_soc_thresh_warn_min_cmd);
- install_element(ENABLE_NODE, &limit_temp_fpga_thresh_warn_max_cmd);
- install_element(ENABLE_NODE, &limit_temp_fpga_thresh_crit_max_cmd);
- install_element(ENABLE_NODE, &limit_temp_fpga_thresh_warn_min_cmd);
- install_element(ENABLE_NODE, &limit_temp_rmsdet_thresh_warn_max_cmd);
- install_element(ENABLE_NODE, &limit_temp_rmsdet_thresh_crit_max_cmd);
- install_element(ENABLE_NODE, &limit_temp_rmsdet_thresh_warn_min_cmd);
- install_element(ENABLE_NODE, &limit_temp_ocxo_thresh_warn_max_cmd);
- install_element(ENABLE_NODE, &limit_temp_ocxo_thresh_crit_max_cmd);
- install_element(ENABLE_NODE, &limit_temp_ocxo_thresh_warn_min_cmd);
- install_element(ENABLE_NODE, &limit_temp_tx0_thresh_warn_max_cmd);
- install_element(ENABLE_NODE, &limit_temp_tx0_thresh_crit_max_cmd);
- install_element(ENABLE_NODE, &limit_temp_tx0_thresh_warn_min_cmd);
- install_element(ENABLE_NODE, &limit_temp_tx1_thresh_warn_max_cmd);
- install_element(ENABLE_NODE, &limit_temp_tx1_thresh_crit_max_cmd);
- install_element(ENABLE_NODE, &limit_temp_tx1_thresh_warn_min_cmd);
- install_element(ENABLE_NODE, &limit_temp_pa0_thresh_warn_max_cmd);
- install_element(ENABLE_NODE, &limit_temp_pa0_thresh_crit_max_cmd);
- install_element(ENABLE_NODE, &limit_temp_pa0_thresh_warn_min_cmd);
- install_element(ENABLE_NODE, &limit_temp_pa1_thresh_warn_max_cmd);
- install_element(ENABLE_NODE, &limit_temp_pa1_thresh_crit_max_cmd);
- install_element(ENABLE_NODE, &limit_temp_pa1_thresh_warn_min_cmd);
-
- install_element(ENABLE_NODE, &limit_volt_supply_thresh_warn_max_cmd);
- install_element(ENABLE_NODE, &limit_volt_supply_thresh_crit_max_cmd);
- install_element(ENABLE_NODE, &limit_volt_supply_thresh_warn_min_cmd);
- install_element(ENABLE_NODE, &limit_volt_supply_thresh_crit_min_cmd);
-
- install_element(ENABLE_NODE, &limit_pwr_supply_thresh_warn_max_cmd);
- install_element(ENABLE_NODE, &limit_pwr_supply_thresh_crit_max_cmd);
- install_element(ENABLE_NODE, &limit_pwr_pa0_thresh_warn_max_cmd);
- install_element(ENABLE_NODE, &limit_pwr_pa0_thresh_crit_max_cmd);
- install_element(ENABLE_NODE, &limit_pwr_pa1_thresh_warn_max_cmd);
- install_element(ENABLE_NODE, &limit_pwr_pa1_thresh_crit_max_cmd);
-
- install_element(ENABLE_NODE, &limit_vswr_tx0_thresh_warn_max_cmd);
- install_element(ENABLE_NODE, &limit_vswr_tx0_thresh_crit_max_cmd);
- install_element(ENABLE_NODE, &limit_vswr_tx1_thresh_warn_max_cmd);
- install_element(ENABLE_NODE, &limit_vswr_tx1_thresh_crit_max_cmd);
-
- install_element(ENABLE_NODE, &limit_gpsfix_thresh_warn_max_cmd);
-}
-
-int lc15bts_mgr_vty_init(void)
-{
- vty_init(&vty_info);
-
- install_element_ve(&show_mgr_cmd);
- install_element_ve(&show_thresh_cmd);
-
- install_element(ENABLE_NODE, &calibrate_clock_cmd);
-
- install_node(&mgr_node, config_write_mgr);
- install_element(CONFIG_NODE, &cfg_mgr_cmd);
-
- /* install the limit nodes */
- install_node(&limit_supply_temp_node, config_write_dummy);
- install_element(MGR_NODE, &cfg_limit_supply_temp_cmd);
-
- install_node(&limit_soc_node, config_write_dummy);
- install_element(MGR_NODE, &cfg_limit_soc_temp_cmd);
-
- install_node(&limit_fpga_node, config_write_dummy);
- install_element(MGR_NODE, &cfg_limit_fpga_temp_cmd);
-
- install_node(&limit_rmsdet_node, config_write_dummy);
- install_element(MGR_NODE, &cfg_limit_rmsdet_temp_cmd);
-
- install_node(&limit_ocxo_node, config_write_dummy);
- install_element(MGR_NODE, &cfg_limit_ocxo_temp_cmd);
-
- install_node(&limit_tx0_temp_node, config_write_dummy);
- install_element(MGR_NODE, &cfg_limit_tx0_temp_cmd);
-
- install_node(&limit_tx1_temp_node, config_write_dummy);
- install_element(MGR_NODE, &cfg_limit_tx1_temp_cmd);
-
- install_node(&limit_pa0_temp_node, config_write_dummy);
- install_element(MGR_NODE, &cfg_limit_pa0_temp_cmd);
-
- install_node(&limit_pa1_temp_node, config_write_dummy);
- install_element(MGR_NODE, &cfg_limit_pa1_temp_cmd);
-
- install_node(&limit_supply_volt_node, config_write_dummy);
- install_element(MGR_NODE, &cfg_limit_supply_volt_cmd);
- register_limit(LIMIT_SUPPLY_VOLT_NODE, MGR_LIMIT_TYPE_VOLT);
-
- install_node(&limit_tx0_vswr_node, config_write_dummy);
- install_element(MGR_NODE, &cfg_limit_tx0_vswr_cmd);
- register_limit(LIMIT_TX0_VSWR_NODE, MGR_LIMIT_TYPE_VSWR);
-
- install_node(&limit_tx1_vswr_node, config_write_dummy);
- install_element(MGR_NODE, &cfg_limit_tx1_vswr_cmd);
- register_limit(LIMIT_TX1_VSWR_NODE, MGR_LIMIT_TYPE_VSWR);
-
- install_node(&limit_supply_pwr_node, config_write_dummy);
- install_element(MGR_NODE, &cfg_limit_supply_pwr_cmd);
- register_limit(LIMIT_SUPPLY_PWR_NODE, MGR_LIMIT_TYPE_PWR);
-
- install_node(&limit_pa0_pwr_node, config_write_dummy);
- install_element(MGR_NODE, &cfg_limit_pa0_pwr_cmd);
- register_limit(LIMIT_PA0_PWR_NODE, MGR_LIMIT_TYPE_PWR);
-
- install_node(&limit_pa1_pwr_node, config_write_dummy);
- install_element(MGR_NODE, &cfg_limit_pa1_pwr_cmd);
- register_limit(LIMIT_PA1_PWR_NODE, MGR_LIMIT_TYPE_PWR);
-
- install_node(&limit_gps_fix_node, config_write_dummy);
- install_element(MGR_NODE, &cfg_limit_gps_fix_cmd);
-
- /* install the normal node */
- install_node(&act_norm_node, config_write_dummy);
- install_element(MGR_NODE, &cfg_action_normal_cmd);
- register_normal_action(ACT_NORM_NODE);
-
- /* install the warning and critical node */
- install_node(&act_warn_node, config_write_dummy);
- install_element(MGR_NODE, &cfg_action_warn_cmd);
- register_action(ACT_WARN_NODE);
-
- install_node(&act_crit_node, config_write_dummy);
- install_element(MGR_NODE, &cfg_action_critical_cmd);
- register_action(ACT_CRIT_NODE);
-
- /* install LED pattern command for debugging purpose */
- install_element_ve(&set_led_pattern_cmd);
- install_element_ve(&force_mgr_state_cmd);
-
- register_hidden_commands();
-
- return 0;
-}
-
-int lc15bts_mgr_parse_config(struct lc15bts_mgr_instance *manager)
-{
- int rc;
-
- s_mgr = manager;
- rc = vty_read_config_file(s_mgr->config_file, NULL);
- if (rc < 0) {
- fprintf(stderr, "Failed to parse the config file: '%s'\n",
- s_mgr->config_file);
- return rc;
- }
-
- return 0;
-}
diff --git a/src/osmo-bts-litecell15/misc/lc15bts_misc.c b/src/osmo-bts-litecell15/misc/lc15bts_misc.c
deleted file mode 100644
index 467b9d0a..00000000
--- a/src/osmo-bts-litecell15/misc/lc15bts_misc.c
+++ /dev/null
@@ -1,383 +0,0 @@
-/* Copyright (C) 2015 by Yves Godin <support@nuranwireless.com>
- *
- * Based on sysmoBTS:
- * sysmobts_misc.c
- * (C) 2012 by Harald Welte <laforge@gnumonks.org>
- *
- * 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 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/licenses/>.
- *
- */
-
-#include <stdint.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <getopt.h>
-#include <fcntl.h>
-#include <limits.h>
-#include <time.h>
-#include <sys/signal.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-
-#include <osmocom/core/talloc.h>
-#include <osmocom/core/utils.h>
-#include <osmocom/core/msgb.h>
-#include <osmocom/core/application.h>
-#include <osmocom/vty/telnet_interface.h>
-#include <osmocom/vty/logging.h>
-
-#include "lc15bts_mgr.h"
-#include "btsconfig.h"
-#include "lc15bts_misc.h"
-#include "lc15bts_par.h"
-#include "lc15bts_mgr.h"
-#include "lc15bts_temp.h"
-#include "lc15bts_power.h"
-
-/*********************************************************************
- * Temperature handling
- *********************************************************************/
-
-static const struct {
- const char *name;
- int has_max;
- enum lc15bts_temp_sensor sensor;
- enum lc15bts_par ee_par;
-} temp_data[] = {
- {
- .name = "supply_temp",
- .has_max = 1,
- .sensor = LC15BTS_TEMP_SUPPLY,
- .ee_par = LC15BTS_PAR_TEMP_SUPPLY_MAX,
- }, {
- .name = "soc_temp",
- .has_max = 0,
- .sensor = LC15BTS_TEMP_SOC,
- .ee_par = LC15BTS_PAR_TEMP_SOC_MAX,
- }, {
- .name = "fpga_temp",
- .has_max = 0,
- .sensor = LC15BTS_TEMP_FPGA,
- .ee_par = LC15BTS_PAR_TEMP_FPGA_MAX,
-
- }, {
- .name = "rmsdet_temp",
- .has_max = 1,
- .sensor = LC15BTS_TEMP_RMSDET,
- .ee_par = LC15BTS_PAR_TEMP_RMSDET_MAX,
- }, {
- .name = "ocxo_temp",
- .has_max = 1,
- .sensor = LC15BTS_TEMP_OCXO,
- .ee_par = LC15BTS_PAR_TEMP_OCXO_MAX,
- }, {
- .name = "tx0_temp",
- .has_max = 0,
- .sensor = LC15BTS_TEMP_TX0,
- .ee_par = LC15BTS_PAR_TEMP_TX0_MAX,
- }, {
- .name = "tx1_temp",
- .has_max = 0,
- .sensor = LC15BTS_TEMP_TX1,
- .ee_par = LC15BTS_PAR_TEMP_TX1_MAX,
- }, {
- .name = "pa0_temp",
- .has_max = 1,
- .sensor = LC15BTS_TEMP_PA0,
- .ee_par = LC15BTS_PAR_TEMP_PA0_MAX,
- }, {
- .name = "pa1_temp",
- .has_max = 1,
- .sensor = LC15BTS_TEMP_PA1,
- .ee_par = LC15BTS_PAR_TEMP_PA1_MAX,
- }
-};
-
-static const struct {
- const char *name;
- int has_max;
- enum lc15bts_power_source sensor_source;
- enum lc15bts_power_type sensor_type;
- enum lc15bts_par ee_par;
-} power_data[] = {
- {
- .name = "supply_volt",
- .has_max = 1,
- .sensor_source = LC15BTS_POWER_SUPPLY,
- .sensor_type = LC15BTS_POWER_VOLTAGE,
- .ee_par = LC15BTS_PAR_VOLT_SUPPLY_MAX,
- }, {
- .name = "supply_pwr",
- .has_max = 1,
- .sensor_source = LC15BTS_POWER_SUPPLY,
- .sensor_type = LC15BTS_POWER_POWER,
- .ee_par = LC15BTS_PAR_PWR_SUPPLY_MAX,
- }, {
- .name = "pa0_pwr",
- .has_max = 1,
- .sensor_source = LC15BTS_POWER_PA0,
- .sensor_type = LC15BTS_POWER_POWER,
- .ee_par = LC15BTS_PAR_PWR_PA0_MAX,
- }, {
- .name = "pa1_pwr",
- .has_max = 1,
- .sensor_source = LC15BTS_POWER_PA1,
- .sensor_type = LC15BTS_POWER_POWER,
- .ee_par = LC15BTS_PAR_PWR_PA1_MAX,
- }
-};
-
-static const struct {
- const char *name;
- int has_max;
- enum lc15bts_vswr_sensor sensor;
- enum lc15bts_par ee_par;
-} vswr_data[] = {
- {
- .name = "tx0_vswr",
- .has_max = 0,
- .sensor = LC15BTS_VSWR_TX0,
- .ee_par = LC15BTS_PAR_VSWR_TX0_MAX,
- }, {
- .name = "tx1_vswr",
- .has_max = 0,
- .sensor = LC15BTS_VSWR_TX1,
- .ee_par = LC15BTS_PAR_VSWR_TX1_MAX,
- }
-};
-
-static const struct value_string power_unit_strs[] = {
- { LC15BTS_POWER_POWER, "W" },
- { LC15BTS_POWER_VOLTAGE, "V" },
- { 0, NULL }
-};
-
-void lc15bts_check_temp(int no_rom_write)
-{
- int temp_old[ARRAY_SIZE(temp_data)];
- int temp_cur[ARRAY_SIZE(temp_data)];
- int i, rc;
-
- for (i = 0; i < ARRAY_SIZE(temp_data); i++) {
- int ret;
- rc = lc15bts_par_get_int(tall_mgr_ctx, temp_data[i].ee_par, &ret);
- temp_old[i] = ret * 1000;
-
- lc15bts_temp_get(temp_data[i].sensor, &temp_cur[i]);
- if (temp_cur[i] < 0 && temp_cur[i] > -1000) {
- LOGP(DTEMP, LOGL_ERROR, "Error reading temperature (%d): unexpected value %d\n",
- temp_data[i].sensor, temp_cur[i]);
- continue;
- }
-
- LOGP(DTEMP, LOGL_DEBUG, "Current %s temperature: %d.%d C\n",
- temp_data[i].name, temp_cur[i]/1000, temp_cur[i]%1000);
-
- if (temp_cur[i] > temp_old[i]) {
- LOGP(DTEMP, LOGL_NOTICE, "New maximum %s "
- "temperature: %d.%d C\n", temp_data[i].name,
- temp_cur[i]/1000, temp_old[i]%1000);
-
- if (!no_rom_write) {
- rc = lc15bts_par_set_int(tall_mgr_ctx, temp_data[i].ee_par, temp_cur[i]/1000);
- if (rc < 0)
- LOGP(DTEMP, LOGL_ERROR, "error writing new %s "
- "max temp %d (%s)\n", temp_data[i].name,
- rc, strerror(errno));
- }
- }
- }
-}
-
-void lc15bts_check_power(int no_rom_write)
-{
- int power_old[ARRAY_SIZE(power_data)];
- int power_cur[ARRAY_SIZE(power_data)];
- int i, rc;
- int div_ratio;
-
- for (i = 0; i < ARRAY_SIZE(power_data); i++) {
- int ret;
- rc = lc15bts_par_get_int(tall_mgr_ctx, power_data[i].ee_par, &ret);
- switch(power_data[i].sensor_type) {
- case LC15BTS_POWER_VOLTAGE:
- div_ratio = 1000;
- break;
- case LC15BTS_POWER_POWER:
- div_ratio = 1000000;
- break;
- default:
- div_ratio = 1000;
- }
- power_old[i] = ret * div_ratio;
-
- lc15bts_power_sensor_get(power_data[i].sensor_source, power_data[i].sensor_type, &power_cur[i]);
- if (power_cur[i] < 0 && power_cur[i] > -1000) {
- LOGP(DTEMP, LOGL_ERROR, "Error reading power (%d) (%d)\n", power_data[i].sensor_source,
- power_data[i].sensor_type);
- continue;
- }
- LOGP(DTEMP, LOGL_DEBUG, "Current %s power: %d.%d %s\n",
- power_data[i].name, power_cur[i]/div_ratio, power_cur[i]%div_ratio,
- get_value_string(power_unit_strs, power_data[i].sensor_type));
-
- if (power_cur[i] > power_old[i]) {
- LOGP(DTEMP, LOGL_NOTICE, "New maximum %s "
- "power: %d.%d %s\n", power_data[i].name,
- power_cur[i]/div_ratio, power_cur[i]%div_ratio,
- get_value_string(power_unit_strs, power_data[i].sensor_type));
-
- if (!no_rom_write) {
- rc = lc15bts_par_set_int(tall_mgr_ctx, power_data[i].ee_par, power_cur[i]/div_ratio);
- if (rc < 0)
- LOGP(DTEMP, LOGL_ERROR, "error writing new %s "
- "max power %d (%s)\n", power_data[i].name,
- rc, strerror(errno));
- }
- }
- }
-}
-
-void lc15bts_check_vswr(int no_rom_write)
-{
- int vswr_old[ARRAY_SIZE(vswr_data)];
- int vswr_cur[ARRAY_SIZE(vswr_data)];
- int i, rc;
-
- for (i = 0; i < ARRAY_SIZE(vswr_data); i++) {
- int ret;
- rc = lc15bts_par_get_int(tall_mgr_ctx, vswr_data[i].ee_par, &ret);
- vswr_old[i] = ret * 1000;
-
- lc15bts_vswr_get(vswr_data[i].sensor, &vswr_cur[i]);
- if (vswr_cur[i] < 0 && vswr_cur[i] > -1000) {
- LOGP(DTEMP, LOGL_ERROR, "Error reading vswr (%d)\n", vswr_data[i].sensor);
- continue;
- }
-
- LOGP(DTEMP, LOGL_DEBUG, "Current %s vswr: %d.%d\n",
- vswr_data[i].name, vswr_cur[i]/1000, vswr_cur[i]%1000);
-
- if (vswr_cur[i] > vswr_old[i]) {
- LOGP(DTEMP, LOGL_NOTICE, "New maximum %s "
- "vswr: %d.%d C\n", vswr_data[i].name,
- vswr_cur[i]/1000, vswr_old[i]%1000);
-
- if (!no_rom_write) {
- rc = lc15bts_par_set_int(tall_mgr_ctx, vswr_data[i].ee_par, vswr_cur[i]/1000);
- if (rc < 0)
- LOGP(DTEMP, LOGL_ERROR, "error writing new %s "
- "max vswr %d (%s)\n", vswr_data[i].name,
- rc, strerror(errno));
- }
- }
- }
-}
-
-/*********************************************************************
- * Hours handling
- *********************************************************************/
-static time_t last_update;
-
-int lc15bts_update_hours(int no_rom_write)
-{
- time_t now = time(NULL);
- int rc, op_hrs;
-
- /* first time after start of manager program */
- if (last_update == 0) {
- last_update = now;
-
- rc = lc15bts_par_get_int(tall_mgr_ctx, LC15BTS_PAR_HOURS, &op_hrs);
- if (rc < 0) {
- LOGP(DTEMP, LOGL_ERROR, "Unable to read "
- "operational hours: %d (%s)\n", rc,
- strerror(errno));
- return rc;
- }
-
- LOGP(DTEMP, LOGL_INFO, "Total hours of Operation: %u\n",
- op_hrs);
-
- return 0;
- }
-
- if (now >= last_update + 3600) {
- rc = lc15bts_par_get_int(tall_mgr_ctx, LC15BTS_PAR_HOURS, &op_hrs);
- if (rc < 0) {
- LOGP(DTEMP, LOGL_ERROR, "Unable to read "
- "operational hours: %d (%s)\n", rc,
- strerror(errno));
- return rc;
- }
-
- /* number of hours to increase */
- op_hrs += (now-last_update)/3600;
-
- LOGP(DTEMP, LOGL_INFO, "Total hours of Operation: %u\n",
- op_hrs);
-
- if (!no_rom_write) {
- rc = lc15bts_par_set_int(tall_mgr_ctx, LC15BTS_PAR_HOURS, op_hrs);
- if (rc < 0)
- return rc;
- }
-
- last_update = now;
- }
-
- return 0;
-}
-
-/*********************************************************************
- * Firmware reloading
- *********************************************************************/
-
-static const char *fw_sysfs[_NUM_FW] = {
- [LC15BTS_FW_DSP0] = "/sys/kernel/debug/remoteproc/remoteproc0/recovery",
- [LC15BTS_FW_DSP1] = "/sys/kernel/debug/remoteproc/remoteproc0/recovery",
-};
-
-int lc15bts_firmware_reload(enum lc15bts_firmware_type type)
-{
- int fd;
- int rc;
-
- switch (type) {
- case LC15BTS_FW_DSP0:
- case LC15BTS_FW_DSP1:
- fd = open(fw_sysfs[type], O_WRONLY);
- if (fd < 0) {
- LOGP(DFW, LOGL_ERROR, "unable to open firmware device %s: %s\n",
- fw_sysfs[type], strerror(errno));
- close(fd);
- return fd;
- }
- rc = write(fd, "restart", 8);
- if (rc < 8) {
- LOGP(DFW, LOGL_ERROR, "short write during "
- "fw write to %s\n", fw_sysfs[type]);
- close(fd);
- return -EIO;
- }
- close(fd);
- default:
- return -EINVAL;
- }
- return 0;
-}
diff --git a/src/osmo-bts-litecell15/misc/lc15bts_misc.h b/src/osmo-bts-litecell15/misc/lc15bts_misc.h
deleted file mode 100644
index 79e9e686..00000000
--- a/src/osmo-bts-litecell15/misc/lc15bts_misc.h
+++ /dev/null
@@ -1,18 +0,0 @@
-#ifndef _LC15BTS_MISC_H
-#define _LC15BTS_MISC_H
-
-#include <stdint.h>
-
-void lc15bts_check_temp(int no_rom_write);
-void lc15bts_check_power(int no_rom_write);
-void lc15bts_check_vswr(int no_rom_write);
-
-int lc15bts_update_hours(int no_rom_write);
-
-enum lc15bts_firmware_type {
- LC15BTS_FW_DSP0,
- LC15BTS_FW_DSP1,
- _NUM_FW
-};
-
-#endif
diff --git a/src/osmo-bts-litecell15/misc/lc15bts_nl.c b/src/osmo-bts-litecell15/misc/lc15bts_nl.c
deleted file mode 100644
index 39f64aae..00000000
--- a/src/osmo-bts-litecell15/misc/lc15bts_nl.c
+++ /dev/null
@@ -1,123 +0,0 @@
-/* Helper for netlink */
-
-/* Copyright (C) 2015 by Yves Godin <support@nuranwireless.com>
- *
- * Based on sysmoBTS:
- * sysmobts_nl.c
- * (C) 2014 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 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 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/licenses/>.
- *
- */
-
-#include <arpa/inet.h>
-#include <netinet/ip.h>
-
-#include <sys/socket.h>
-
-#include <linux/netlink.h>
-#include <linux/rtnetlink.h>
-
-#include <string.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <unistd.h>
-
-#define NLMSG_TAIL(nmsg) \
- ((struct rtattr *) (((void *) (nmsg)) + NLMSG_ALIGN((nmsg)->nlmsg_len)))
-
-/**
- * In case one binds to 0.0.0.0/INADDR_ANY and wants to know which source
- * address will be used when sending a message this function can be used.
- * It will ask the routing code of the kernel for the PREFSRC
- */
-int source_for_dest(const struct in_addr *dest, struct in_addr *loc_source)
-{
- int fd, rc;
- struct rtmsg *r;
- struct rtattr *rta;
- struct {
- struct nlmsghdr n;
- struct rtmsg r;
- char buf[1024];
- } req;
-
- memset(&req, 0, sizeof(req));
-
- fd = socket(AF_NETLINK, SOCK_RAW|SOCK_CLOEXEC, NETLINK_ROUTE);
- if (fd < 0) {
- perror("nl socket");
- return -1;
- }
-
- /* Send a rtmsg and ask for a response */
- req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
- req.n.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
- req.n.nlmsg_type = RTM_GETROUTE;
- req.n.nlmsg_seq = 1;
-
- /* Prepare the routing request */
- req.r.rtm_family = AF_INET;
-
- /* set the dest */
- rta = NLMSG_TAIL(&req.n);
- rta->rta_type = RTA_DST;
- rta->rta_len = RTA_LENGTH(sizeof(*dest));
- memcpy(RTA_DATA(rta), dest, sizeof(*dest));
-
- /* update sizes for dest */
- req.r.rtm_dst_len = sizeof(*dest) * 8;
- req.n.nlmsg_len = NLMSG_ALIGN(req.n.nlmsg_len) + RTA_ALIGN(rta->rta_len);
-
- rc = send(fd, &req, req.n.nlmsg_len, 0);
- if (rc != req.n.nlmsg_len) {
- perror("short write");
- close(fd);
- return -2;
- }
-
-
- /* now receive a response and parse it */
- rc = recv(fd, &req, sizeof(req), 0);
- if (rc <= 0) {
- perror("short read");
- close(fd);
- return -3;
- }
-
- if (!NLMSG_OK(&req.n, rc) || req.n.nlmsg_type != RTM_NEWROUTE) {
- close(fd);
- return -4;
- }
-
- r = NLMSG_DATA(&req.n);
- rc -= NLMSG_LENGTH(sizeof(*r));
- rta = RTM_RTA(r);
- while (RTA_OK(rta, rc)) {
- if (rta->rta_type != RTA_PREFSRC) {
- rta = RTA_NEXT(rta, rc);
- continue;
- }
-
- /* we are done */
- memcpy(loc_source, RTA_DATA(rta), RTA_PAYLOAD(rta));
- close(fd);
- return 0;
- }
-
- close(fd);
- return -5;
-}
diff --git a/src/osmo-bts-litecell15/misc/lc15bts_nl.h b/src/osmo-bts-litecell15/misc/lc15bts_nl.h
deleted file mode 100644
index 340cf117..00000000
--- a/src/osmo-bts-litecell15/misc/lc15bts_nl.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/* Copyright (C) 2015 by Yves Godin <support@nuranwireless.com>
- *
- * Based on sysmoBTS:
- * sysmobts_nl.h
- * (C) 2014 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 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 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/licenses/>.
- *
- */
-#pragma once
-
-struct in_addr;
-
-int source_for_dest(const struct in_addr *dest, struct in_addr *loc_source);
diff --git a/src/osmo-bts-litecell15/misc/lc15bts_par.c b/src/osmo-bts-litecell15/misc/lc15bts_par.c
deleted file mode 100644
index af9d030f..00000000
--- a/src/osmo-bts-litecell15/misc/lc15bts_par.c
+++ /dev/null
@@ -1,232 +0,0 @@
-/* lc15bts - access to hardware related parameters */
-
-/* Copyright (C) 2015 by Yves Godin <support@nuranwireless.com>
- *
- * Based on sysmoBTS:
- * sysmobts_par.c
- * (C) 2012 by Harald Welte <laforge@gnumonks.org>
- *
- * 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 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/licenses/>.
- *
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdint.h>
-#include <string.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <limits.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-
-#include <osmocom/core/utils.h>
-#include <osmocom/core/talloc.h>
-
-#include "lc15bts_par.h"
-
-const struct value_string lc15bts_par_names[_NUM_LC15BTS_PAR+1] = {
- { LC15BTS_PAR_TEMP_SUPPLY_MAX, "temp-supply-max" },
- { LC15BTS_PAR_TEMP_SOC_MAX, "temp-soc-max" },
- { LC15BTS_PAR_TEMP_FPGA_MAX, "temp-fpga-max" },
- { LC15BTS_PAR_TEMP_RMSDET_MAX, "temp-rmsdet-max" },
- { LC15BTS_PAR_TEMP_OCXO_MAX, "temp-ocxo-max" },
- { LC15BTS_PAR_TEMP_TX0_MAX, "temp-tx0-max" },
- { LC15BTS_PAR_TEMP_TX1_MAX, "temp-tx1-max" },
- { LC15BTS_PAR_TEMP_PA0_MAX, "temp-pa0-max" },
- { LC15BTS_PAR_TEMP_PA1_MAX, "temp-pa1-max" },
- { LC15BTS_PAR_VOLT_SUPPLY_MAX, "volt-supply-max" },
- { LC15BTS_PAR_PWR_SUPPLY_MAX, "pwr-supply-max" },
- { LC15BTS_PAR_PWR_PA0_MAX, "pwr-pa0-max" },
- { LC15BTS_PAR_PWR_PA1_MAX, "pwr-pa1-max" },
- { LC15BTS_PAR_VSWR_TX0_MAX, "vswr-tx0-max" },
- { LC15BTS_PAR_VSWR_TX1_MAX, "vswr-tx1-max" },
- { LC15BTS_PAR_GPS_FIX, "gps-fix" },
- { LC15BTS_PAR_SERNR, "serial-nr" },
- { LC15BTS_PAR_HOURS, "hours-running" },
- { LC15BTS_PAR_BOOTS, "boot-count" },
- { LC15BTS_PAR_KEY, "key" },
- { 0, NULL }
-};
-
-int lc15bts_par_is_int(enum lc15bts_par par)
-{
- switch (par) {
- case LC15BTS_PAR_TEMP_SUPPLY_MAX:
- case LC15BTS_PAR_TEMP_SOC_MAX:
- case LC15BTS_PAR_TEMP_FPGA_MAX:
- case LC15BTS_PAR_TEMP_RMSDET_MAX:
- case LC15BTS_PAR_TEMP_OCXO_MAX:
- case LC15BTS_PAR_TEMP_TX0_MAX:
- case LC15BTS_PAR_TEMP_TX1_MAX:
- case LC15BTS_PAR_TEMP_PA0_MAX:
- case LC15BTS_PAR_TEMP_PA1_MAX:
- case LC15BTS_PAR_VOLT_SUPPLY_MAX:
- case LC15BTS_PAR_VSWR_TX0_MAX:
- case LC15BTS_PAR_VSWR_TX1_MAX:
- case LC15BTS_PAR_SERNR:
- case LC15BTS_PAR_HOURS:
- case LC15BTS_PAR_BOOTS:
- case LC15BTS_PAR_PWR_SUPPLY_MAX:
- case LC15BTS_PAR_PWR_PA0_MAX:
- case LC15BTS_PAR_PWR_PA1_MAX:
- return 1;
- default:
- return 0;
- }
-}
-
-FILE *lc15bts_par_get_path(void *ctx, enum lc15bts_par par, const char* mode)
-{
- char *fpath;
- FILE *fp;
-
- if (par >= _NUM_LC15BTS_PAR)
- return NULL;
-
- fpath = talloc_asprintf(ctx, "%s/%s", USER_ROM_PATH, get_value_string(lc15bts_par_names, par));
- if (!fpath)
- return NULL;
-
- fp = fopen(fpath, mode);
- if (!fp)
- fprintf(stderr, "Failed to open %s due to '%s' error\n", fpath, strerror(errno));
-
- talloc_free(fpath);
-
- return fp;
-}
-
-int lc15bts_par_get_int(void *ctx, enum lc15bts_par par, int *ret)
-{
- FILE *fp = lc15bts_par_get_path(ctx, par, "r");
- int rc;
-
- if (fp == NULL) {
- return -errno;
- }
-
- rc = fscanf(fp, "%d", ret);
- if (rc != 1) {
- fclose(fp);
- return -EIO;
- }
- fclose(fp);
- return 0;
-}
-
-int lc15bts_par_set_int(void *ctx, enum lc15bts_par par, int val)
-{
- FILE *fp = lc15bts_par_get_path(ctx, par, "w");
- int rc;
-
- if (fp == NULL) {
- return -errno;
- }
-
- rc = fprintf(fp, "%d", val);
- if (rc < 0) {
- fclose(fp);
- return -EIO;
- }
-
- fsync(fileno(fp));
- fclose(fp);
- return 0;
-}
-
-int lc15bts_par_get_buf(void *ctx, enum lc15bts_par par, uint8_t *buf, unsigned int size)
-{
- FILE *fp = lc15bts_par_get_path(ctx, par, "rb");
- int rc;
-
- if (fp == NULL) {
- return -errno;
- }
-
- rc = fread(buf, 1, size, fp);
-
- fclose(fp);
-
- return rc;
-}
-
-int lc15bts_par_set_buf(void *ctx, enum lc15bts_par par, const uint8_t *buf, unsigned int size)
-{
- FILE *fp = lc15bts_par_get_path(ctx, par, "wb");
- int rc;
-
- if (fp == NULL) {
- return -errno;
- }
-
- rc = fwrite(buf, 1, size, fp);
-
- fsync(fileno(fp));
- fclose(fp);
-
- return rc;
-}
-
-int lc15bts_par_get_gps_fix(time_t *ret)
-{
- char fpath[PATH_MAX];
- FILE *fp;
- int rc;
-
- snprintf(fpath, sizeof(fpath)-1, "%s/%s", USER_ROM_PATH, get_value_string(lc15bts_par_names, LC15BTS_PAR_GPS_FIX));
- fpath[sizeof(fpath)-1] = '\0';
-
- fp = fopen(fpath, "r");
- if (fp == NULL) {
- return -errno;
- }
-
- rc = fscanf(fp, "%lld", (long long *)ret);
- if (rc != 1) {
- fclose(fp);
- return -EIO;
- }
- fclose(fp);
-
- return 0;
-}
-
-int lc15bts_par_set_gps_fix(time_t val)
-{
- char fpath[PATH_MAX];
- FILE *fp;
- int rc;
-
- snprintf(fpath, sizeof(fpath)-1, "%s/%s", USER_ROM_PATH, get_value_string(lc15bts_par_names, LC15BTS_PAR_GPS_FIX));
- fpath[sizeof(fpath)-1] = '\0';
-
- fp = fopen(fpath, "w");
- if (fp == NULL) {
- return -errno;
- }
-
- rc = fprintf(fp, "%lld", (long long)val);
- if (rc < 0) {
- fclose(fp);
- return -EIO;
- }
- fsync(fileno(fp));
- fclose(fp);
-
- return 0;
-}
diff --git a/src/osmo-bts-litecell15/misc/lc15bts_par.h b/src/osmo-bts-litecell15/misc/lc15bts_par.h
deleted file mode 100644
index 74295653..00000000
--- a/src/osmo-bts-litecell15/misc/lc15bts_par.h
+++ /dev/null
@@ -1,43 +0,0 @@
-#ifndef _LC15BTS_PAR_H
-#define _LC15BTS_PAR_H
-
-#include <osmocom/core/utils.h>
-
-#define USER_ROM_PATH "/mnt/storage/var/run/lc15bts-mgr"
-
-enum lc15bts_par {
- LC15BTS_PAR_TEMP_SUPPLY_MAX,
- LC15BTS_PAR_TEMP_SOC_MAX,
- LC15BTS_PAR_TEMP_FPGA_MAX,
- LC15BTS_PAR_TEMP_RMSDET_MAX,
- LC15BTS_PAR_TEMP_OCXO_MAX,
- LC15BTS_PAR_TEMP_TX0_MAX,
- LC15BTS_PAR_TEMP_TX1_MAX,
- LC15BTS_PAR_TEMP_PA0_MAX,
- LC15BTS_PAR_TEMP_PA1_MAX,
- LC15BTS_PAR_VOLT_SUPPLY_MAX,
- LC15BTS_PAR_PWR_SUPPLY_MAX,
- LC15BTS_PAR_PWR_PA0_MAX,
- LC15BTS_PAR_PWR_PA1_MAX,
- LC15BTS_PAR_VSWR_TX0_MAX,
- LC15BTS_PAR_VSWR_TX1_MAX,
- LC15BTS_PAR_GPS_FIX,
- LC15BTS_PAR_SERNR,
- LC15BTS_PAR_HOURS,
- LC15BTS_PAR_BOOTS,
- LC15BTS_PAR_KEY,
- _NUM_LC15BTS_PAR
-};
-
-extern const struct value_string lc15bts_par_names[_NUM_LC15BTS_PAR+1];
-
-int lc15bts_par_get_int(void *ctx, enum lc15bts_par par, int *ret);
-int lc15bts_par_set_int(void *ctx, enum lc15bts_par par, int val);
-int lc15bts_par_get_buf(void *ctx, enum lc15bts_par par, uint8_t *buf, unsigned int size);
-int lc15bts_par_set_buf(void *ctx, enum lc15bts_par par, const uint8_t *buf, unsigned int size);
-
-int lc15bts_par_is_int(enum lc15bts_par par);
-int lc15bts_par_get_gps_fix(time_t *ret);
-int lc15bts_par_set_gps_fix(time_t val);
-
-#endif
diff --git a/src/osmo-bts-litecell15/misc/lc15bts_power.c b/src/osmo-bts-litecell15/misc/lc15bts_power.c
deleted file mode 100644
index 1a37d8e6..00000000
--- a/src/osmo-bts-litecell15/misc/lc15bts_power.c
+++ /dev/null
@@ -1,210 +0,0 @@
-/* Copyright (C) 2015 by Yves Godin <support@nuranwireless.com>
- *
- * 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 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/licenses/>.
- *
- */
-
-#include <stdio.h>
-#include <stdint.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <limits.h>
-
-#include "lc15bts_power.h"
-
-#define LC15BTS_PA_VOLTAGE 24000000
-
-#define PA_SUPPLY_MIN_SYSFS "/var/lc15/pa-supply/min_microvolts"
-#define PA_SUPPLY_MAX_SYSFS "/var/lc15/pa-supply/max_microvolts"
-
-static const char *power_enable_devs[_NUM_POWER_SOURCES] = {
- [LC15BTS_POWER_PA0] = "/var/lc15/pa-state/pa0/state",
- [LC15BTS_POWER_PA1] = "/var/lc15/pa-state/pa1/state",
-};
-
-static const char *power_sensor_devs[_NUM_POWER_SOURCES] = {
- [LC15BTS_POWER_SUPPLY] = "/var/lc15/pwr-sense/main-supply/",
- [LC15BTS_POWER_PA0] = "/var/lc15/pwr-sense/pa0/",
- [LC15BTS_POWER_PA1] = "/var/lc15/pwr-sense/pa1/",
-};
-
-static const char *power_sensor_type_str[_NUM_POWER_TYPES] = {
- [LC15BTS_POWER_POWER] = "power",
- [LC15BTS_POWER_VOLTAGE] = "voltage",
- [LC15BTS_POWER_CURRENT] = "current",
-};
-
-int lc15bts_power_sensor_get(
- enum lc15bts_power_source source,
- enum lc15bts_power_type type,
- int *power)
-{
- char buf[PATH_MAX];
- char pwrstr[10];
- int fd, rc;
-
- if (source >= _NUM_POWER_SOURCES)
- return -EINVAL;
-
- if (type >= _NUM_POWER_TYPES)
- return -EINVAL;
-
- snprintf(buf, sizeof(buf)-1, "%s%s", power_sensor_devs[source], power_sensor_type_str[type]);
- buf[sizeof(buf)-1] = '\0';
-
- fd = open(buf, O_RDONLY);
- if (fd < 0)
- return fd;
-
- rc = read(fd, pwrstr, sizeof(pwrstr));
- pwrstr[sizeof(pwrstr)-1] = '\0';
- if (rc < 0) {
- close(fd);
- return rc;
- }
- if (rc == 0) {
- close(fd);
- return -EIO;
- }
- close(fd);
- *power = atoi(pwrstr);
- return 0;
-}
-
-
-int lc15bts_power_set(
- enum lc15bts_power_source source,
- int en)
-{
- int fd;
- int rc;
-
- if ((source != LC15BTS_POWER_PA0)
- && (source != LC15BTS_POWER_PA1) ) {
- return -EINVAL;
- }
-
- fd = open(PA_SUPPLY_MAX_SYSFS, O_WRONLY);
- if (fd < 0) {
- return fd;
- }
- rc = write(fd, "32000000", 9);
- close( fd );
-
- if (rc != 9) {
- return -1;
- }
-
- fd = open(PA_SUPPLY_MIN_SYSFS, O_WRONLY);
- if (fd < 0) {
- return fd;
- }
-
- /* TODO NTQ: Make the voltage configurable */
- rc = write(fd, "24000000", 9);
- close( fd );
-
- if (rc != 9) {
- return -1;
- }
-
- fd = open(power_enable_devs[source], O_WRONLY);
- if (fd < 0) {
- return fd;
- }
- rc = write(fd, en?"1":"0", 2);
- close( fd );
-
- if (rc != 2) {
- return -1;
- }
-
- if (en) usleep(50*1000);
-
- return 0;
-}
-
-int lc15bts_power_get(
- enum lc15bts_power_source source)
-{
- int fd;
- int rc;
- int retVal = 0;
- char enstr[10];
-
- fd = open(power_enable_devs[source], O_RDONLY);
- if (fd < 0) {
- return fd;
- }
-
- rc = read(fd, enstr, sizeof(enstr));
- enstr[rc-1] = '\0';
-
- close(fd);
-
- if (rc < 0) {
- return rc;
- }
- if (rc == 0) {
- return -EIO;
- }
-
- rc = strcmp(enstr, "enabled");
- if(rc == 0) {
- retVal = 1;
- }
-
- return retVal;
-}
-
-static const char *vswr_devs[_NUM_VSWR_SENSORS] = {
- [LC15BTS_VSWR_TX0] = "/var/lc15/vswr/tx0/vswr",
- [LC15BTS_VSWR_TX1] = "/var/lc15/vswr/tx1/vswr",
-};
-
-int lc15bts_vswr_get(enum lc15bts_vswr_sensor sensor, int *vswr)
-{
- char buf[PATH_MAX];
- char vswrstr[8];
- int fd, rc;
-
- if (sensor < 0 || sensor >= _NUM_VSWR_SENSORS)
- return -EINVAL;
-
- snprintf(buf, sizeof(buf)-1, "%s", vswr_devs[sensor]);
- buf[sizeof(buf)-1] = '\0';
-
- fd = open(buf, O_RDONLY);
- if (fd < 0)
- return fd;
-
- rc = read(fd, vswrstr, sizeof(vswrstr));
- vswrstr[sizeof(vswrstr)-1] = '\0';
- if (rc < 0) {
- close(fd);
- return rc;
- }
- if (rc == 0) {
- close(fd);
- return -EIO;
- }
- close(fd);
- *vswr = atoi(vswrstr);
- return 0;
-}
diff --git a/src/osmo-bts-litecell15/misc/lc15bts_power.h b/src/osmo-bts-litecell15/misc/lc15bts_power.h
deleted file mode 100644
index b48cfdcd..00000000
--- a/src/osmo-bts-litecell15/misc/lc15bts_power.h
+++ /dev/null
@@ -1,38 +0,0 @@
-#ifndef _LC15BTS_POWER_H
-#define _LC15BTS_POWER_H
-
-enum lc15bts_power_source {
- LC15BTS_POWER_SUPPLY,
- LC15BTS_POWER_PA0,
- LC15BTS_POWER_PA1,
- _NUM_POWER_SOURCES
-};
-
-enum lc15bts_power_type {
- LC15BTS_POWER_POWER,
- LC15BTS_POWER_VOLTAGE,
- LC15BTS_POWER_CURRENT,
- _NUM_POWER_TYPES
-};
-
-int lc15bts_power_sensor_get(
- enum lc15bts_power_source source,
- enum lc15bts_power_type type,
- int *volt);
-
-int lc15bts_power_set(
- enum lc15bts_power_source source,
- int en);
-
-int lc15bts_power_get(
- enum lc15bts_power_source source);
-
-enum lc15bts_vswr_sensor {
- LC15BTS_VSWR_TX0,
- LC15BTS_VSWR_TX1,
- _NUM_VSWR_SENSORS
-};
-
-int lc15bts_vswr_get(enum lc15bts_vswr_sensor sensor, int *vswr);
-
-#endif
diff --git a/src/osmo-bts-litecell15/misc/lc15bts_swd.c b/src/osmo-bts-litecell15/misc/lc15bts_swd.c
deleted file mode 100644
index eac64d66..00000000
--- a/src/osmo-bts-litecell15/misc/lc15bts_swd.c
+++ /dev/null
@@ -1,178 +0,0 @@
-/* Systemd service wd notification for Litecell 1.5 BTS management daemon */
-
-/* Copyright (C) 2015 by Yves Godin <support@nuranwireless.com>
- *
- * 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 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/licenses/>.
- *
- */
-
-#include "misc/lc15bts_mgr.h"
-#include "misc/lc15bts_swd.h"
-#include <osmocom/core/logging.h>
-
-/* Needed for service watchdog notification */
-#include <systemd/sd-daemon.h>
-
-/* This is the period used to verify if all events have been registered to be allowed
- to notify the systemd service watchdog
-*/
-#define SWD_PERIOD 30
-
-static void swd_start(struct lc15bts_mgr_instance *mgr);
-static void swd_process(struct lc15bts_mgr_instance *mgr);
-static void swd_close(struct lc15bts_mgr_instance *mgr);
-static void swd_state_reset(struct lc15bts_mgr_instance *mgr, int reason);
-static int swd_run(struct lc15bts_mgr_instance *mgr, int from_loop);
-static void swd_loop_run(void *_data);
-
-enum swd_state {
- SWD_INITIAL,
- SWD_IN_PROGRESS,
-};
-
-enum swd_result {
- SWD_FAIL_START,
- SWD_FAIL_NOTIFY,
- SWD_SUCCESS,
-};
-
-static void swd_start(struct lc15bts_mgr_instance *mgr)
-{
- swd_process(mgr);
-}
-
-static void swd_process(struct lc15bts_mgr_instance *mgr)
-{
- int rc = 0, notify = 0;
-
- /* Did we get all needed conditions ? */
- if (mgr->swd.swd_eventmasks == mgr->swd.swd_events) {
- /* Ping systemd service wd if enabled */
- rc = sd_notify(0, "WATCHDOG=1");
- LOGP(DSWD, LOGL_NOTICE, "Watchdog notification attempt\n");
- notify = 1;
- }
- else {
- LOGP(DSWD, LOGL_NOTICE, "Missing watchdog events: e:0x%016llx,m:0x%016llx\n",mgr->swd.swd_events,mgr->swd.swd_eventmasks);
- }
-
- if (rc < 0) {
- LOGP(DSWD, LOGL_ERROR,
- "Failed to notify system service watchdog: %d\n", rc);
- swd_state_reset(mgr, SWD_FAIL_NOTIFY);
- return;
- }
- else {
- /* Did we notified the watchdog? */
- if (notify) {
- mgr->swd.swd_events = 0;
- /* Makes sure we really cleared it in case any event was notified at this same moment (it would be lost) */
- if (mgr->swd.swd_events != 0)
- mgr->swd.swd_events = 0;
- }
- }
-
- swd_state_reset(mgr, SWD_SUCCESS);
- return;
-}
-
-static void swd_close(struct lc15bts_mgr_instance *mgr)
-{
-}
-
-static void swd_state_reset(struct lc15bts_mgr_instance *mgr, int outcome)
-{
- if (mgr->swd.swd_from_loop) {
- mgr->swd.swd_timeout.data = mgr;
- mgr->swd.swd_timeout.cb = swd_loop_run;
- osmo_timer_schedule(&mgr->swd.swd_timeout, SWD_PERIOD, 0);
- }
-
- mgr->swd.state = SWD_INITIAL;
- swd_close(mgr);
-}
-
-static int swd_run(struct lc15bts_mgr_instance *mgr, int from_loop)
-{
- if (mgr->swd.state != SWD_INITIAL) {
- LOGP(DSWD, LOGL_ERROR, "Swd is already in progress.\n");
- return -1;
- }
-
- mgr->swd.swd_from_loop = from_loop;
-
- /* From now on everything will be handled from the failure */
- mgr->swd.state = SWD_IN_PROGRESS;
- swd_start(mgr);
- return 0;
-}
-
-static void swd_loop_run(void *_data)
-{
- int rc;
- struct lc15bts_mgr_instance *mgr = _data;
-
- LOGP(DSWD, LOGL_NOTICE, "Going to check for watchdog notification.\n");
- rc = swd_run(mgr, 1);
- if (rc != 0) {
- swd_state_reset(mgr, SWD_FAIL_START);
- }
-}
-
-/* 'swd_num_events' configures the number of events to be monitored before notifying the
- systemd service watchdog. It must be in the range of [1,64]. Events are notified
- through the function 'lc15bts_swd_event'
-*/
-int lc15bts_swd_init(struct lc15bts_mgr_instance *mgr, int swd_num_events)
-{
- /* Checks for a valid number of events to validate */
- if (swd_num_events < 1 || swd_num_events > 64)
- return(-1);
-
- mgr->swd.state = SWD_INITIAL;
- mgr->swd.swd_timeout.data = mgr;
- mgr->swd.swd_timeout.cb = swd_loop_run;
- osmo_timer_schedule(&mgr->swd.swd_timeout, 0, 0);
-
- if (swd_num_events == 64){
- mgr->swd.swd_eventmasks = 0xffffffffffffffffULL;
- }
- else {
- mgr->swd.swd_eventmasks = ((1ULL << swd_num_events) - 1);
- }
- mgr->swd.swd_events = 0;
- mgr->swd.num_events = swd_num_events;
-
- return 0;
-}
-
-/* Notifies that the specified event 'swd_event' happened correctly;
- the value must be in the range of [0,'swd_num_events'[ (see lc15bts_swd_init).
- For example, if 'swd_num_events' was 64, 'swd_event' events are numbered 0 to 63.
- WARNING: if this function can be used from multiple threads at the same time,
- it must be protected with a kind of mutex to avoid losing event notification.
-*/
-int lc15bts_swd_event(struct lc15bts_mgr_instance *mgr, enum mgr_swd_events swd_event)
-{
- /* Checks for a valid specified event (smaller than max possible) */
- if ((int)(swd_event) < 0 || (int)(swd_event) >= mgr->swd.num_events)
- return(-1);
-
- mgr->swd.swd_events = mgr->swd.swd_events | ((unsigned long long int)(1) << (int)(swd_event));
-
- /* !!! Uncomment following line to debug events notification */
- LOGP(DSWD, LOGL_DEBUG,"Swd event notified: %d\n", (int)(swd_event));
-
- return 0;
-}
diff --git a/src/osmo-bts-litecell15/misc/lc15bts_swd.h b/src/osmo-bts-litecell15/misc/lc15bts_swd.h
deleted file mode 100644
index b78a2c2a..00000000
--- a/src/osmo-bts-litecell15/misc/lc15bts_swd.h
+++ /dev/null
@@ -1,7 +0,0 @@
-#ifndef _LC15BTS_SWD_H
-#define _LC15BTS_SWD_H
-
-int lc15bts_swd_init(struct lc15bts_mgr_instance *mgr, int swd_num_events);
-int lc15bts_swd_event(struct lc15bts_mgr_instance *mgr, enum mgr_swd_events swd_event);
-
-#endif
diff --git a/src/osmo-bts-litecell15/misc/lc15bts_temp.c b/src/osmo-bts-litecell15/misc/lc15bts_temp.c
deleted file mode 100644
index 45602dcc..00000000
--- a/src/osmo-bts-litecell15/misc/lc15bts_temp.c
+++ /dev/null
@@ -1,74 +0,0 @@
-/* Copyright (C) 2015 by Yves Godin <support@nuranwireless.com>
- *
- * 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 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/licenses/>.
- *
- */
-
-#include <stdint.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <limits.h>
-
-#include <osmocom/core/utils.h>
-
-#include "lc15bts_temp.h"
-
-static const char *temp_devs[_NUM_TEMP_SENSORS] = {
- [LC15BTS_TEMP_SUPPLY] = "/var/lc15/temp/main-supply/temp",
- [LC15BTS_TEMP_SOC] = "/var/lc15/temp/cpu/temp",
- [LC15BTS_TEMP_FPGA] = "/var/lc15/temp/fpga/temp",
- [LC15BTS_TEMP_RMSDET] = "/var/lc15/temp/rmsdet/temp",
- [LC15BTS_TEMP_OCXO] = "/var/lc15/temp/ocxo/temp",
- [LC15BTS_TEMP_TX0] = "/var/lc15/temp/tx0/temp",
- [LC15BTS_TEMP_TX1] = "/var/lc15/temp/tx1/temp",
- [LC15BTS_TEMP_PA0] = "/var/lc15/temp/pa0/temp",
- [LC15BTS_TEMP_PA1] = "/var/lc15/temp/pa1/temp",
-};
-
-int lc15bts_temp_get(enum lc15bts_temp_sensor sensor, int *temp)
-{
- char buf[PATH_MAX];
- char tempstr[8];
- int fd, rc;
-
- if (sensor < 0 || sensor >= _NUM_TEMP_SENSORS)
- return -EINVAL;
-
- snprintf(buf, sizeof(buf)-1, "%s", temp_devs[sensor]);
- buf[sizeof(buf)-1] = '\0';
-
- fd = open(buf, O_RDONLY);
- if (fd < 0)
- return fd;
-
- rc = read(fd, tempstr, sizeof(tempstr));
- tempstr[sizeof(tempstr)-1] = '\0';
- if (rc < 0) {
- close(fd);
- return rc;
- }
- if (rc == 0) {
- close(fd);
- return -EIO;
- }
- close(fd);
- *temp = atoi(tempstr);
- return 0;
-}
-
diff --git a/src/osmo-bts-litecell15/misc/lc15bts_temp.h b/src/osmo-bts-litecell15/misc/lc15bts_temp.h
deleted file mode 100644
index 35d81f1b..00000000
--- a/src/osmo-bts-litecell15/misc/lc15bts_temp.h
+++ /dev/null
@@ -1,28 +0,0 @@
-#ifndef _LC15BTS_TEMP_H
-#define _LC15BTS_TEMP_H
-
-enum lc15bts_temp_sensor {
- LC15BTS_TEMP_SUPPLY,
- LC15BTS_TEMP_SOC,
- LC15BTS_TEMP_FPGA,
- LC15BTS_TEMP_RMSDET,
- LC15BTS_TEMP_OCXO,
- LC15BTS_TEMP_TX0,
- LC15BTS_TEMP_TX1,
- LC15BTS_TEMP_PA0,
- LC15BTS_TEMP_PA1,
- _NUM_TEMP_SENSORS
-};
-
-enum lc15bts_temp_type {
- LC15BTS_TEMP_INPUT,
- LC15BTS_TEMP_LOWEST,
- LC15BTS_TEMP_HIGHEST,
- LC15BTS_TEMP_FAULT,
- _NUM_TEMP_TYPES
-};
-
-int lc15bts_temp_get(enum lc15bts_temp_sensor sensor, int *temp);
-
-
-#endif
diff --git a/src/osmo-bts-litecell15/misc/lc15bts_util.c b/src/osmo-bts-litecell15/misc/lc15bts_util.c
deleted file mode 100644
index 430ce0f7..00000000
--- a/src/osmo-bts-litecell15/misc/lc15bts_util.c
+++ /dev/null
@@ -1,164 +0,0 @@
-/* lc15bts-util - access to hardware related parameters */
-
-/* Copyright (C) 2015 by Yves Godin <support@nuranwireless.com>
- *
- * Based on sysmoBTS:
- * sysmobts_misc.c
- * (C) 2012-2013 by Harald Welte <laforge@gnumonks.org>
- *
- * 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 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/licenses/>.
- *
- */
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdint.h>
-#include <string.h>
-#include <errno.h>
-#include <getopt.h>
-#include <osmocom/core/talloc.h>
-#include <osmocom/core/msgb.h>
-
-#include "lc15bts_par.h"
-
-void *tall_util_ctx;
-
-enum act {
- ACT_GET,
- ACT_SET,
-};
-
-static enum act action;
-static char *write_arg;
-static int void_warranty;
-
-static void print_help()
-{
- const struct value_string *par = lc15bts_par_names;
-
- printf("lc15bts-util [--void-warranty -r | -w value] param_name\n");
- printf("Possible param names:\n");
-
- for (; par->str != NULL; par += 1) {
- if (!lc15bts_par_is_int(par->value))
- continue;
- printf(" %s\n", par->str);
- }
-}
-
-static int parse_options(int argc, char **argv)
-{
- while (1) {
- int option_idx = 0, c;
- static const struct option long_options[] = {
- { "help", 0, 0, 'h' },
- { "read", 0, 0, 'r' },
- { "void-warranty", 0, 0, 1000},
- { "write", 1, 0, 'w' },
- { 0, 0, 0, 0 }
- };
-
- c = getopt_long(argc, argv, "rw:h",
- long_options, &option_idx);
- if (c == -1)
- break;
- switch (c) {
- case 'r':
- action = ACT_GET;
- break;
- case 'w':
- action = ACT_SET;
- write_arg = optarg;
- break;
- case 'h':
- print_help();
- return -1;
- break;
- case 1000:
- printf("Will void warranty on write.\n");
- void_warranty = 1;
- break;
- default:
- return -1;
- }
- }
-
- return 0;
-}
-
-int main(int argc, char **argv)
-{
- const char *parname;
- enum lc15bts_par par;
- int rc, val;
-
- tall_util_ctx = talloc_named_const(NULL, 1, "lc15 utils");
- msgb_talloc_ctx_init(tall_util_ctx, 0);
-
- rc = parse_options(argc, argv);
- if (rc < 0)
- exit(2);
-
- if (optind >= argc) {
- fprintf(stderr, "You must specify the parameter name\n");
- exit(2);
- }
- parname = argv[optind];
-
- rc = get_string_value(lc15bts_par_names, parname);
- if (rc < 0) {
- fprintf(stderr, "`%s' is not a valid parameter\n", parname);
- exit(2);
- } else
- par = rc;
-
- switch (action) {
- case ACT_GET:
- rc = lc15bts_par_get_int(tall_util_ctx, par, &val);
- if (rc < 0) {
- fprintf(stderr, "Error %d\n", rc);
- goto err;
- }
- printf("%d\n", val);
- break;
- case ACT_SET:
- rc = lc15bts_par_get_int(tall_util_ctx, par, &val);
- if (rc < 0) {
- fprintf(stderr, "Error %d\n", rc);
- goto err;
- }
- if (val != 0xFFFF && val != 0xFF && val != 0xFFFFFFFF && !void_warranty) {
- fprintf(stderr, "Parameter is already set!\r\n");
- goto err;
- }
- rc = lc15bts_par_set_int(tall_util_ctx, par, atoi(write_arg));
- if (rc < 0) {
- fprintf(stderr, "Error %d\n", rc);
- goto err;
- }
- printf("Success setting %s=%d\n", parname,
- atoi(write_arg));
- break;
- default:
- fprintf(stderr, "Unsupported action\n");
- goto err;
- }
-
- exit(0);
-
-err:
- exit(1);
-}
-
diff --git a/src/osmo-bts-litecell15/oml.c b/src/osmo-bts-litecell15/oml.c
deleted file mode 100644
index 1fe7205a..00000000
--- a/src/osmo-bts-litecell15/oml.c
+++ /dev/null
@@ -1,2112 +0,0 @@
-/* Copyright (C) 2015 by Yves Godin <support@nuranwireless.com>
- *
- * Based on sysmoBTS:
- * (C) 2011 by Harald Welte <laforge@gnumonks.org>
- * (C) 2013-2014 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 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 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/licenses/>.
- *
- */
-
-#include <stdint.h>
-#include <errno.h>
-
-#include <osmocom/core/talloc.h>
-#include <osmocom/core/utils.h>
-#include <osmocom/core/fsm.h>
-
-#include <nrw/litecell15/gsml1prim.h>
-#include <nrw/litecell15/gsml1const.h>
-#include <nrw/litecell15/gsml1types.h>
-#include <nrw/litecell15/litecell15.h>
-
-#include <osmo-bts/gsm_data.h>
-#include <osmo-bts/logging.h>
-#include <osmo-bts/oml.h>
-#include <osmo-bts/rsl.h>
-#include <osmo-bts/amr.h>
-#include <osmo-bts/bts.h>
-#include <osmo-bts/bts_model.h>
-#include <osmo-bts/phy_link.h>
-#include <osmo-bts/handover.h>
-#include <osmo-bts/l1sap.h>
-#include <osmo-bts/nm_common_fsm.h>
-
-#include "l1_if.h"
-#include "lc15bts.h"
-#include "utils.h"
-
-static int mph_info_chan_confirm(struct gsm_lchan *lchan,
- enum osmo_mph_info_type type, uint8_t cause)
-{
- struct osmo_phsap_prim l1sap;
-
- memset(&l1sap, 0, sizeof(l1sap));
- osmo_prim_init(&l1sap.oph, SAP_GSM_PH, PRIM_MPH_INFO, PRIM_OP_CONFIRM,
- NULL);
- l1sap.u.info.type = type;
- l1sap.u.info.u.act_cnf.chan_nr = gsm_lchan2chan_nr(lchan);
- l1sap.u.info.u.act_cnf.cause = cause;
-
- return l1sap_up(lchan->ts->trx, &l1sap);
-}
-
-enum sapi_cmd_type {
- SAPI_CMD_ACTIVATE,
- SAPI_CMD_CONFIG_CIPHERING,
- SAPI_CMD_CONFIG_LOGCH_PARAM,
- SAPI_CMD_SACCH_REL_MARKER,
- SAPI_CMD_REL_MARKER,
- SAPI_CMD_DEACTIVATE,
-};
-
-struct sapi_cmd {
- struct llist_head entry;
- GsmL1_Sapi_t sapi;
- GsmL1_Dir_t dir;
- enum sapi_cmd_type type;
- int (*callback)(struct gsm_lchan *lchan, int status);
-};
-
-static const enum GsmL1_LogChComb_t pchan_to_logChComb[_GSM_PCHAN_MAX] = {
- [GSM_PCHAN_NONE] = GsmL1_LogChComb_0,
- [GSM_PCHAN_CCCH] = GsmL1_LogChComb_IV,
- [GSM_PCHAN_CCCH_SDCCH4] = GsmL1_LogChComb_V,
- [GSM_PCHAN_CCCH_SDCCH4_CBCH] = GsmL1_LogChComb_V,
- [GSM_PCHAN_TCH_F] = GsmL1_LogChComb_I,
- [GSM_PCHAN_TCH_H] = GsmL1_LogChComb_II,
- [GSM_PCHAN_SDCCH8_SACCH8C] = GsmL1_LogChComb_VII,
- [GSM_PCHAN_SDCCH8_SACCH8C_CBCH] = GsmL1_LogChComb_VII,
- [GSM_PCHAN_PDCH] = GsmL1_LogChComb_XIII,
- [GSM_PCHAN_UNKNOWN] = GsmL1_LogChComb_0,
- /*
- * GSM_PCHAN_TCH_F_PDCH and GSM_PCHAN_TCH_F_TCH_H_PDCH should not be
- * part of this, only "real" pchan values will be looked up here.
- * See the callers of ts_connect_as().
- */
-};
-
-static int trx_rf_lock(struct gsm_bts_trx *trx, int locked, l1if_compl_cb *cb);
-
-static void *prim_init(GsmL1_Prim_t *prim, GsmL1_PrimId_t id, struct lc15l1_hdl *gl1,
- uint32_t hLayer3_uint32)
-{
- HANDLE hLayer3;
- prim->id = id;
-
- osmo_static_assert(sizeof(HANDLE) >= 4, l1p_handle_is_at_least_32bit);
- hLayer3 = (void*)hLayer3_uint32;
-
- switch (id) {
- case GsmL1_PrimId_MphInitReq:
- //prim->u.mphInitReq.hLayer1 = (HANDLE)gl1->hLayer1;
- prim->u.mphInitReq.hLayer3 = hLayer3;
- break;
- case GsmL1_PrimId_MphCloseReq:
- prim->u.mphCloseReq.hLayer1 = gl1->hLayer1;
- prim->u.mphCloseReq.hLayer3 = hLayer3;
- break;
- case GsmL1_PrimId_MphConnectReq:
- prim->u.mphConnectReq.hLayer1 = gl1->hLayer1;
- prim->u.mphConnectReq.hLayer3 = hLayer3;
- break;
- case GsmL1_PrimId_MphDisconnectReq:
- prim->u.mphDisconnectReq.hLayer1 = gl1->hLayer1;
- prim->u.mphDisconnectReq.hLayer3 = hLayer3;
- break;
- case GsmL1_PrimId_MphActivateReq:
- prim->u.mphActivateReq.hLayer1 = gl1->hLayer1;
- prim->u.mphActivateReq.hLayer3 = hLayer3;
- break;
- case GsmL1_PrimId_MphDeactivateReq:
- prim->u.mphDeactivateReq.hLayer1 = gl1->hLayer1;
- prim->u.mphDeactivateReq.hLayer3 = hLayer3;
- break;
- case GsmL1_PrimId_MphConfigReq:
- prim->u.mphConfigReq.hLayer1 = gl1->hLayer1;
- prim->u.mphConfigReq.hLayer3 = hLayer3;
- break;
- case GsmL1_PrimId_MphMeasureReq:
- prim->u.mphMeasureReq.hLayer1 = gl1->hLayer1;
- prim->u.mphMeasureReq.hLayer3 = hLayer3;
- break;
- case GsmL1_PrimId_MphInitCnf:
- prim->u.mphInitCnf.hLayer3 = hLayer3;
- break;
- case GsmL1_PrimId_MphCloseCnf:
- prim->u.mphCloseCnf.hLayer3 = hLayer3;
- break;
- case GsmL1_PrimId_MphConnectCnf:
- prim->u.mphConnectCnf.hLayer3 = hLayer3;
- break;
- case GsmL1_PrimId_MphDisconnectCnf:
- prim->u.mphDisconnectCnf.hLayer3 = hLayer3;
- break;
- case GsmL1_PrimId_MphActivateCnf:
- prim->u.mphActivateCnf.hLayer3 = hLayer3;
- break;
- case GsmL1_PrimId_MphDeactivateCnf:
- prim->u.mphDeactivateCnf.hLayer3 = hLayer3;
- break;
- case GsmL1_PrimId_MphConfigCnf:
- prim->u.mphConfigCnf.hLayer3 = hLayer3;
- break;
- case GsmL1_PrimId_MphMeasureCnf:
- prim->u.mphMeasureCnf.hLayer3 = hLayer3;
- break;
- case GsmL1_PrimId_MphTimeInd:
- break;
- case GsmL1_PrimId_MphSyncInd:
- break;
- case GsmL1_PrimId_PhEmptyFrameReq:
- prim->u.phEmptyFrameReq.hLayer1 = gl1->hLayer1;
- break;
- case GsmL1_PrimId_PhDataReq:
- prim->u.phDataReq.hLayer1 = gl1->hLayer1;
- break;
- case GsmL1_PrimId_PhConnectInd:
- break;
- case GsmL1_PrimId_PhReadyToSendInd:
- break;
- case GsmL1_PrimId_PhDataInd:
- break;
- case GsmL1_PrimId_PhRaInd:
- break;
- default:
- LOGP(DL1C, LOGL_ERROR, "unknown L1 primitive %u\n", id);
- break;
- }
- return &prim->u;
-}
-
-static uint32_t l1p_handle_for_trx(struct gsm_bts_trx *trx)
-{
- struct gsm_bts *bts = trx->bts;
-
- osmo_static_assert(sizeof(trx->nr) == 1, trx_nr_is_8bit);
- osmo_static_assert(sizeof(bts->nr) == 1, bts_nr_is_8bit);
-
- return bts->nr << 24
- | trx->nr << 16;
-}
-
-static uint32_t l1p_handle_for_ts(struct gsm_bts_trx_ts *ts)
-{
- osmo_static_assert(sizeof(ts->nr) == 1, ts_nr_is_8bit);
-
- return l1p_handle_for_trx(ts->trx)
- | ts->nr << 8;
-}
-
-
-static uint32_t l1p_handle_for_lchan(struct gsm_lchan *lchan)
-{
- osmo_static_assert(sizeof(lchan->nr) == 1, lchan_nr_is_8bit);
-
- return l1p_handle_for_ts(lchan->ts)
- | lchan->nr;
-}
-
-GsmL1_Status_t prim_status(GsmL1_Prim_t *prim)
-{
- switch (prim->id) {
- case GsmL1_PrimId_MphInitCnf:
- return prim->u.mphInitCnf.status;
- case GsmL1_PrimId_MphCloseCnf:
- return prim->u.mphCloseCnf.status;
- case GsmL1_PrimId_MphConnectCnf:
- return prim->u.mphConnectCnf.status;
- case GsmL1_PrimId_MphDisconnectCnf:
- return prim->u.mphDisconnectCnf.status;
- case GsmL1_PrimId_MphActivateCnf:
- return prim->u.mphActivateCnf.status;
- case GsmL1_PrimId_MphDeactivateCnf:
- return prim->u.mphDeactivateCnf.status;
- case GsmL1_PrimId_MphConfigCnf:
- return prim->u.mphConfigCnf.status;
- case GsmL1_PrimId_MphMeasureCnf:
- return prim->u.mphMeasureCnf.status;
- default:
- break;
- }
- return GsmL1_Status_Success;
-}
-
-#if 0
-static int compl_cb_send_oml_msg(struct msgb *l1_msg, void *data)
-{
- struct msgb *resp_msg = data;
- GsmL1_Prim_t *l1p = msgb_l1prim(l1_msg);
-
- if (prim_status(l1p) != GsmL1_Status_Success) {
- LOGP(DL1C, LOGL_ERROR, "Rx %s, status: %s\n",
- get_value_string(lc15bts_l1prim_names, l1p->id),
- get_value_string(lc15bts_l1status_names, cc->status));
- return 0;
- }
-
- msgb_free(l1_msg);
-
- return abis_nm_sendmsg(msg);
-}
-#endif
-
-int lchan_activate(struct gsm_lchan *lchan);
-
-static int opstart_compl(struct gsm_abis_mo *mo, struct msgb *l1_msg)
-{
- GsmL1_Prim_t *l1p = msgb_l1prim(l1_msg);
- GsmL1_Status_t status = prim_status(l1p);
- struct gsm_bts_trx *trx = gsm_bts_trx_num(mo->bts, mo->obj_inst.trx_nr);
-
- if (status != GsmL1_Status_Success) {
- LOGP(DL1C, LOGL_ERROR, "Rx %s, status: %s\n",
- get_value_string(lc15bts_l1prim_names, l1p->id),
- get_value_string(lc15bts_l1status_names, status));
- msgb_free(l1_msg);
- switch (mo->obj_class) {
- case NM_OC_RADIO_CARRIER:
- return osmo_fsm_inst_dispatch(trx->mo.fi, NM_EV_OPSTART_NACK,
- (void*)(intptr_t)NM_NACK_CANT_PERFORM);
- case NM_OC_CHANNEL:
- return osmo_fsm_inst_dispatch(trx->ts[mo->obj_inst.ts_nr].mo.fi, NM_EV_OPSTART_NACK,
- (void*)(intptr_t)NM_NACK_CANT_PERFORM);
- default:
- OSMO_ASSERT(0);
- }
- }
-
- msgb_free(l1_msg);
- switch (mo->obj_class) {
- case NM_OC_RADIO_CARRIER:
- return osmo_fsm_inst_dispatch(trx->mo.fi, NM_EV_OPSTART_ACK, NULL);
- case NM_OC_CHANNEL:
- /* ugly hack to auto-activate all SAPIs for the BCCH/CCCH on TS0 */
- if (mo->obj_inst.trx_nr == 0 &&
- mo->obj_inst.ts_nr == 0) {
- struct gsm_lchan *cbch = gsm_bts_get_cbch(mo->bts);
- DEBUGP(DL1C, "====> trying to activate lchans of BCCH\n");
- mo->bts->c0->ts[0].lchan[CCCH_LCHAN].rel_act_kind =
- LCHAN_REL_ACT_OML;
- lchan_activate(&mo->bts->c0->ts[0].lchan[CCCH_LCHAN]);
- if (cbch) {
- cbch->rel_act_kind = LCHAN_REL_ACT_OML;
- lchan_activate(cbch);
- }
- }
- return osmo_fsm_inst_dispatch(trx->ts[mo->obj_inst.ts_nr].mo.fi,
- NM_EV_OPSTART_ACK, NULL);
- default:
- OSMO_ASSERT(0);
- }
-}
-
-static int opstart_compl_cb(struct gsm_bts_trx *trx, struct msgb *l1_msg,
- void *data)
-{
- struct gsm_abis_mo *mo;
- GsmL1_Prim_t *l1p = msgb_l1prim(l1_msg);
- GsmL1_MphConnectCnf_t *cnf = &l1p->u.mphConnectCnf;
-
- mo = &trx->ts[cnf->u8Tn].mo;
- return opstart_compl(mo, l1_msg);
-}
-
-static int trx_mute_on_init_cb(struct gsm_bts_trx *trx, struct msgb *resp,
- void *data)
-{
- Litecell15_Prim_t *sysp = msgb_sysprim(resp);
- GsmL1_Status_t status;
-
- status = sysp->u.muteRfCnf.status;
-
- if (status != GsmL1_Status_Success) {
- LOGP(DL1C, LOGL_FATAL, "Rx RF-MUTE.conf status=%s\n",
- get_value_string(lc15bts_l1status_names, status));
- bts_shutdown(trx->bts, "RF-MUTE failure");
- }
-
- msgb_free(resp);
-
- return 0;
-}
-
-static int trx_init_compl_cb(struct gsm_bts_trx *trx, struct msgb *l1_msg,
- void *data)
-{
- struct lc15l1_hdl *fl1h = trx_lc15l1_hdl(trx);
-
- GsmL1_Prim_t *l1p = msgb_l1prim(l1_msg);
- GsmL1_MphInitCnf_t *ic = &l1p->u.mphInitCnf;
-
- LOGP(DL1C, LOGL_INFO, "Rx MPH-INIT.conf (status=%s)\n",
- get_value_string(lc15bts_l1status_names, ic->status));
-
- /* store layer1 handle */
- if (ic->status != GsmL1_Status_Success) {
- LOGP(DL1C, LOGL_FATAL, "Rx MPH-INIT.conf status=%s\n",
- get_value_string(lc15bts_l1status_names, ic->status));
- bts_shutdown(trx->bts, "MPH-INIT failure");
- }
-
- fl1h->hLayer1 = ic->hLayer1;
-
- /* If the TRX was already locked the MphInit would have undone it */
- if (trx->mo.nm_state.administrative == NM_STATE_LOCKED)
- trx_rf_lock(trx, 1, trx_mute_on_init_cb);
-
- /* Begin to ramp up the power */
- power_ramp_start(trx, get_p_target_mdBm(trx, 0), 0, NULL);
-
- return opstart_compl(&trx->mo, l1_msg);
-}
-
-int gsm_abis_mo_check_attr(const struct gsm_abis_mo *mo, const uint8_t *attr_ids,
- unsigned int num_attr_ids)
-{
- unsigned int i;
-
- if (!mo->nm_attr)
- return 0;
-
- for (i = 0; i < num_attr_ids; i++) {
- if (!TLVP_PRESENT(mo->nm_attr, attr_ids[i]))
- return 0;
- }
- return 1;
-}
-
-static const uint8_t trx_rqd_attr[] = { NM_ATT_RF_MAXPOWR_R };
-
-/* initialize the layer1 */
-static int trx_init(struct gsm_bts_trx *trx)
-{
- struct lc15l1_hdl *fl1h = trx_lc15l1_hdl(trx);
- struct msgb *msg;
- GsmL1_MphInitReq_t *mi_req;
- GsmL1_DeviceParam_t *dev_par;
- int rc, lc15_band;
-
- if (!gsm_abis_mo_check_attr(&trx->mo, trx_rqd_attr,
- ARRAY_SIZE(trx_rqd_attr))) {
- /* HACK: spec says we need to decline, but openbsc
- * doesn't deal with this very well */
- return osmo_fsm_inst_dispatch(trx->mo.fi, NM_EV_OPSTART_ACK, NULL);
- //return osmo_fsm_inst_dispatch(trx->mo.fi, NM_EV_OPSTART_NACK,
- // (void*)(intptr_t)NM_NACK_CANT_PERFORM);
- }
-
- /* Update TRX band */
- rc = gsm_arfcn2band_rc(trx->arfcn, &trx->bts->band);
- if (rc) {
- /* FIXME: abort initialization? */
- LOGP(DL1C, LOGL_ERROR, "Could not pick GSM band "
- "for ARFCN %u\n", trx->arfcn);
- trx->bts->band = 0x00;
- }
-
- lc15_band = lc15bts_select_lc15_band(trx, trx->arfcn);
- if (lc15_band < 0) {
- LOGP(DL1C, LOGL_ERROR, "Unsupported GSM band %s\n",
- gsm_band_name(trx->bts->band));
- }
-
- msg = l1p_msgb_alloc();
- mi_req = prim_init(msgb_l1prim(msg), GsmL1_PrimId_MphInitReq, fl1h,
- l1p_handle_for_trx(trx));
- dev_par = &mi_req->deviceParam;
- dev_par->devType = GsmL1_DevType_TxdRxu;
- dev_par->freqBand = lc15_band;
- dev_par->u16Arfcn = trx->arfcn;
- dev_par->u16BcchArfcn = trx->bts->c0->arfcn;
- dev_par->u8NbTsc = trx->bts->bsic & 7;
- dev_par->fRxPowerLevel = trx_ms_pwr_ctrl_is_osmo(trx)
- ? 0.0 : trx->bts->ul_power_target;
-
- dev_par->fTxPowerLevel = 0.0;
- LOGP(DL1C, LOGL_NOTICE, "Init TRX (Band %d, ARFCN %u, TSC %u, RxPower % 2f dBm, "
- "TxPower % 2.2f dBm\n", dev_par->freqBand, dev_par->u16Arfcn, dev_par->u8NbTsc,
- dev_par->fRxPowerLevel, dev_par->fTxPowerLevel);
-
- /* send MPH-INIT-REQ, wait for MPH-INIT-CNF */
- return l1if_gsm_req_compl(fl1h, msg, trx_init_compl_cb, NULL);
-}
-
-uint32_t trx_get_hlayer1(const struct gsm_bts_trx *trx)
-{
- const struct lc15l1_hdl *fl1h = trx_lc15l1_hdl(trx);
-
- return fl1h->hLayer1;
-}
-
-static int trx_close_compl_cb(struct gsm_bts_trx *trx, struct msgb *l1_msg,
- void *data)
-{
- msgb_free(l1_msg);
- bts_model_trx_close_cb(trx, 0);
- return 0;
-}
-
-void bts_model_trx_close(struct gsm_bts_trx *trx)
-{
- struct lc15l1_hdl *fl1h = trx_lc15l1_hdl(trx);
- struct msgb *msg;
- int rc;
-
- msg = l1p_msgb_alloc();
- prim_init(msgb_l1prim(msg), GsmL1_PrimId_MphCloseReq, fl1h,
- l1p_handle_for_trx(trx));
- LOGP(DL1C, LOGL_NOTICE, "Close TRX %u\n", trx->nr);
-
- rc = l1if_gsm_req_compl(fl1h, msg, trx_close_compl_cb, NULL);
- if (rc < 0)
- bts_model_trx_close_cb(trx, rc);
-}
-
-static int trx_rf_lock(struct gsm_bts_trx *trx, int locked, l1if_compl_cb *cb)
-{
- struct lc15l1_hdl *fl1h = trx_lc15l1_hdl(trx);
- uint8_t mute[8];
- int i;
-
- for (i = 0; i < ARRAY_SIZE(mute); ++i)
- mute[i] = locked ? 1 : 0;
-
- return l1if_mute_rf(fl1h, mute, cb);
-}
-
-int oml_mo_rf_lock_chg(struct gsm_abis_mo *mo, uint8_t mute_state[8],
- int success)
-{
- if (success) {
- int i;
- int is_locked = 1;
-
- for (i = 0; i < 8; ++i)
- if (!mute_state[i])
- is_locked = 0;
-
- mo->nm_state.administrative =
- is_locked ? NM_STATE_LOCKED : NM_STATE_UNLOCKED;
- mo->procedure_pending = 0;
- return oml_mo_statechg_ack(mo);
- } else {
- mo->procedure_pending = 0;
- return oml_mo_statechg_nack(mo, NM_NACK_REQ_NOT_GRANT);
- }
-}
-
-static int ts_connect_as(struct gsm_bts_trx_ts *ts,
- enum gsm_phys_chan_config pchan,
- l1if_compl_cb *cb, void *data)
-{
- struct msgb *msg = l1p_msgb_alloc();
- struct lc15l1_hdl *fl1h = trx_lc15l1_hdl(ts->trx);
- GsmL1_MphConnectReq_t *cr;
-
- if (pchan == GSM_PCHAN_TCH_F_PDCH
- || pchan == GSM_PCHAN_TCH_F_TCH_H_PDCH) {
- LOGP(DL1C, LOGL_ERROR,
- "%s Requested TS connect as %s,"
- " expected a specific pchan instead\n",
- gsm_ts_and_pchan_name(ts), gsm_pchan_name(pchan));
- return -EINVAL;
- }
-
- cr = prim_init(msgb_l1prim(msg), GsmL1_PrimId_MphConnectReq, fl1h,
- l1p_handle_for_ts(ts));
- cr->u8Tn = ts->nr;
- cr->logChComb = pchan_to_logChComb[pchan];
-
- return l1if_gsm_req_compl(fl1h, msg, cb, NULL);
-}
-
-static int ts_opstart(struct gsm_bts_trx_ts *ts)
-{
- enum gsm_phys_chan_config pchan = ts->pchan;
- switch (pchan) {
- case GSM_PCHAN_TCH_F_TCH_H_PDCH:
- ts->dyn.pchan_is = ts->dyn.pchan_want = GSM_PCHAN_NONE;
- /* First connect as NONE, until first RSL CHAN ACT. */
- pchan = GSM_PCHAN_NONE;
- break;
- case GSM_PCHAN_TCH_F_PDCH:
- /* First connect as TCH/F, expecting PDCH ACT. */
- pchan = GSM_PCHAN_TCH_F;
- break;
- default:
- /* simply use ts->pchan */
- break;
- }
- return ts_connect_as(ts, pchan, opstart_compl_cb, NULL);
-}
-
-GsmL1_Sapi_t lchan_to_GsmL1_Sapi_t(const struct gsm_lchan *lchan)
-{
- switch (lchan->type) {
- case GSM_LCHAN_TCH_F:
- return GsmL1_Sapi_TchF;
- case GSM_LCHAN_TCH_H:
- return GsmL1_Sapi_TchH;
- default:
- LOGP(DL1C, LOGL_NOTICE, "%s cannot determine L1 SAPI\n",
- gsm_lchan_name(lchan));
- break;
- }
- return GsmL1_Sapi_Idle;
-}
-
-GsmL1_SubCh_t lchan_to_GsmL1_SubCh_t(const struct gsm_lchan *lchan)
-{
- enum gsm_phys_chan_config pchan = lchan->ts->pchan;
-
- if (pchan == GSM_PCHAN_TCH_F_TCH_H_PDCH)
- pchan = lchan->ts->dyn.pchan_want;
-
- switch (pchan) {
- case GSM_PCHAN_CCCH_SDCCH4:
- case GSM_PCHAN_CCCH_SDCCH4_CBCH:
- if (lchan->type == GSM_LCHAN_CCCH)
- return GsmL1_SubCh_NA;
- /* fall-through */
- case GSM_PCHAN_TCH_H:
- case GSM_PCHAN_SDCCH8_SACCH8C:
- case GSM_PCHAN_SDCCH8_SACCH8C_CBCH:
- return lchan->nr;
- case GSM_PCHAN_NONE:
- case GSM_PCHAN_CCCH:
- case GSM_PCHAN_TCH_F:
- case GSM_PCHAN_PDCH:
- case GSM_PCHAN_UNKNOWN:
- default:
- /* case GSM_PCHAN_TCH_F_TCH_H_PDCH: is caught above */
- return GsmL1_SubCh_NA;
- }
-
- return GsmL1_SubCh_NA;
-}
-
-struct sapi_dir {
- GsmL1_Sapi_t sapi;
- GsmL1_Dir_t dir;
-};
-
-static const struct sapi_dir ccch_sapis[] = {
- { GsmL1_Sapi_Fcch, GsmL1_Dir_TxDownlink },
- { GsmL1_Sapi_Sch, GsmL1_Dir_TxDownlink },
- { GsmL1_Sapi_Bcch, GsmL1_Dir_TxDownlink },
- { GsmL1_Sapi_Agch, GsmL1_Dir_TxDownlink },
- { GsmL1_Sapi_Pch, GsmL1_Dir_TxDownlink },
- { GsmL1_Sapi_Rach, GsmL1_Dir_RxUplink },
-};
-
-static const struct sapi_dir tchf_sapis[] = {
- { GsmL1_Sapi_TchF, GsmL1_Dir_TxDownlink },
- { GsmL1_Sapi_TchF, GsmL1_Dir_RxUplink },
- { GsmL1_Sapi_FacchF, GsmL1_Dir_TxDownlink },
- { GsmL1_Sapi_FacchF, GsmL1_Dir_RxUplink },
- { GsmL1_Sapi_Sacch, GsmL1_Dir_TxDownlink },
- { GsmL1_Sapi_Sacch, GsmL1_Dir_RxUplink },
-};
-
-static const struct sapi_dir tchh_sapis[] = {
- { GsmL1_Sapi_TchH, GsmL1_Dir_TxDownlink },
- { GsmL1_Sapi_TchH, GsmL1_Dir_RxUplink },
- { GsmL1_Sapi_FacchH, GsmL1_Dir_TxDownlink },
- { GsmL1_Sapi_FacchH, GsmL1_Dir_RxUplink },
- { GsmL1_Sapi_Sacch, GsmL1_Dir_TxDownlink },
- { GsmL1_Sapi_Sacch, GsmL1_Dir_RxUplink },
-};
-
-static const struct sapi_dir sdcch_sapis[] = {
- { GsmL1_Sapi_Sdcch, GsmL1_Dir_TxDownlink },
- { GsmL1_Sapi_Sdcch, GsmL1_Dir_RxUplink },
- { GsmL1_Sapi_Sacch, GsmL1_Dir_TxDownlink },
- { GsmL1_Sapi_Sacch, GsmL1_Dir_RxUplink },
-};
-
-static const struct sapi_dir cbch_sapis[] = {
- { GsmL1_Sapi_Cbch, GsmL1_Dir_TxDownlink },
- /* Does the CBCH really have a SACCH in Downlink? */
- { GsmL1_Sapi_Sacch, GsmL1_Dir_TxDownlink },
-};
-
-static const struct sapi_dir pdtch_sapis[] = {
- { GsmL1_Sapi_Pdtch, GsmL1_Dir_TxDownlink },
- { GsmL1_Sapi_Pdtch, GsmL1_Dir_RxUplink },
- { GsmL1_Sapi_Ptcch, GsmL1_Dir_TxDownlink },
- { GsmL1_Sapi_Prach, GsmL1_Dir_RxUplink },
-#if 0
- { GsmL1_Sapi_Ptcch, GsmL1_Dir_RxUplink },
- { GsmL1_Sapi_Pacch, GsmL1_Dir_TxDownlink },
-#endif
-};
-
-static const struct sapi_dir ho_sapis[] = {
- { GsmL1_Sapi_Rach, GsmL1_Dir_RxUplink },
-};
-
-struct lchan_sapis {
- const struct sapi_dir *sapis;
- unsigned int num_sapis;
-};
-
-static const struct lchan_sapis sapis_for_lchan[_GSM_LCHAN_MAX] = {
- [GSM_LCHAN_SDCCH] = {
- .sapis = sdcch_sapis,
- .num_sapis = ARRAY_SIZE(sdcch_sapis),
- },
- [GSM_LCHAN_TCH_F] = {
- .sapis = tchf_sapis,
- .num_sapis = ARRAY_SIZE(tchf_sapis),
- },
- [GSM_LCHAN_TCH_H] = {
- .sapis = tchh_sapis,
- .num_sapis = ARRAY_SIZE(tchh_sapis),
- },
- [GSM_LCHAN_CCCH] = {
- .sapis = ccch_sapis,
- .num_sapis = ARRAY_SIZE(ccch_sapis),
- },
- [GSM_LCHAN_PDTCH] = {
- .sapis = pdtch_sapis,
- .num_sapis = ARRAY_SIZE(pdtch_sapis),
- },
- [GSM_LCHAN_CBCH] = {
- .sapis = cbch_sapis,
- .num_sapis = ARRAY_SIZE(cbch_sapis),
- },
-};
-
-static const struct lchan_sapis sapis_for_ho = {
- .sapis = ho_sapis,
- .num_sapis = ARRAY_SIZE(ho_sapis),
-};
-
-static int mph_send_activate_req(struct gsm_lchan *lchan, struct sapi_cmd *cmd);
-static int mph_send_deactivate_req(struct gsm_lchan *lchan, struct sapi_cmd *cmd);
-static int mph_send_config_ciphering(struct gsm_lchan *lchan, struct sapi_cmd *cmd);
-static int mph_send_config_logchpar(struct gsm_lchan *lchan, struct sapi_cmd *cmd);
-
-static int check_sapi_release(struct gsm_lchan *lchan, int sapi, int dir);
-static int lchan_deactivate_sapis(struct gsm_lchan *lchan);
-
-/**
- * Execute the first SAPI command of the queue. In case of the markers
- * this method is re-entrant so we need to make sure to remove a command
- * from the list before calling a function that will queue a command.
- *
- * \return 0 in case no Gsm Request was sent, 1 otherwise
- */
-static int sapi_queue_exeute(struct gsm_lchan *lchan)
-{
- int res;
- struct sapi_cmd *cmd;
-
- cmd = llist_entry(lchan->sapi_cmds.next, struct sapi_cmd, entry);
-
- switch (cmd->type) {
- case SAPI_CMD_ACTIVATE:
- mph_send_activate_req(lchan, cmd);
- res = 1;
- break;
- case SAPI_CMD_CONFIG_CIPHERING:
- mph_send_config_ciphering(lchan, cmd);
- res = 1;
- break;
- case SAPI_CMD_CONFIG_LOGCH_PARAM:
- mph_send_config_logchpar(lchan, cmd);
- res = 1;
- break;
- case SAPI_CMD_SACCH_REL_MARKER:
- llist_del(&cmd->entry);
- talloc_free(cmd);
- res = check_sapi_release(lchan, GsmL1_Sapi_Sacch,
- GsmL1_Dir_TxDownlink);
- res |= check_sapi_release(lchan, GsmL1_Sapi_Sacch,
- GsmL1_Dir_RxUplink);
- break;
- case SAPI_CMD_REL_MARKER:
- llist_del(&cmd->entry);
- talloc_free(cmd);
- res = lchan_deactivate_sapis(lchan);
- break;
- case SAPI_CMD_DEACTIVATE:
- mph_send_deactivate_req(lchan, cmd);
- res = 1;
- break;
- default:
- LOGP(DL1C, LOGL_NOTICE,
- "Unimplemented command type %d\n", cmd->type);
- llist_del(&cmd->entry);
- talloc_free(cmd);
- res = 0;
- abort();
- break;
- }
-
- return res;
-}
-
-static void sapi_queue_send(struct gsm_lchan *lchan)
-{
- int res;
-
- do {
- res = sapi_queue_exeute(lchan);
- } while (res == 0 && !llist_empty(&lchan->sapi_cmds));
-}
-
-static void sapi_queue_dispatch(struct gsm_lchan *lchan, int status)
-{
- int end;
- struct sapi_cmd *cmd = llist_entry(lchan->sapi_cmds.next,
- struct sapi_cmd, entry);
- llist_del(&cmd->entry);
- end = llist_empty(&lchan->sapi_cmds);
-
- if (cmd->callback)
- cmd->callback(lchan, status);
- talloc_free(cmd);
-
- if (end || llist_empty(&lchan->sapi_cmds)) {
- LOGP(DL1C, LOGL_DEBUG,
- "%s End of SAPI cmd queue encountered.%s\n",
- gsm_lchan_name(lchan),
- llist_empty(&lchan->sapi_cmds)
- ? " Queue is now empty."
- : " More pending.");
- return;
- }
-
- sapi_queue_send(lchan);
-}
-
-/**
- * Queue and possible execute a SAPI command. Return 1 in case the command was
- * already executed and 0 in case if it was only put into the queue
- */
-static int queue_sapi_command(struct gsm_lchan *lchan, struct sapi_cmd *cmd)
-{
- int start = llist_empty(&lchan->sapi_cmds);
- llist_add_tail(&cmd->entry, &lchan->sapi_cmds);
-
- if (!start)
- return 0;
-
- sapi_queue_send(lchan);
- return 1;
-}
-
-static int lchan_act_compl_cb(struct gsm_bts_trx *trx, struct msgb *l1_msg,
- void *data)
-{
- enum lchan_sapi_state status;
- struct sapi_cmd *cmd;
- struct gsm_lchan *lchan;
- GsmL1_Prim_t *l1p = msgb_l1prim(l1_msg);
- GsmL1_MphActivateCnf_t *ic = &l1p->u.mphActivateCnf;
-
- /* get the lchan from the information we supplied */
- lchan = l1if_hLayer_to_lchan(trx, (uint32_t)ic->hLayer3);
- if (!lchan) {
- LOGP(DL1C, LOGL_ERROR,
- "Failed to find lchan for hLayer3=0x%x\n", (uint32_t)ic->hLayer3);
- goto err;
- }
-
- LOGP(DL1C, LOGL_INFO, "%s MPH-ACTIVATE.conf (%s ",
- gsm_lchan_name(lchan),
- get_value_string(lc15bts_l1sapi_names, ic->sapi));
- LOGPC(DL1C, LOGL_INFO, "%s)\n",
- get_value_string(lc15bts_dir_names, ic->dir));
-
- if (ic->status == GsmL1_Status_Success) {
- DEBUGP(DL1C, "Successful activation of L1 SAPI %s on TS %u\n",
- get_value_string(lc15bts_l1sapi_names, ic->sapi), ic->u8Tn);
- status = LCHAN_SAPI_S_ASSIGNED;
- } else {
- LOGP(DL1C, LOGL_ERROR, "Error activating L1 SAPI %s on TS %u: %s\n",
- get_value_string(lc15bts_l1sapi_names, ic->sapi), ic->u8Tn,
- get_value_string(lc15bts_l1status_names, ic->status));
- status = LCHAN_SAPI_S_ERROR;
- }
-
- if (ic->dir & GsmL1_Dir_TxDownlink)
- lchan->sapis_dl[ic->sapi] = status;
- if (ic->dir & GsmL1_Dir_RxUplink)
- lchan->sapis_ul[ic->sapi] = status;
-
- if (llist_empty(&lchan->sapi_cmds)) {
- LOGP(DL1C, LOGL_ERROR,
- "%s Got activation confirmation with empty queue\n",
- gsm_lchan_name(lchan));
- goto err;
- }
-
- cmd = llist_entry(lchan->sapi_cmds.next, struct sapi_cmd, entry);
- if (cmd->sapi != ic->sapi || cmd->dir != ic->dir ||
- cmd->type != SAPI_CMD_ACTIVATE) {
- LOGP(DL1C, LOGL_ERROR,
- "%s Confirmation mismatch (%d, %d) (%d, %d)\n",
- gsm_lchan_name(lchan), cmd->sapi, cmd->dir,
- ic->sapi, ic->dir);
- goto err;
- }
-
- sapi_queue_dispatch(lchan, ic->status);
-
-err:
- msgb_free(l1_msg);
-
- return 0;
-}
-
-uint32_t l1if_lchan_to_hLayer(struct gsm_lchan *lchan)
-{
- return 0xBB
- | (lchan->nr << 8)
- | (lchan->ts->nr << 16)
- | (lchan->ts->trx->nr << 24);
-}
-
-/* obtain a ptr to the lapdm_channel for a given hLayer */
-struct gsm_lchan *
-l1if_hLayer_to_lchan(struct gsm_bts_trx *trx, uint32_t hLayer2)
-{
- uint8_t magic = hLayer2 & 0xff;
- uint8_t ts_nr = (hLayer2 >> 16) & 0xff;
- uint8_t lchan_nr = (hLayer2 >> 8)& 0xff;
- struct gsm_bts_trx_ts *ts;
-
- if (magic != 0xBB)
- return NULL;
-
- /* FIXME: if we actually run on the BTS, the 32bit field is large
- * enough to simply put a pointer inside. */
- if (ts_nr >= ARRAY_SIZE(trx->ts))
- return NULL;
-
- ts = &trx->ts[ts_nr];
-
- if (lchan_nr >= ARRAY_SIZE(ts->lchan))
- return NULL;
-
- return &ts->lchan[lchan_nr];
-}
-
-/* we regularly check if the DSP L1 is still sending us primitives.
- * if not, we simply stop the BTS program (and be re-spawned) */
-static void alive_timer_cb(void *data)
-{
- struct lc15l1_hdl *fl1h = data;
-
- if (fl1h->alive_prim_cnt == 0) {
- LOGP(DL1C, LOGL_FATAL, "DSP L1 is no longer sending primitives!\n");
- exit(23);
- }
- fl1h->alive_prim_cnt = 0;
- osmo_timer_schedule(&fl1h->alive_timer, 5, 0);
-}
-
-static void clear_amr_params(GsmL1_LogChParam_t *lch_par)
-{
- int j;
- /* common for the SIGN, V1 and EFR: */
- lch_par->tch.amrCmiPhase = GsmL1_AmrCmiPhase_NA;
- lch_par->tch.amrInitCodecMode = GsmL1_AmrCodecMode_Unset;
- for (j = 0; j < ARRAY_SIZE(lch_par->tch.amrActiveCodecSet); j++)
- lch_par->tch.amrActiveCodecSet[j] = GsmL1_AmrCodec_Unset;
-}
-
-static void set_payload_format(GsmL1_LogChParam_t *lch_par)
-{
- lch_par->tch.tchPlFmt = GsmL1_TchPlFmt_Rtp;
-}
-
-static void lchan2lch_par(GsmL1_LogChParam_t *lch_par, struct gsm_lchan *lchan)
-{
- struct amr_multirate_conf *amr_mrc = &lchan->tch.amr_mr;
- struct gsm48_multi_rate_conf *mr_conf =
- (struct gsm48_multi_rate_conf *) amr_mrc->gsm48_ie;
- int j;
-
- LOGP(DL1C, LOGL_INFO, "%s: %s tch_mode=0x%02x\n",
- gsm_lchan_name(lchan), __FUNCTION__, lchan->tch_mode);
-
- switch (lchan->tch_mode) {
- case GSM48_CMODE_SIGN:
- /* we have to set some TCH payload type even if we don't
- * know yet what codec we will use later on */
- if (lchan->type == GSM_LCHAN_TCH_F)
- lch_par->tch.tchPlType = GsmL1_TchPlType_Fr;
- else
- lch_par->tch.tchPlType = GsmL1_TchPlType_Hr;
- clear_amr_params(lch_par);
- break;
- case GSM48_CMODE_SPEECH_V1:
- if (lchan->type == GSM_LCHAN_TCH_F)
- lch_par->tch.tchPlType = GsmL1_TchPlType_Fr;
- else
- lch_par->tch.tchPlType = GsmL1_TchPlType_Hr;
- set_payload_format(lch_par);
- clear_amr_params(lch_par);
- break;
- case GSM48_CMODE_SPEECH_EFR:
- lch_par->tch.tchPlType = GsmL1_TchPlType_Efr;
- set_payload_format(lch_par);
- clear_amr_params(lch_par);
- break;
- case GSM48_CMODE_SPEECH_AMR:
- lch_par->tch.tchPlType = GsmL1_TchPlType_Amr;
- set_payload_format(lch_par);
- lch_par->tch.amrCmiPhase = GsmL1_AmrCmiPhase_Odd; /* FIXME? */
- lch_par->tch.amrInitCodecMode = amr_get_initial_mode(lchan);
-
- /* initialize to clean state */
- for (j = 0; j < ARRAY_SIZE(lch_par->tch.amrActiveCodecSet); j++)
- lch_par->tch.amrActiveCodecSet[j] = GsmL1_AmrCodec_Unset;
-
- j = 0;
- if (mr_conf->m4_75)
- lch_par->tch.amrActiveCodecSet[j++] = GsmL1_AmrCodec_4_75;
- if (j >= ARRAY_SIZE(lch_par->tch.amrActiveCodecSet))
- break;
-
- if (mr_conf->m5_15)
- lch_par->tch.amrActiveCodecSet[j++] = GsmL1_AmrCodec_5_15;
- if (j >= ARRAY_SIZE(lch_par->tch.amrActiveCodecSet))
- break;
-
- if (mr_conf->m5_90)
- lch_par->tch.amrActiveCodecSet[j++] = GsmL1_AmrCodec_5_9;
- if (j >= ARRAY_SIZE(lch_par->tch.amrActiveCodecSet))
- break;
-
- if (mr_conf->m6_70)
- lch_par->tch.amrActiveCodecSet[j++] = GsmL1_AmrCodec_6_7;
- if (j >= ARRAY_SIZE(lch_par->tch.amrActiveCodecSet))
- break;
-
- if (mr_conf->m7_40)
- lch_par->tch.amrActiveCodecSet[j++] = GsmL1_AmrCodec_7_4;
- if (j >= ARRAY_SIZE(lch_par->tch.amrActiveCodecSet))
- break;
-
- if (mr_conf->m7_95)
- lch_par->tch.amrActiveCodecSet[j++] = GsmL1_AmrCodec_7_95;
- if (j >= ARRAY_SIZE(lch_par->tch.amrActiveCodecSet))
- break;
-
- if (mr_conf->m10_2)
- lch_par->tch.amrActiveCodecSet[j++] = GsmL1_AmrCodec_10_2;
- if (j >= ARRAY_SIZE(lch_par->tch.amrActiveCodecSet))
- break;
- if (mr_conf->m12_2)
- lch_par->tch.amrActiveCodecSet[j++] = GsmL1_AmrCodec_12_2;
- break;
- case GSM48_CMODE_DATA_14k5:
- case GSM48_CMODE_DATA_12k0:
- case GSM48_CMODE_DATA_6k0:
- case GSM48_CMODE_DATA_3k6:
- LOGP(DL1C, LOGL_ERROR, "%s: CSD not supported!\n",
- gsm_lchan_name(lchan));
- break;
- }
-}
-
-static int mph_send_activate_req(struct gsm_lchan *lchan, struct sapi_cmd *cmd)
-{
- struct lc15l1_hdl *fl1h = trx_lc15l1_hdl(lchan->ts->trx);
- struct msgb *msg = l1p_msgb_alloc();
- int sapi = cmd->sapi;
- int dir = cmd->dir;
- GsmL1_MphActivateReq_t *act_req;
- GsmL1_LogChParam_t *lch_par;
-
- act_req = prim_init(msgb_l1prim(msg), GsmL1_PrimId_MphActivateReq,
- fl1h, l1p_handle_for_lchan(lchan));
- lch_par = &act_req->logChPrm;
- act_req->u8Tn = lchan->ts->nr;
- act_req->subCh = lchan_to_GsmL1_SubCh_t(lchan);
- act_req->dir = dir;
- act_req->sapi = sapi;
- act_req->hLayer2 = (HANDLE *)l1if_lchan_to_hLayer(lchan);
- act_req->hLayer3 = act_req->hLayer2;
-
- switch (act_req->sapi) {
- case GsmL1_Sapi_Rach:
- lch_par->rach.u8Bsic = lchan->ts->trx->bts->bsic;
- break;
- case GsmL1_Sapi_Agch:
- lch_par->agch.u8NbrOfAgch = num_agch(lchan->ts->trx, lchan->name);
- break;
- case GsmL1_Sapi_TchH:
- case GsmL1_Sapi_TchF:
- lchan2lch_par(lch_par, lchan);
- /*
- * Be sure that every packet is received, even if it
- * fails. In this case the length might be lower or 0.
- */
- act_req->fBFILevel = -200.0f;
- break;
- case GsmL1_Sapi_Ptcch:
- lch_par->ptcch.u8Bsic = lchan->ts->trx->bts->bsic;
- break;
- case GsmL1_Sapi_Prach:
- lch_par->prach.u8Bsic = lchan->ts->trx->bts->bsic;
- break;
- case GsmL1_Sapi_Sacch:
- /*
- * For the SACCH we need to set the u8MsPowerLevel when
- * doing manual MS power control.
- */
- if (trx_ms_pwr_ctrl_is_osmo(lchan->ts->trx))
- lch_par->sacch.u8MsPowerLevel = lchan->ms_power_ctrl.current;
- /* fall through */
- case GsmL1_Sapi_Pdtch:
- case GsmL1_Sapi_Pacch:
- /*
- * Be sure that every packet is received, even if it
- * fails. In this case the length might be lower or 0.
- */
- act_req->fBFILevel = -200.0f;
- break;
- default:
- break;
- }
-
- LOGP(DL1C, LOGL_INFO, "%s MPH-ACTIVATE.req (hL2=0x%08x, %s ",
- gsm_lchan_name(lchan), (uint32_t)act_req->hLayer2,
- get_value_string(lc15bts_l1sapi_names, act_req->sapi));
- LOGPC(DL1C, LOGL_INFO, "%s)\n",
- get_value_string(lc15bts_dir_names, act_req->dir));
-
- /* send the primitive for all GsmL1_Sapi_* that match the LCHAN */
- return l1if_gsm_req_compl(fl1h, msg, lchan_act_compl_cb, NULL);
-}
-
-static void sapi_clear_queue(struct llist_head *queue)
-{
- struct sapi_cmd *next, *tmp;
-
- llist_for_each_entry_safe(next, tmp, queue, entry) {
- llist_del(&next->entry);
- talloc_free(next);
- }
-}
-
-static int sapi_activate_cb(struct gsm_lchan *lchan, int status)
-{
- struct lc15l1_hdl *fl1h = trx_lc15l1_hdl(lchan->ts->trx);
-
- /* FIXME: Error handling */
- if (status != GsmL1_Status_Success) {
- LOGP(DL1C, LOGL_ERROR,
- "%s act failed mark broken due status: %d\n",
- gsm_lchan_name(lchan), status);
- lchan_set_state(lchan, LCHAN_S_BROKEN);
- sapi_clear_queue(&lchan->sapi_cmds);
- mph_info_chan_confirm(lchan, PRIM_INFO_ACTIVATE, RSL_ERR_PROCESSOR_OVERLOAD);
- return -1;
- }
-
- if (!llist_empty(&lchan->sapi_cmds))
- return 0;
-
- if (lchan->state != LCHAN_S_ACT_REQ)
- return 0;
-
- lchan_set_state(lchan, LCHAN_S_ACTIVE);
- mph_info_chan_confirm(lchan, PRIM_INFO_ACTIVATE, 0);
-
- /* set the initial ciphering parameters for both directions */
- l1if_set_ciphering(fl1h, lchan, 1);
- l1if_set_ciphering(fl1h, lchan, 0);
- if (lchan->encr.alg_id)
- lchan->ciph_state = LCHAN_CIPH_RXTX_REQ;
- else
- lchan->ciph_state = LCHAN_CIPH_NONE;
-
- return 0;
-}
-
-static void enqueue_sapi_act_cmd(struct gsm_lchan *lchan, int sapi, int dir)
-{
- struct sapi_cmd *cmd = talloc_zero(lchan->ts->trx, struct sapi_cmd);
-
- cmd->sapi = sapi;
- cmd->dir = dir;
- cmd->type = SAPI_CMD_ACTIVATE;
- cmd->callback = sapi_activate_cb;
- queue_sapi_command(lchan, cmd);
-}
-
-int lchan_activate(struct gsm_lchan *lchan)
-{
- struct lc15l1_hdl *fl1h = trx_lc15l1_hdl(lchan->ts->trx);
- const struct lchan_sapis *s4l = &sapis_for_lchan[lchan->type];
- unsigned int i;
-
- lchan_set_state(lchan, LCHAN_S_ACT_REQ);
-
- if (!llist_empty(&lchan->sapi_cmds))
- LOGP(DL1C, LOGL_ERROR,
- "%s Trying to activate lchan, but commands in queue\n",
- gsm_lchan_name(lchan));
-
- /* override the regular SAPIs if this is the first hand-over
- * related activation of the LCHAN */
- if (lchan->ho.active == HANDOVER_ENABLED)
- s4l = &sapis_for_ho;
-
- for (i = 0; i < s4l->num_sapis; i++) {
- int sapi = s4l->sapis[i].sapi;
- int dir = s4l->sapis[i].dir;
-
- if (sapi == GsmL1_Sapi_Sch) {
- /* once we activate the SCH, we should get MPH-TIME.ind */
- fl1h->alive_timer.cb = alive_timer_cb;
- fl1h->alive_timer.data = fl1h;
- fl1h->alive_prim_cnt = 0;
- osmo_timer_schedule(&fl1h->alive_timer, 5, 0);
- }
- enqueue_sapi_act_cmd(lchan, sapi, dir);
- }
-
-#warning "FIXME: Should this be in sapi_activate_cb?"
- lchan_init_lapdm(lchan);
-
- return 0;
-}
-
-const struct value_string lc15bts_l1cfgt_names[] = {
- { GsmL1_ConfigParamId_SetNbTsc, "Set NB TSC" },
- { GsmL1_ConfigParamId_SetTxPowerLevel, "Set Tx power level" },
- { GsmL1_ConfigParamId_SetLogChParams, "Set logical channel params" },
- { GsmL1_ConfigParamId_SetCipheringParams,"Configure ciphering params" },
-#if LITECELL15_API_VERSION >= LITECELL15_API(2,1,7)
- { GsmL1_ConfigParamId_Set8pskPowerReduction, "Set 8PSK Tx power reduction" },
-#endif
- { 0, NULL }
-};
-
-static void dump_lch_par(int logl, GsmL1_LogChParam_t *lch_par, GsmL1_Sapi_t sapi)
-{
- int i;
-
- switch (sapi) {
- case GsmL1_Sapi_Rach:
- LOGPC(DL1C, logl, "BSIC=0x%08x", lch_par->rach.u8Bsic);
- break;
- case GsmL1_Sapi_Agch:
- LOGPC(DL1C, logl, "BS_AG_BLKS_RES=%u ",
- lch_par->agch.u8NbrOfAgch);
- break;
- case GsmL1_Sapi_Sacch:
- LOGPC(DL1C, logl, "MS Power Level 0x%02x",
- lch_par->sacch.u8MsPowerLevel);
- break;
- case GsmL1_Sapi_TchF:
- case GsmL1_Sapi_TchH:
- LOGPC(DL1C, logl, "amrCmiPhase=0x%02x amrInitCodec=0x%02x (",
- lch_par->tch.amrCmiPhase,
- lch_par->tch.amrInitCodecMode);
- for (i = 0; i < ARRAY_SIZE(lch_par->tch.amrActiveCodecSet); i++) {
- LOGPC(DL1C, logl, "%x ",
- lch_par->tch.amrActiveCodecSet[i]);
- }
- break;
- /* FIXME: PRACH / PTCCH */
- default:
- break;
- }
- LOGPC(DL1C, logl, ")\n");
-}
-
-static int chmod_txpower_compl_cb(struct gsm_bts_trx *trx, struct msgb *l1_msg,
- void *data)
-{
- GsmL1_Prim_t *l1p = msgb_l1prim(l1_msg);
- GsmL1_MphConfigCnf_t *cc = &l1p->u.mphConfigCnf;
-
- LOGP(DL1C, LOGL_INFO, "%s MPH-CONFIG.conf (%s) ",
- gsm_trx_name(trx),
- get_value_string(lc15bts_l1cfgt_names, cc->cfgParamId));
-
- LOGPC(DL1C, LOGL_INFO, "setTxPower %f dBm\n",
- cc->cfgParams.setTxPowerLevel.fTxPowerLevel);
-
- power_trx_change_compl(trx,
- (int) (cc->cfgParams.setTxPowerLevel.fTxPowerLevel * 1000));
-
- msgb_free(l1_msg);
-
- return 0;
-}
-
-#if LITECELL15_API_VERSION >= LITECELL15_API(2,1,7)
-static int chmod_txpower_backoff_8psk_compl_cb(struct gsm_bts_trx *trx, struct msgb *l1_msg,
- void *data)
-{
- GsmL1_Prim_t *l1p = msgb_l1prim(l1_msg);
- GsmL1_MphConfigCnf_t *cc = &l1p->u.mphConfigCnf;
-
- LOGP(DL1C, LOGL_INFO, "%s MPH-CONFIG.conf (%s) ",
- gsm_trx_name(trx),
- get_value_string(lc15bts_l1cfgt_names, cc->cfgParamId));
-
- LOGPC(DL1C, LOGL_INFO, "Backoff %u dB\n",
- cc->cfgParams.set8pskPowerReduction.u8PowerReduction);
-
- msgb_free(l1_msg);
-
- return 0;
-}
-
-static int chmod_max_cell_size_compl_cb(struct gsm_bts_trx *trx, struct msgb *resp,
- void *data)
-{
- Litecell15_Prim_t *sysp = msgb_sysprim(resp);
- Litecell15_SetMaxCellSizeCnf_t *sac = &sysp->u.setMaxCellSizeCnf;
-
- LOGP(DL1C, LOGL_INFO, "%s Rx SYS prim %s -> %s\n",
- gsm_trx_name(trx),
- get_value_string(lc15bts_sysprim_names, sysp->id),
- get_value_string(lc15bts_l1status_names, sac->status));
-
- msgb_free(resp);
-
- return 0;
-}
-
-static int chmod_c0_idle_pwr_red_compl_cb(struct gsm_bts_trx *trx, struct msgb *resp,
- void *data)
-{
- Litecell15_Prim_t *sysp = msgb_sysprim(resp);
- Litecell15_SetC0IdleSlotPowerReductionCnf_t *sac = &sysp->u.setC0IdleSlotPowerReductionCnf;
-
- LOGP(DL1C, LOGL_INFO, "%s Rx SYS prim %s -> %s\n",
- gsm_trx_name(trx),
- get_value_string(lc15bts_sysprim_names, sysp->id),
- get_value_string(lc15bts_l1status_names, sac->status));
-
- msgb_free(resp);
-
- return 0;
-}
-#endif
-
-static int chmod_modif_compl_cb(struct gsm_bts_trx *trx, struct msgb *l1_msg,
- void *data)
-{
- struct gsm_lchan *lchan;
- GsmL1_Prim_t *l1p = msgb_l1prim(l1_msg);
- GsmL1_MphConfigCnf_t *cc = &l1p->u.mphConfigCnf;
-
- /* get the lchan from the information we supplied */
- lchan = l1if_hLayer_to_lchan(trx, (uint32_t)cc->hLayer3);
- if (!lchan) {
- LOGP(DL1C, LOGL_ERROR,
- "Failed to find lchan for hLayer3=0x%x\n", (uint32_t)cc->hLayer3);
- goto err;
- }
-
- LOGP(DL1C, LOGL_INFO, "%s MPH-CONFIG.conf (%s) ",
- gsm_lchan_name(lchan),
- get_value_string(lc15bts_l1cfgt_names, cc->cfgParamId));
-
- switch (cc->cfgParamId) {
- case GsmL1_ConfigParamId_SetLogChParams:
- dump_lch_par(LOGL_INFO,
- &cc->cfgParams.setLogChParams.logChParams,
- cc->cfgParams.setLogChParams.sapi);
-
- sapi_queue_dispatch(lchan, cc->status);
- break;
- case GsmL1_ConfigParamId_SetCipheringParams:
- switch (lchan->ciph_state) {
- case LCHAN_CIPH_RX_REQ:
- LOGPC(DL1C, LOGL_INFO, "RX_REQ -> RX_CONF\n");
- lchan->ciph_state = LCHAN_CIPH_RX_CONF;
- break;
- case LCHAN_CIPH_RX_CONF_TX_REQ:
- LOGPC(DL1C, LOGL_INFO, "RX_CONF_TX_REQ -> RXTX_CONF\n");
- lchan->ciph_state = LCHAN_CIPH_RXTX_CONF;
- break;
- case LCHAN_CIPH_RXTX_REQ:
- LOGPC(DL1C, LOGL_INFO, "RXTX_REQ -> RX_CONF_TX_REQ\n");
- lchan->ciph_state = LCHAN_CIPH_RX_CONF_TX_REQ;
- break;
- case LCHAN_CIPH_NONE:
- LOGPC(DL1C, LOGL_INFO, "\n");
- break;
- default:
- LOGPC(DL1C, LOGL_INFO, "unhandled state %u\n", lchan->ciph_state);
- break;
- }
- if (llist_empty(&lchan->sapi_cmds)) {
- LOGP(DL1C, LOGL_ERROR,
- "%s Got ciphering conf with empty queue\n",
- gsm_lchan_name(lchan));
- goto err;
- }
-
- sapi_queue_dispatch(lchan, cc->status);
- break;
- case GsmL1_ConfigParamId_SetNbTsc:
- default:
- LOGPC(DL1C, LOGL_INFO, "\n");
- break;
- }
-
-err:
- msgb_free(l1_msg);
-
- return 0;
-}
-
-static int mph_send_config_logchpar(struct gsm_lchan *lchan, struct sapi_cmd *cmd)
-{
- struct gsm_bts_trx *trx = lchan->ts->trx;
- struct lc15l1_hdl *fl1h = trx_lc15l1_hdl(trx);
- struct msgb *msg = l1p_msgb_alloc();
- GsmL1_MphConfigReq_t *conf_req;
- GsmL1_LogChParam_t *lch_par;
-
- /* channel mode, encryption and/or multirate have changed */
-
- /* update multi-rate config */
- conf_req = prim_init(msgb_l1prim(msg), GsmL1_PrimId_MphConfigReq, fl1h,
- l1p_handle_for_lchan(lchan));
- conf_req->cfgParamId = GsmL1_ConfigParamId_SetLogChParams;
- conf_req->cfgParams.setLogChParams.sapi = cmd->sapi;
- conf_req->cfgParams.setLogChParams.u8Tn = lchan->ts->nr;
- conf_req->cfgParams.setLogChParams.subCh = lchan_to_GsmL1_SubCh_t(lchan);
- conf_req->cfgParams.setLogChParams.dir = cmd->dir;
- conf_req->hLayer3 = (HANDLE)l1if_lchan_to_hLayer(lchan);
-
- lch_par = &conf_req->cfgParams.setLogChParams.logChParams;
- lchan2lch_par(lch_par, lchan);
-
- /* Update the MS Power Level */
- if (cmd->sapi == GsmL1_Sapi_Sacch && trx_ms_pwr_ctrl_is_osmo(trx))
- lch_par->sacch.u8MsPowerLevel = lchan->ms_power_ctrl.current;
-
- /* FIXME: update encryption */
-
- LOGP(DL1C, LOGL_INFO, "%s MPH-CONFIG.req (%s) ",
- gsm_lchan_name(lchan),
- get_value_string(lc15bts_l1sapi_names,
- conf_req->cfgParams.setLogChParams.sapi));
- LOGPC(DL1C, LOGL_INFO, "cfgParams Tn=%u, subCh=%u, dir=0x%x ",
- conf_req->cfgParams.setLogChParams.u8Tn,
- conf_req->cfgParams.setLogChParams.subCh,
- conf_req->cfgParams.setLogChParams.dir);
- dump_lch_par(LOGL_INFO,
- &conf_req->cfgParams.setLogChParams.logChParams,
- conf_req->cfgParams.setLogChParams.sapi);
-
- return l1if_gsm_req_compl(fl1h, msg, chmod_modif_compl_cb, NULL);
-}
-
-static void enqueue_sapi_logchpar_cmd(struct gsm_lchan *lchan, int dir, GsmL1_Sapi_t sapi)
-{
- struct sapi_cmd *cmd = talloc_zero(lchan->ts->trx, struct sapi_cmd);
-
- cmd->dir = dir;
- cmd->sapi = sapi;
- cmd->type = SAPI_CMD_CONFIG_LOGCH_PARAM;
- queue_sapi_command(lchan, cmd);
-}
-
-static int tx_confreq_logchpar(struct gsm_lchan *lchan, uint8_t direction)
-{
- enqueue_sapi_logchpar_cmd(lchan, direction, lchan_to_GsmL1_Sapi_t(lchan));
- return 0;
-}
-
-int l1if_set_txpower(struct lc15l1_hdl *fl1h, float tx_power)
-{
- struct msgb *msg = l1p_msgb_alloc();
- GsmL1_MphConfigReq_t *conf_req;
-
- conf_req = prim_init(msgb_l1prim(msg), GsmL1_PrimId_MphConfigReq, fl1h, 0);
- conf_req->cfgParamId = GsmL1_ConfigParamId_SetTxPowerLevel;
- conf_req->cfgParams.setTxPowerLevel.fTxPowerLevel = tx_power;
-
- return l1if_gsm_req_compl(fl1h, msg, chmod_txpower_compl_cb, NULL);
-}
-
-#if LITECELL15_API_VERSION >= LITECELL15_API(2,1,7)
-int l1if_set_txpower_backoff_8psk(struct lc15l1_hdl *fl1h, uint8_t backoff)
-{
- struct msgb *msg = l1p_msgb_alloc();
- GsmL1_MphConfigReq_t *conf_req;
-
- conf_req = prim_init(msgb_l1prim(msg), GsmL1_PrimId_MphConfigReq, fl1h, 0);
- conf_req->cfgParamId = GsmL1_ConfigParamId_Set8pskPowerReduction;
- conf_req->cfgParams.set8pskPowerReduction.u8PowerReduction = backoff;
-
- return l1if_gsm_req_compl(fl1h, msg, chmod_txpower_backoff_8psk_compl_cb, NULL);
-}
-
-int l1if_set_max_cell_size(struct lc15l1_hdl *fl1h, uint8_t cell_size)
-{
- struct msgb *msg = sysp_msgb_alloc();
- Litecell15_Prim_t *sys_prim = msgb_sysprim(msg);
- sys_prim->id = Litecell15_PrimId_SetMaxCellSizeReq;
- sys_prim->u.setMaxCellSizeReq.u8MaxCellSize = cell_size;
-
- LOGP(DL1C, LOGL_INFO, "%s Set max cell size = %d qbits\n",
- gsm_trx_name(fl1h->phy_inst->trx),
- cell_size);
-
- return l1if_req_compl(fl1h, msg, chmod_max_cell_size_compl_cb, NULL);
-
-}
-
-int l1if_set_txpower_c0_idle_pwr_red(struct lc15l1_hdl *fl1h, uint8_t red)
-{
- struct msgb *msg = sysp_msgb_alloc();
- Litecell15_Prim_t *sys_prim = msgb_sysprim(msg);
- sys_prim->id = Litecell15_PrimId_SetC0IdleSlotPowerReductionReq;
- sys_prim->u.setC0IdleSlotPowerReductionReq.u8PowerReduction = red;
-
- LOGP(DL1C, LOGL_INFO, "%s Set C0 idle slot power reduction = %d dB\n",
- gsm_trx_name(fl1h->phy_inst->trx),
- red);
-
- return l1if_req_compl(fl1h, msg, chmod_c0_idle_pwr_red_compl_cb, NULL);
-}
-#endif
-
-const enum GsmL1_CipherId_t rsl2l1_ciph[] = {
- [0] = GsmL1_CipherId_A50,
- [1] = GsmL1_CipherId_A50,
- [2] = GsmL1_CipherId_A51,
- [3] = GsmL1_CipherId_A52,
- [4] = GsmL1_CipherId_A53,
-};
-
-static int mph_send_config_ciphering(struct gsm_lchan *lchan, struct sapi_cmd *cmd)
-{
- struct lc15l1_hdl *fl1h = trx_lc15l1_hdl(lchan->ts->trx);
- struct msgb *msg = l1p_msgb_alloc();
- struct GsmL1_MphConfigReq_t *cfgr;
-
- cfgr = prim_init(msgb_l1prim(msg), GsmL1_PrimId_MphConfigReq, fl1h,
- l1p_handle_for_lchan(lchan));
-
- cfgr->cfgParamId = GsmL1_ConfigParamId_SetCipheringParams;
- cfgr->cfgParams.setCipheringParams.u8Tn = lchan->ts->nr;
- cfgr->cfgParams.setCipheringParams.subCh = lchan_to_GsmL1_SubCh_t(lchan);
- cfgr->cfgParams.setCipheringParams.dir = cmd->dir;
- cfgr->hLayer3 = (HANDLE)l1if_lchan_to_hLayer(lchan);
-
- if (lchan->encr.alg_id >= ARRAY_SIZE(rsl2l1_ciph))
- return -EINVAL;
- cfgr->cfgParams.setCipheringParams.cipherId = rsl2l1_ciph[lchan->encr.alg_id];
-
- LOGP(DL1C, LOGL_NOTICE, "%s SET_CIPHERING (ALG=%u %s)\n",
- gsm_lchan_name(lchan),
- cfgr->cfgParams.setCipheringParams.cipherId,
- get_value_string(lc15bts_dir_names,
- cfgr->cfgParams.setCipheringParams.dir));
-
- memcpy(cfgr->cfgParams.setCipheringParams.u8Kc,
- lchan->encr.key, lchan->encr.key_len);
-
- return l1if_gsm_req_compl(fl1h, msg, chmod_modif_compl_cb, NULL);
-}
-
-static void enqueue_sapi_ciphering_cmd(struct gsm_lchan *lchan, int dir)
-{
- struct sapi_cmd *cmd = talloc_zero(lchan->ts->trx, struct sapi_cmd);
-
- cmd->dir = dir;
- cmd->type = SAPI_CMD_CONFIG_CIPHERING;
- queue_sapi_command(lchan, cmd);
-}
-
-int l1if_set_ciphering(struct lc15l1_hdl *fl1h,
- struct gsm_lchan *lchan,
- int dir_downlink)
-{
- int dir;
-
- /* ignore the request when the channel is not active */
- if (lchan->state != LCHAN_S_ACTIVE)
- return -1;
-
- if (dir_downlink)
- dir = GsmL1_Dir_TxDownlink;
- else
- dir = GsmL1_Dir_RxUplink;
-
- enqueue_sapi_ciphering_cmd(lchan, dir);
-
- return 0;
-}
-
-int bts_model_adjst_ms_pwr(struct gsm_lchan *lchan)
-{
- if (lchan->state != LCHAN_S_ACTIVE)
- return -1;
-
- enqueue_sapi_logchpar_cmd(lchan, GsmL1_Dir_RxUplink, GsmL1_Sapi_Sacch);
- return 0;
-}
-
-int l1if_rsl_mode_modify(struct gsm_lchan *lchan)
-{
- if (lchan->state != LCHAN_S_ACTIVE)
- return -1;
-
- /* channel mode, encryption and/or multirate have changed */
-
- /* update multi-rate config */
- tx_confreq_logchpar(lchan, GsmL1_Dir_RxUplink);
- tx_confreq_logchpar(lchan, GsmL1_Dir_TxDownlink);
-
- /* FIXME: update encryption */
-
- return 0;
-}
-
-static int lchan_deact_compl_cb(struct gsm_bts_trx *trx, struct msgb *l1_msg,
- void *data)
-{
- enum lchan_sapi_state status;
- struct sapi_cmd *cmd;
- struct gsm_lchan *lchan;
- GsmL1_Prim_t *l1p = msgb_l1prim(l1_msg);
- GsmL1_MphDeactivateCnf_t *ic = &l1p->u.mphDeactivateCnf;
-
- lchan = l1if_hLayer_to_lchan(trx, (uint32_t)ic->hLayer3);
- if (!lchan) {
- LOGP(DL1C, LOGL_ERROR,
- "Failed to find lchan for hLayer3=0x%x\n", (uint32_t)ic->hLayer3);
- goto err;
- }
-
- LOGP(DL1C, LOGL_INFO, "%s MPH-DEACTIVATE.conf (%s ",
- gsm_lchan_name(lchan),
- get_value_string(lc15bts_l1sapi_names, ic->sapi));
- LOGPC(DL1C, LOGL_INFO, "%s)\n",
- get_value_string(lc15bts_dir_names, ic->dir));
-
- if (ic->status == GsmL1_Status_Success) {
- DEBUGP(DL1C, "Successful deactivation of L1 SAPI %s on TS %u\n",
- get_value_string(lc15bts_l1sapi_names, ic->sapi), ic->u8Tn);
- status = LCHAN_SAPI_S_NONE;
- } else {
- LOGP(DL1C, LOGL_ERROR, "Error deactivating L1 SAPI %s on TS %u: %s\n",
- get_value_string(lc15bts_l1sapi_names, ic->sapi), ic->u8Tn,
- get_value_string(lc15bts_l1status_names, ic->status));
- status = LCHAN_SAPI_S_ERROR;
- }
-
- if (ic->dir & GsmL1_Dir_TxDownlink)
- lchan->sapis_dl[ic->sapi] = status;
- if (ic->dir & GsmL1_Dir_RxUplink)
- lchan->sapis_ul[ic->sapi] = status;
-
-
- if (llist_empty(&lchan->sapi_cmds)) {
- LOGP(DL1C, LOGL_ERROR,
- "%s Got de-activation confirmation with empty queue\n",
- gsm_lchan_name(lchan));
- goto err;
- }
-
- cmd = llist_entry(lchan->sapi_cmds.next, struct sapi_cmd, entry);
- if (cmd->sapi != ic->sapi || cmd->dir != ic->dir ||
- cmd->type != SAPI_CMD_DEACTIVATE) {
- LOGP(DL1C, LOGL_ERROR,
- "%s Confirmation mismatch (%d, %d) (%d, %d)\n",
- gsm_lchan_name(lchan), cmd->sapi, cmd->dir,
- ic->sapi, ic->dir);
- goto err;
- }
-
- sapi_queue_dispatch(lchan, ic->status);
-
-err:
- msgb_free(l1_msg);
- return 0;
-}
-
-static int mph_send_deactivate_req(struct gsm_lchan *lchan, struct sapi_cmd *cmd)
-{
- struct lc15l1_hdl *fl1h = trx_lc15l1_hdl(lchan->ts->trx);
- struct msgb *msg = l1p_msgb_alloc();
- GsmL1_MphDeactivateReq_t *deact_req;
-
- deact_req = prim_init(msgb_l1prim(msg), GsmL1_PrimId_MphDeactivateReq,
- fl1h, l1p_handle_for_lchan(lchan));
- deact_req->u8Tn = lchan->ts->nr;
- deact_req->subCh = lchan_to_GsmL1_SubCh_t(lchan);
- deact_req->dir = cmd->dir;
- deact_req->sapi = cmd->sapi;
- deact_req->hLayer3 = (HANDLE)l1if_lchan_to_hLayer(lchan);
-
- LOGP(DL1C, LOGL_INFO, "%s MPH-DEACTIVATE.req (%s ",
- gsm_lchan_name(lchan),
- get_value_string(lc15bts_l1sapi_names, deact_req->sapi));
- LOGPC(DL1C, LOGL_INFO, "%s)\n",
- get_value_string(lc15bts_dir_names, deact_req->dir));
-
- /* send the primitive for all GsmL1_Sapi_* that match the LCHAN */
- return l1if_gsm_req_compl(fl1h, msg, lchan_deact_compl_cb, NULL);
-}
-
-static int sapi_deactivate_cb(struct gsm_lchan *lchan, int status)
-{
- /* FIXME: Error handling. There is no NACK... */
- if (status != GsmL1_Status_Success && lchan->state == LCHAN_S_REL_REQ) {
- LOGP(DL1C, LOGL_ERROR, "%s is now broken. Stopping the release.\n",
- gsm_lchan_name(lchan));
- lchan_set_state(lchan, LCHAN_S_BROKEN);
- sapi_clear_queue(&lchan->sapi_cmds);
- mph_info_chan_confirm(lchan, PRIM_INFO_DEACTIVATE, 0);
- return -1;
- }
-
- if (!llist_empty(&lchan->sapi_cmds))
- return 0;
-
- /* Don't send an REL ACK on SACCH deactivate */
- if (lchan->state != LCHAN_S_REL_REQ)
- return 0;
-
- lchan_set_state(lchan, LCHAN_S_NONE);
- mph_info_chan_confirm(lchan, PRIM_INFO_DEACTIVATE, 0);
-
- /* Reactivate CCCH due to SI3 update in RSL */
- if (lchan->rel_act_kind == LCHAN_REL_ACT_REACT) {
- lchan->rel_act_kind = LCHAN_REL_ACT_RSL;
- lchan_activate(lchan);
- }
- return 0;
-}
-
-static int enqueue_sapi_deact_cmd(struct gsm_lchan *lchan, int sapi, int dir)
-{
- struct sapi_cmd *cmd = talloc_zero(lchan->ts->trx, struct sapi_cmd);
-
- cmd->sapi = sapi;
- cmd->dir = dir;
- cmd->type = SAPI_CMD_DEACTIVATE;
- cmd->callback = sapi_deactivate_cb;
- return queue_sapi_command(lchan, cmd);
-}
-
-/*
- * Release the SAPI if it was allocated. E.g. the SACCH might be already
- * deactivated or during a hand-over the TCH was not allocated yet.
- */
-static int check_sapi_release(struct gsm_lchan *lchan, int sapi, int dir)
-{
- /* check if we should schedule a release */
- if (dir & GsmL1_Dir_TxDownlink) {
- if (lchan->sapis_dl[sapi] != LCHAN_SAPI_S_ASSIGNED)
- return 0;
- lchan->sapis_dl[sapi] = LCHAN_SAPI_S_REL;
- } else if (dir & GsmL1_Dir_RxUplink) {
- if (lchan->sapis_ul[sapi] != LCHAN_SAPI_S_ASSIGNED)
- return 0;
- lchan->sapis_ul[sapi] = LCHAN_SAPI_S_REL;
- }
-
- /* now schedule the command and maybe dispatch it */
- return enqueue_sapi_deact_cmd(lchan, sapi, dir);
-}
-
-static int release_sapis_for_ho(struct gsm_lchan *lchan)
-{
- int res = 0;
- int i;
-
- const struct lchan_sapis *s4l = &sapis_for_ho;
-
- for (i = s4l->num_sapis-1; i >= 0; i--)
- res |= check_sapi_release(lchan,
- s4l->sapis[i].sapi, s4l->sapis[i].dir);
- return res;
-}
-
-static int lchan_deactivate_sapis(struct gsm_lchan *lchan)
-{
- struct lc15l1_hdl *fl1h = trx_lc15l1_hdl(lchan->ts->trx);
- const struct lchan_sapis *s4l = &sapis_for_lchan[lchan->type];
- int i, res;
-
- res = 0;
-
- /* The order matters.. the Facch needs to be released first */
- for (i = s4l->num_sapis-1; i >= 0; i--) {
- /* Stop the alive timer once we deactivate the SCH */
- if (s4l->sapis[i].sapi == GsmL1_Sapi_Sch)
- osmo_timer_del(&fl1h->alive_timer);
-
- /* Release if it was allocated */
- res |= check_sapi_release(lchan, s4l->sapis[i].sapi, s4l->sapis[i].dir);
- }
-
- /* always attempt to disable the RACH burst */
- res |= release_sapis_for_ho(lchan);
-
- /* nothing was queued */
- if (res == 0) {
- LOGP(DL1C, LOGL_ERROR, "%s all SAPIs already released?\n",
- gsm_lchan_name(lchan));
- lchan_set_state(lchan, LCHAN_S_BROKEN);
- mph_info_chan_confirm(lchan, PRIM_INFO_DEACTIVATE, 0);
- }
-
- return res;
-}
-
-static void enqueue_rel_marker(struct gsm_lchan *lchan)
-{
- struct sapi_cmd *cmd;
-
- /* remember we need to release all active SAPIs */
- cmd = talloc_zero(lchan->ts->trx, struct sapi_cmd);
- cmd->type = SAPI_CMD_REL_MARKER;
- queue_sapi_command(lchan, cmd);
-}
-
-int bts_model_lchan_deactivate(struct gsm_lchan *lchan)
-{
- lchan_set_state(lchan, LCHAN_S_REL_REQ);
- enqueue_rel_marker(lchan);
- return 0;
-}
-
-static void enqueue_sacch_rel_marker(struct gsm_lchan *lchan)
-{
- struct sapi_cmd *cmd;
-
- /* remember we need to check if the SACCH is allocated */
- cmd = talloc_zero(lchan->ts->trx, struct sapi_cmd);
- cmd->type = SAPI_CMD_SACCH_REL_MARKER;
- queue_sapi_command(lchan, cmd);
-}
-
-int bts_model_lchan_deactivate_sacch(struct gsm_lchan *lchan)
-{
- enqueue_sacch_rel_marker(lchan);
- return 0;
-}
-
-/* callback from OML */
-int bts_model_check_oml(struct gsm_bts *bts, uint8_t msg_type,
- struct tlv_parsed *old_attr, struct tlv_parsed *new_attr,
- void *obj)
-{
- /* FIXME: more checks if the attributes are valid */
-
- switch (msg_type) {
- case NM_MT_SET_CHAN_ATTR:
- /* our L1 only supports one global TSC for all channels
- * one one TRX, so we need to make sure not to activate
- * channels with a different TSC!! */
- if (TLVP_PRESENT(new_attr, NM_ATT_TSC) &&
- TLVP_LEN(new_attr, NM_ATT_TSC) >= 1 &&
- *TLVP_VAL(new_attr, NM_ATT_TSC) != (bts->bsic & 7)) {
- LOGP(DOML, LOGL_ERROR, "Channel TSC %u != BSIC-TSC %u\n",
- *TLVP_VAL(new_attr, NM_ATT_TSC), bts->bsic & 7);
- return -NM_NACK_PARAM_RANGE;
- }
- break;
- }
- return 0;
-}
-
-/* callback from OML */
-int bts_model_apply_oml(struct gsm_bts *bts, struct msgb *msg,
- struct tlv_parsed *new_attr, int kind, void *obj)
-{
- if (kind == NM_OC_RADIO_CARRIER) {
- struct gsm_bts_trx *trx = obj;
- struct lc15l1_hdl *fl1h = trx_lc15l1_hdl(trx);
- /* convert max TA to max cell size in qbits */
- uint8_t cell_size = bts->max_ta << 2;
-
-#if LITECELL15_API_VERSION >= LITECELL15_API(2,1,7)
- /* We do not need to check for L1 handle
- * because the max cell size parameter can receive before MphInit */
- if (fl1h->phy_inst->u.lc15.max_cell_size != cell_size) {
- /* instruct L1 to apply max cell size */
- l1if_set_max_cell_size(fl1h, cell_size);
- /* update current max cell size */
- fl1h->phy_inst->u.lc15.max_cell_size = cell_size;
- }
-#endif
-
- /* Did we go through MphInit yet? If yes fire and forget */
- if (fl1h->hLayer1) {
- power_ramp_start(trx, get_p_target_mdBm(trx, 0), 0, NULL);
-#if LITECELL15_API_VERSION >= LITECELL15_API(2,1,7)
- if (fl1h->phy_inst->u.lc15.tx_pwr_red_8psk != trx->max_power_backoff_8psk) {
- /* update current Tx power backoff for 8-PSK */
- fl1h->phy_inst->u.lc15.tx_pwr_red_8psk = trx->max_power_backoff_8psk;
- /* instruct L1 to apply Tx power backoff for 8 PSK */
- l1if_set_txpower_backoff_8psk(fl1h, fl1h->phy_inst->u.lc15.tx_pwr_red_8psk);
- }
-
- if (fl1h->phy_inst->u.lc15.tx_c0_idle_pwr_red != trx->c0_idle_power_red) {
- /* update current C0 idle slot Tx power reduction */
- fl1h->phy_inst->u.lc15.tx_c0_idle_pwr_red = trx->c0_idle_power_red;
- /* instruct L1 to apply C0 idle slot power reduction */
- l1if_set_txpower_c0_idle_pwr_red(fl1h, fl1h->phy_inst->u.lc15.tx_c0_idle_pwr_red);
- }
-#endif
- }
- }
- /* FIXME: we actually need to send a ACK or NACK for the OML message */
- return oml_fom_ack_nack(msg, 0);
-}
-
-/* callback from OML */
-int bts_model_opstart(struct gsm_bts *bts, struct gsm_abis_mo *mo,
- void *obj)
-{
- struct gsm_bts_bb_trx *bb_transc;
- struct gsm_bts_trx *trx;
- struct gsm_bts_trx_ts *ts;
- int rc;
-
- switch (mo->obj_class) {
- case NM_OC_SITE_MANAGER:
- rc = osmo_fsm_inst_dispatch(bts->site_mgr.mo.fi, NM_EV_OPSTART_ACK, NULL);
- break;
- case NM_OC_BTS:
- rc = osmo_fsm_inst_dispatch(bts->mo.fi, NM_EV_OPSTART_ACK, NULL);
- break;
- case NM_OC_RADIO_CARRIER:
- trx = (struct gsm_bts_trx *) obj;
- rc = trx_init(trx);
- break;
- case NM_OC_BASEB_TRANSC:
- bb_transc = (struct gsm_bts_bb_trx *) obj;
- rc = osmo_fsm_inst_dispatch(bb_transc->mo.fi, NM_EV_OPSTART_ACK, NULL);
- break;
- case NM_OC_CHANNEL:
- ts = (struct gsm_bts_trx_ts*) obj;
- rc = ts_opstart(ts);
- break;
- case NM_OC_GPRS_NSE:
- case NM_OC_GPRS_CELL:
- case NM_OC_GPRS_NSVC:
- oml_mo_state_chg(mo, NM_OPSTATE_ENABLED, -1);
- rc = oml_mo_opstart_ack(mo);
- if (mo->obj_class == NM_OC_BTS) {
- oml_mo_state_chg(&bts->mo, -1, NM_AVSTATE_OK);
- oml_mo_state_chg(&bts->gprs.nse.mo, -1, NM_AVSTATE_OK);
- oml_mo_state_chg(&bts->gprs.cell.mo, -1, NM_AVSTATE_OK);
- oml_mo_state_chg(&bts->gprs.nsvc[0].mo, -1, NM_AVSTATE_OK);
- }
- break;
- default:
- rc = oml_mo_opstart_nack(mo, NM_NACK_OBJCLASS_NOTSUPP);
- }
- return rc;
-}
-
-int bts_model_chg_adm_state(struct gsm_bts *bts, struct gsm_abis_mo *mo,
- void *obj, uint8_t adm_state)
-{
- int rc = -EINVAL;
- int granted = 0;
-
- switch (mo->obj_class) {
- case NM_OC_RADIO_CARRIER:
-
- if (mo->procedure_pending) {
- LOGP(DL1C, LOGL_ERROR, "Discarding adm change command: "
- "pending procedure on RC %d\n",
- ((struct gsm_bts_trx *)obj)->nr);
- return 0;
- }
- mo->procedure_pending = 1;
- switch (adm_state) {
- case NM_STATE_LOCKED:
- rc = trx_rf_lock(obj, 1, NULL);
- break;
- case NM_STATE_UNLOCKED:
- rc = trx_rf_lock(obj, 0, NULL);
- break;
- default:
- granted = 1;
- break;
- }
-
- if (!granted && rc == 0)
- /* in progress, will send ack/nack after completion */
- return 0;
-
- mo->procedure_pending = 0;
-
- break;
- default:
- /* blindly accept all state changes */
- granted = 1;
- break;
- }
-
- if (granted) {
- mo->nm_state.administrative = adm_state;
- return oml_mo_statechg_ack(mo);
- } else
- return oml_mo_statechg_nack(mo, NM_NACK_REQ_NOT_GRANT);
-
-}
-
-int l1if_rsl_chan_act(struct gsm_lchan *lchan)
-{
- //uint8_t mode = *TLVP_VAL(tp, RSL_IE_CHAN_MODE);
- //uint8_t type = *TLVP_VAL(tp, RSL_IE_ACT_TYPE);
- lchan_activate(lchan);
- return 0;
-}
-
-/**
- * Modify the given lchan in the handover scenario. This is a lot like
- * second channel activation but with some additional activation.
- */
-int l1if_rsl_chan_mod(struct gsm_lchan *lchan)
-{
- const struct lchan_sapis *s4l = &sapis_for_lchan[lchan->type];
- unsigned int i;
-
- if (lchan->ho.active == HANDOVER_NONE)
- return -1;
-
- LOGP(DHO, LOGL_ERROR, "%s modifying channel for handover\n",
- gsm_lchan_name(lchan));
-
- /* Give up listening to RACH bursts */
- release_sapis_for_ho(lchan);
-
- /* Activate the normal SAPIs */
- for (i = 0; i < s4l->num_sapis; i++) {
- int sapi = s4l->sapis[i].sapi;
- int dir = s4l->sapis[i].dir;
- enqueue_sapi_act_cmd(lchan, sapi, dir);
- }
-
- return 0;
-}
-
-int l1if_rsl_chan_rel(struct gsm_lchan *lchan)
-{
- /* A duplicate RF Release Request, ignore it */
- if (lchan->state == LCHAN_S_REL_REQ) {
- LOGP(DL1C, LOGL_ERROR, "%s already in release request state.\n",
- gsm_lchan_name(lchan));
- return 0;
- }
-
- lchan_deactivate(lchan);
- return 0;
-}
-
-int l1if_rsl_deact_sacch(struct gsm_lchan *lchan)
-{
- /* Only de-activate the SACCH if the lchan is active */
- if (lchan->state != LCHAN_S_ACTIVE)
- return 0;
- return bts_model_lchan_deactivate_sacch(lchan);
-}
-
-int bts_model_trx_deact_rf(struct gsm_bts_trx *trx)
-{
- struct lc15l1_hdl *fl1 = trx_lc15l1_hdl(trx);
-
- return l1if_activate_rf(fl1, 0);
-}
-
-int bts_model_change_power(struct gsm_bts_trx *trx, int p_trxout_mdBm)
-{
- return l1if_set_txpower(trx_lc15l1_hdl(trx), ((float) p_trxout_mdBm)/1000.0);
-}
-
-static int ts_disconnect_cb(struct gsm_bts_trx *trx, struct msgb *l1_msg,
- void *data)
-{
- GsmL1_Prim_t *l1p = msgb_l1prim(l1_msg);
- GsmL1_MphDisconnectCnf_t *cnf = &l1p->u.mphDisconnectCnf;
- struct gsm_bts_trx_ts *ts = &trx->ts[cnf->u8Tn];
- OSMO_ASSERT(cnf->u8Tn < TRX_NR_TS);
-
- LOGP(DL1C, LOGL_DEBUG, "%s Rx mphDisconnectCnf\n",
- gsm_lchan_name(ts->lchan));
-
- cb_ts_disconnected(ts);
-
- msgb_free(l1_msg);
-
- return 0;
-}
-
-int bts_model_ts_disconnect(struct gsm_bts_trx_ts *ts)
-{
- struct msgb *msg = l1p_msgb_alloc();
- struct lc15l1_hdl *fl1h = trx_lc15l1_hdl(ts->trx);
- GsmL1_MphDisconnectReq_t *cr;
-
- DEBUGP(DRSL, "%s TS disconnect\n", gsm_lchan_name(ts->lchan));
- cr = prim_init(msgb_l1prim(msg), GsmL1_PrimId_MphDisconnectReq, fl1h,
- l1p_handle_for_ts(ts));
- cr->u8Tn = ts->nr;
-
- return l1if_gsm_req_compl(fl1h, msg, ts_disconnect_cb, NULL);
-}
-
-static int ts_connect_cb(struct gsm_bts_trx *trx, struct msgb *l1_msg,
- void *data)
-{
- GsmL1_Prim_t *l1p = msgb_l1prim(l1_msg);
- GsmL1_MphConnectCnf_t *cnf = &l1p->u.mphConnectCnf;
- struct gsm_bts_trx_ts *ts = &trx->ts[cnf->u8Tn];
- OSMO_ASSERT(cnf->u8Tn < TRX_NR_TS);
-
- DEBUGP(DL1C, "%s %s Rx mphConnectCnf flags=%s%s%s\n",
- gsm_lchan_name(ts->lchan),
- gsm_pchan_name(ts->pchan),
- ts->flags & TS_F_PDCH_ACTIVE ? "ACTIVE " : "",
- ts->flags & TS_F_PDCH_ACT_PENDING ? "ACT_PENDING " : "",
- ts->flags & TS_F_PDCH_DEACT_PENDING ? "DEACT_PENDING " : "");
-
- cb_ts_connected(ts, 0);
-
- msgb_free(l1_msg);
-
- return 0;
-}
-
-void bts_model_ts_connect(struct gsm_bts_trx_ts *ts,
- enum gsm_phys_chan_config as_pchan)
-{
- int rc;
-
- rc = ts_connect_as(ts, as_pchan, ts_connect_cb, NULL);
- if (rc)
- cb_ts_connected(ts, rc);
-}
diff --git a/src/osmo-bts-litecell15/tch.c b/src/osmo-bts-litecell15/tch.c
deleted file mode 100644
index 526b2ddf..00000000
--- a/src/osmo-bts-litecell15/tch.c
+++ /dev/null
@@ -1,533 +0,0 @@
-/* Traffic channel support for NuRAN Wireless Litecell 1.5 BTS L1 */
-
-/* Copyright (C) 2015 by Yves Godin <support@nuranwireless.com>
- *
- * Based on sysmoBTS:
- * (C) 2011-2012 by Harald Welte <laforge@gnumonks.org>
- *
- * 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 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/licenses/>.
- *
- */
-
-#include <stdint.h>
-#include <unistd.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <stdbool.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-
-#include <osmocom/core/talloc.h>
-#include <osmocom/core/utils.h>
-#include <osmocom/core/select.h>
-#include <osmocom/core/timer.h>
-#include <osmocom/core/bits.h>
-#include <osmocom/gsm/gsm_utils.h>
-
-#include <osmo-bts/logging.h>
-#include <osmo-bts/bts.h>
-#include <osmo-bts/gsm_data.h>
-#include <osmo-bts/msg_utils.h>
-#include <osmo-bts/measurement.h>
-#include <osmo-bts/amr.h>
-#include <osmo-bts/l1sap.h>
-#include <osmo-bts/dtx_dl_amr_fsm.h>
-
-#include <nrw/litecell15/litecell15.h>
-#include <nrw/litecell15/gsml1prim.h>
-#include <nrw/litecell15/gsml1const.h>
-#include <nrw/litecell15/gsml1types.h>
-
-#include "lc15bts.h"
-#include "l1_if.h"
-
-static struct msgb *l1_to_rtppayload_fr(uint8_t *l1_payload, uint8_t payload_len,
- struct gsm_lchan *lchan)
-{
- struct msgb *msg;
- uint8_t *cur;
-
- msg = msgb_alloc_headroom(1024, 128, "L1P-to-RTP");
- if (!msg)
- return NULL;
-
- /* new L1 can deliver bits like we need them */
- cur = msgb_put(msg, GSM_FR_BYTES);
- memcpy(cur, l1_payload, GSM_FR_BYTES);
-
- lchan_set_marker(osmo_fr_check_sid(l1_payload, payload_len), lchan);
-
- return msg;
-}
-
-/*! \brief convert GSM-FR from RTP payload to L1 format
- * \param[out] l1_payload payload part of L1 buffer
- * \param[in] rtp_payload pointer to RTP payload data
- * \param[in] payload_len length of \a rtp_payload
- * \returns number of \a l1_payload bytes filled
- */
-static int rtppayload_to_l1_fr(uint8_t *l1_payload, const uint8_t *rtp_payload,
- unsigned int payload_len)
-{
- /* new L1 can deliver bits like we need them */
- memcpy(l1_payload, rtp_payload, GSM_FR_BYTES);
- return GSM_FR_BYTES;
-}
-
-static struct msgb *l1_to_rtppayload_efr(uint8_t *l1_payload,
- uint8_t payload_len,
- struct gsm_lchan *lchan)
-{
- struct msgb *msg;
- uint8_t *cur;
-
- msg = msgb_alloc_headroom(1024, 128, "L1P-to-RTP");
- if (!msg)
- return NULL;
-
- /* new L1 can deliver bits like we need them */
- cur = msgb_put(msg, GSM_EFR_BYTES);
- memcpy(cur, l1_payload, GSM_EFR_BYTES);
- enum osmo_amr_type ft;
- enum osmo_amr_quality bfi;
- uint8_t cmr;
- int8_t sti, cmi;
- osmo_amr_rtp_dec(l1_payload, payload_len, &cmr, &cmi, &ft, &bfi, &sti);
- lchan_set_marker(ft == AMR_GSM_EFR_SID, lchan);
-
- return msg;
-}
-
-static int rtppayload_to_l1_efr(uint8_t *l1_payload, const uint8_t *rtp_payload,
- unsigned int payload_len)
-{
- memcpy(l1_payload, rtp_payload, payload_len);
-
- return payload_len;
-}
-
-static struct msgb *l1_to_rtppayload_hr(uint8_t *l1_payload, uint8_t payload_len,
- struct gsm_lchan *lchan)
-{
- struct msgb *msg;
- uint8_t *cur;
-
- msg = msgb_alloc_headroom(1024, 128, "L1P-to-RTP");
- if (!msg)
- return NULL;
-
- if (payload_len != GSM_HR_BYTES) {
- LOGP(DL1P, LOGL_ERROR, "L1 HR frame length %u != expected %u\n",
- payload_len, GSM_HR_BYTES);
- return NULL;
- }
-
- cur = msgb_put(msg, GSM_HR_BYTES);
- memcpy(cur, l1_payload, GSM_HR_BYTES);
-
- lchan_set_marker(osmo_hr_check_sid(l1_payload, payload_len), lchan);
-
- return msg;
-}
-
-/*! \brief convert GSM-FR from RTP payload to L1 format
- * \param[out] l1_payload payload part of L1 buffer
- * \param[in] rtp_payload pointer to RTP payload data
- * \param[in] payload_len length of \a rtp_payload
- * \returns number of \a l1_payload bytes filled
- */
-static int rtppayload_to_l1_hr(uint8_t *l1_payload, const uint8_t *rtp_payload,
- unsigned int payload_len)
-{
-
- if (payload_len != GSM_HR_BYTES) {
- LOGP(DL1P, LOGL_ERROR, "RTP HR frame length %u != expected %u\n",
- payload_len, GSM_HR_BYTES);
- return 0;
- }
-
- memcpy(l1_payload, rtp_payload, GSM_HR_BYTES);
-
- return GSM_HR_BYTES;
-}
-
-static struct msgb *l1_to_rtppayload_amr(uint8_t *l1_payload, uint8_t payload_len,
- struct gsm_lchan *lchan)
-{
- struct msgb *msg;
- uint8_t amr_if2_len = payload_len - 2;
- uint8_t *cur;
-
- msg = msgb_alloc_headroom(1024, 128, "L1P-to-RTP");
- if (!msg)
- return NULL;
-
- cur = msgb_put(msg, amr_if2_len);
- memcpy(cur, l1_payload+2, amr_if2_len);
-
- /*
- * Audiocode's MGW doesn't like receiving CMRs that are not
- * the same as the previous one. This means we need to patch
- * the content here.
- */
- if ((cur[0] & 0xF0) == 0xF0)
- cur[0]= lchan->tch.last_cmr << 4;
- else
- lchan->tch.last_cmr = cur[0] >> 4;
-
- return msg;
-}
-
-/*! \brief convert AMR from RTP payload to L1 format
- * \param[out] l1_payload payload part of L1 buffer
- * \param[in] rtp_payload pointer to RTP payload data
- * \param[in] payload_len length of \a rtp_payload
- * \returns number of \a l1_payload bytes filled
- */
-static int rtppayload_to_l1_amr(uint8_t *l1_payload, const uint8_t *rtp_payload,
- uint8_t payload_len, uint8_t ft)
-{
- memcpy(l1_payload, rtp_payload, payload_len);
- return payload_len;
-}
-
-#define RTP_MSGB_ALLOC_SIZE 512
-
-/*! \brief function for incoming RTP via TCH.req
- * \param[in] rtp_pl buffer containing RTP payload
- * \param[in] rtp_pl_len length of \a rtp_pl
- * \param[in] use_cache Use cached payload instead of parsing RTP
- * \param[in] marker RTP header Marker bit (indicates speech onset)
- * \returns 0 if encoding result can be sent further to L1 without extra actions
- * positive value if data is ready AND extra actions are required
- * negative value otherwise (no data for L1 encoded)
- *
- * This function prepares a msgb with a L1 PH-DATA.req primitive and
- * queues it into lchan->dl_tch_queue.
- *
- * Note that the actual L1 primitive header is not fully initialized
- * yet, as things like the frame number, etc. are unknown at the time we
- * pre-fill the primtive.
- */
-int l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len,
- const uint8_t *rtp_pl, unsigned int rtp_pl_len, uint32_t fn,
- bool use_cache, bool marker)
-{
- uint8_t *payload_type;
- uint8_t *l1_payload, ft;
- int rc = 0;
- bool is_sid = false;
-
- DEBUGP(DRTP, "%s RTP IN: %s\n", gsm_lchan_name(lchan),
- osmo_hexdump(rtp_pl, rtp_pl_len));
-
- payload_type = &data[0];
- l1_payload = &data[1];
-
- switch (lchan->tch_mode) {
- case GSM48_CMODE_SPEECH_V1:
- if (lchan->type == GSM_LCHAN_TCH_F) {
- *payload_type = GsmL1_TchPlType_Fr;
- rc = rtppayload_to_l1_fr(l1_payload,
- rtp_pl, rtp_pl_len);
- if (rc && lchan->ts->trx->bts->dtxd)
- is_sid = osmo_fr_check_sid(rtp_pl, rtp_pl_len);
- } else{
- *payload_type = GsmL1_TchPlType_Hr;
- rc = rtppayload_to_l1_hr(l1_payload,
- rtp_pl, rtp_pl_len);
- if (rc && lchan->ts->trx->bts->dtxd)
- is_sid = osmo_hr_check_sid(rtp_pl, rtp_pl_len);
- }
- if (is_sid)
- dtx_cache_payload(lchan, rtp_pl, rtp_pl_len, fn, -1);
- break;
- case GSM48_CMODE_SPEECH_EFR:
- *payload_type = GsmL1_TchPlType_Efr;
- rc = rtppayload_to_l1_efr(l1_payload, rtp_pl,
- rtp_pl_len);
- /* FIXME: detect and save EFR SID */
- break;
- case GSM48_CMODE_SPEECH_AMR:
- if (use_cache) {
- *payload_type = GsmL1_TchPlType_Amr;
- rtppayload_to_l1_amr(l1_payload, lchan->tch.dtx.cache,
- lchan->tch.dtx.len, ft);
- *len = lchan->tch.dtx.len + 1;
- return 0;
- }
-
- rc = dtx_dl_amr_fsm_step(lchan, rtp_pl, rtp_pl_len, fn,
- l1_payload, marker, len, &ft);
- if (rc < 0)
- return rc;
- if (!dtx_dl_amr_enabled(lchan)) {
- *payload_type = GsmL1_TchPlType_Amr;
- rtppayload_to_l1_amr(l1_payload + 2, rtp_pl, rtp_pl_len,
- ft);
- return 0;
- }
-
- /* DTX DL-specific logic below: */
- switch (lchan->tch.dtx.dl_amr_fsm->state) {
- case ST_ONSET_V:
- *payload_type = GsmL1_TchPlType_Amr_Onset;
- dtx_cache_payload(lchan, rtp_pl, rtp_pl_len, fn, 0);
- *len = 3;
- return 1;
- case ST_VOICE:
- *payload_type = GsmL1_TchPlType_Amr;
- rtppayload_to_l1_amr(l1_payload + 2, rtp_pl, rtp_pl_len,
- ft);
- return 0;
- case ST_SID_F1:
- if (lchan->type == GSM_LCHAN_TCH_H) { /* AMR HR */
- *payload_type = GsmL1_TchPlType_Amr_SidFirstP1;
- rtppayload_to_l1_amr(l1_payload + 2, rtp_pl,
- rtp_pl_len, ft);
- return 0;
- }
- /* AMR FR */
- *payload_type = GsmL1_TchPlType_Amr;
- rtppayload_to_l1_amr(l1_payload + 2, rtp_pl, rtp_pl_len,
- ft);
- return 0;
- case ST_SID_F2:
- *payload_type = GsmL1_TchPlType_Amr;
- rtppayload_to_l1_amr(l1_payload + 2, rtp_pl, rtp_pl_len,
- ft);
- return 0;
- case ST_F1_INH_V:
- *payload_type = GsmL1_TchPlType_Amr_SidFirstInH;
- *len = 3;
- dtx_cache_payload(lchan, rtp_pl, rtp_pl_len, fn, 0);
- return 1;
- case ST_U_INH_V:
- *payload_type = GsmL1_TchPlType_Amr_SidUpdateInH;
- *len = 3;
- dtx_cache_payload(lchan, rtp_pl, rtp_pl_len, fn, 0);
- return 1;
- case ST_SID_U:
- case ST_U_NOINH:
- return -EAGAIN;
- case ST_FACCH:
- return -EBADMSG;
- default:
- LOGP(DRTP, LOGL_ERROR, "Unhandled DTX DL AMR FSM state "
- "%d\n", lchan->tch.dtx.dl_amr_fsm->state);
- return -EINVAL;
- }
- break;
- default:
- /* we don't support CSD modes */
- rc = -1;
- break;
- }
-
- if (rc < 0) {
- LOGP(DRTP, LOGL_ERROR, "%s unable to parse RTP payload\n",
- gsm_lchan_name(lchan));
- return -EBADMSG;
- }
-
- *len = rc + 1;
-
- DEBUGP(DRTP, "%s RTP->L1: %s\n", gsm_lchan_name(lchan),
- osmo_hexdump(data, *len));
- return 0;
-}
-
-static int is_recv_only(uint8_t speech_mode)
-{
- return (speech_mode & 0xF0) == (1 << 4);
-}
-
-/*! \brief receive a traffic L1 primitive for a given lchan */
-int l1if_tch_rx(struct gsm_bts_trx *trx, uint8_t chan_nr, struct msgb *l1p_msg)
-{
- GsmL1_Prim_t *l1p = msgb_l1prim(l1p_msg);
- GsmL1_PhDataInd_t *data_ind = &l1p->u.phDataInd;
- uint8_t *payload, payload_type, payload_len, sid_first[9] = { 0 };
- struct msgb *rmsg = NULL;
- struct gsm_lchan *lchan = &trx->ts[L1SAP_CHAN2TS(chan_nr)].lchan[l1sap_chan2ss(chan_nr)];
-
- if (is_recv_only(lchan->abis_ip.speech_mode))
- return -EAGAIN;
-
- if (data_ind->msgUnitParam.u8Size < 1) {
- LOGPFN(DL1P, LOGL_DEBUG, data_ind->u32Fn, "chan_nr %d Rx Payload size 0\n", chan_nr);
- /* Push empty payload to upper layers */
- rmsg = msgb_alloc_headroom(256, 128, "L1P-to-RTP");
- return add_l1sap_header(trx, rmsg, lchan, chan_nr, data_ind->u32Fn,
- data_ind->measParam.fBer * 10000,
- data_ind->measParam.fLinkQuality * 10, 0, 0, 0);
- }
-
- payload_type = data_ind->msgUnitParam.u8Buffer[0];
- payload = data_ind->msgUnitParam.u8Buffer + 1;
- payload_len = data_ind->msgUnitParam.u8Size - 1;
-
- switch (payload_type) {
- case GsmL1_TchPlType_Fr:
- case GsmL1_TchPlType_Efr:
- if (lchan->type != GSM_LCHAN_TCH_F)
- goto err_payload_match;
- break;
- case GsmL1_TchPlType_Hr:
- if (lchan->type != GSM_LCHAN_TCH_H)
- goto err_payload_match;
- break;
- case GsmL1_TchPlType_Amr:
- if (lchan->type != GSM_LCHAN_TCH_H &&
- lchan->type != GSM_LCHAN_TCH_F)
- goto err_payload_match;
- break;
- case GsmL1_TchPlType_Amr_Onset:
- if (lchan->type != GSM_LCHAN_TCH_H &&
- lchan->type != GSM_LCHAN_TCH_F)
- goto err_payload_match;
- /* according to 3GPP TS 26.093 ONSET frames precede the first
- speech frame of a speech burst - set the marker for next RTP
- frame */
- lchan->rtp_tx_marker = true;
- break;
- case GsmL1_TchPlType_Amr_SidFirstP1:
- if (lchan->type != GSM_LCHAN_TCH_H)
- goto err_payload_match;
- LOGPFN(DL1P, LOGL_DEBUG, data_ind->u32Fn, "DTX: received SID_FIRST_P1 from L1 "
- "(%d bytes)\n", payload_len);
- break;
- case GsmL1_TchPlType_Amr_SidFirstP2:
- if (lchan->type != GSM_LCHAN_TCH_H)
- goto err_payload_match;
- LOGPFN(DL1P, LOGL_DEBUG, data_ind->u32Fn, "DTX: received SID_FIRST_P2 from L1 "
- "(%d bytes)\n", payload_len);
- break;
- case GsmL1_TchPlType_Amr_SidFirstInH:
- if (lchan->type != GSM_LCHAN_TCH_H)
- goto err_payload_match;
- lchan->rtp_tx_marker = true;
- LOGPFN(DL1P, LOGL_DEBUG, data_ind->u32Fn, "DTX: received SID_FIRST_INH from L1 "
- "(%d bytes)\n", payload_len);
- break;
- case GsmL1_TchPlType_Amr_SidUpdateInH:
- if (lchan->type != GSM_LCHAN_TCH_H)
- goto err_payload_match;
- lchan->rtp_tx_marker = true;
- LOGPFN(DL1P, LOGL_DEBUG, data_ind->u32Fn, "DTX: received SID_UPDATE_INH from L1 "
- "(%d bytes)\n", payload_len);
- break;
- default:
- LOGPFN(DL1P, LOGL_NOTICE, data_ind->u32Fn, "%s Rx Payload Type %s is unsupported\n",
- gsm_lchan_name(lchan),
- get_value_string(lc15bts_tch_pl_names, payload_type));
- break;
- }
-
-
- switch (payload_type) {
- case GsmL1_TchPlType_Fr:
- rmsg = l1_to_rtppayload_fr(payload, payload_len, lchan);
- break;
- case GsmL1_TchPlType_Hr:
- rmsg = l1_to_rtppayload_hr(payload, payload_len, lchan);
- break;
- case GsmL1_TchPlType_Efr:
- rmsg = l1_to_rtppayload_efr(payload, payload_len, lchan);
- break;
- case GsmL1_TchPlType_Amr:
- rmsg = l1_to_rtppayload_amr(payload, payload_len, lchan);
- break;
- case GsmL1_TchPlType_Amr_SidFirstP1:
- memcpy(sid_first, payload, payload_len);
- int len = osmo_amr_rtp_enc(sid_first, 0, AMR_SID, AMR_GOOD);
- if (len < 0)
- return 0;
- rmsg = l1_to_rtppayload_amr(sid_first, len, lchan);
- break;
- }
-
- if (rmsg)
- return add_l1sap_header(trx, rmsg, lchan, chan_nr, data_ind->u32Fn,
- data_ind->measParam.fBer * 10000,
- data_ind->measParam.fLinkQuality * 10, 0, 0, 0);
-
- return 0;
-
-err_payload_match:
- LOGPFN(DL1P, LOGL_ERROR, data_ind->u32Fn, "%s Rx Payload Type %s incompatible with lchan\n",
- gsm_lchan_name(lchan), get_value_string(lc15bts_tch_pl_names, payload_type));
- return -EINVAL;
-}
-
-struct msgb *gen_empty_tch_msg(struct gsm_lchan *lchan, uint32_t fn)
-{
- struct msgb *msg;
- GsmL1_Prim_t *l1p;
- GsmL1_PhDataReq_t *data_req;
- GsmL1_MsgUnitParam_t *msu_param;
- uint8_t *payload_type;
- uint8_t *l1_payload;
- int rc;
-
- msg = l1p_msgb_alloc();
- if (!msg)
- return NULL;
-
- l1p = msgb_l1prim(msg);
- data_req = &l1p->u.phDataReq;
- msu_param = &data_req->msgUnitParam;
- payload_type = &msu_param->u8Buffer[0];
- l1_payload = &msu_param->u8Buffer[1];
-
- switch (lchan->tch_mode) {
- case GSM48_CMODE_SPEECH_AMR:
- if (lchan->type == GSM_LCHAN_TCH_H &&
- dtx_dl_amr_enabled(lchan)) {
- /* we have to explicitly handle sending SID FIRST P2 for
- AMR HR in here */
- *payload_type = GsmL1_TchPlType_Amr_SidFirstP2;
- rc = dtx_dl_amr_fsm_step(lchan, NULL, 0, fn, l1_payload,
- false, &(msu_param->u8Size),
- NULL);
- if (rc == 0)
- return msg;
- }
- *payload_type = GsmL1_TchPlType_Amr;
- break;
- case GSM48_CMODE_SPEECH_V1:
- if (lchan->type == GSM_LCHAN_TCH_F)
- *payload_type = GsmL1_TchPlType_Fr;
- else
- *payload_type = GsmL1_TchPlType_Hr;
- break;
- case GSM48_CMODE_SPEECH_EFR:
- *payload_type = GsmL1_TchPlType_Efr;
- break;
- default:
- msgb_free(msg);
- return NULL;
- }
-
- rc = repeat_last_sid(lchan, l1_payload, fn);
- if (!rc) {
- msgb_free(msg);
- return NULL;
- }
- msu_param->u8Size = rc;
-
- return msg;
-}
diff --git a/src/osmo-bts-litecell15/utils.c b/src/osmo-bts-litecell15/utils.c
deleted file mode 100644
index 8d980ba8..00000000
--- a/src/osmo-bts-litecell15/utils.c
+++ /dev/null
@@ -1,118 +0,0 @@
-/* Helper utilities that are used in OMLs */
-
-/* Copyright (C) 2015 by Yves Godin <support@nuranwireless.com>
- *
- * Based on sysmoBTS:
- * (C) 2011-2013 by Harald Welte <laforge@gnumonks.org>
- * (C) 2013 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 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 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/licenses/>.
- *
- */
-
-#include "utils.h"
-
-#include <osmo-bts/bts.h>
-#include <osmo-bts/gsm_data.h>
-#include <osmo-bts/logging.h>
-
-#include "lc15bts.h"
-#include "l1_if.h"
-
-int band_lc152osmo(GsmL1_FreqBand_t band)
-{
- switch (band) {
- case GsmL1_FreqBand_850:
- return GSM_BAND_850;
- case GsmL1_FreqBand_900:
- return GSM_BAND_900;
- case GsmL1_FreqBand_1800:
- return GSM_BAND_1800;
- case GsmL1_FreqBand_1900:
- return GSM_BAND_1900;
- default:
- return -1;
- }
-}
-
-static int band_osmo2lc15(struct gsm_bts_trx *trx, enum gsm_band osmo_band)
-{
- struct lc15l1_hdl *fl1h = trx_lc15l1_hdl(trx);
-
- /* check if the TRX hardware actually supports the given band */
- if (!(fl1h->hw_info.band_support & osmo_band))
- return -1;
-
- /* if yes, convert from osmcoom style band definition to L1 band */
- switch (osmo_band) {
- case GSM_BAND_850:
- return GsmL1_FreqBand_850;
- case GSM_BAND_900:
- return GsmL1_FreqBand_900;
- case GSM_BAND_1800:
- return GsmL1_FreqBand_1800;
- case GSM_BAND_1900:
- return GsmL1_FreqBand_1900;
- default:
- return -1;
- }
-}
-
-/**
- * Select the band that matches the ARFCN. In general the ARFCNs
- * for GSM1800 and GSM1900 overlap and one needs to specify the
- * rightband. When moving between GSM900/GSM1800 and GSM850/1900
- * modifying the BTS configuration is a bit annoying. The auto-band
- * configuration allows to ease with this transition.
- */
-int lc15bts_select_lc15_band(struct gsm_bts_trx *trx, uint16_t arfcn)
-{
- enum gsm_band band;
- struct gsm_bts *bts = trx->bts;
- int rc;
-
- if (!bts->auto_band)
- return band_osmo2lc15(trx, bts->band);
-
- /*
- * We need to check what will happen now.
- */
- rc = gsm_arfcn2band_rc(arfcn, &band);
- if (rc) /* wrong ARFCN, give up */
- return -1;
-
- /* if we are already on the right band return */
- if (band == bts->band)
- return band_osmo2lc15(trx, bts->band);
-
- /* Check if it is GSM1800/GSM1900 */
- if (band == GSM_BAND_1800 && bts->band == GSM_BAND_1900)
- return band_osmo2lc15(trx, bts->band);
-
- /*
- * Now to the actual autobauding. We just want DCS/DCS and
- * PCS/PCS for PCS we check for 850/1800 though
- */
- if ((band == GSM_BAND_900 && bts->band == GSM_BAND_1800)
- || (band == GSM_BAND_1800 && bts->band == GSM_BAND_900)
- || (band == GSM_BAND_850 && bts->band == GSM_BAND_1900))
- return band_osmo2lc15(trx, band);
- if (band == GSM_BAND_1800 && bts->band == GSM_BAND_850)
- return band_osmo2lc15(trx, GSM_BAND_1900);
-
- /* give up */
- return -1;
-}
diff --git a/src/osmo-bts-litecell15/utils.h b/src/osmo-bts-litecell15/utils.h
deleted file mode 100644
index a2a22348..00000000
--- a/src/osmo-bts-litecell15/utils.h
+++ /dev/null
@@ -1,13 +0,0 @@
-#ifndef _UTILS_H
-#define _UTILS_H
-
-#include <stdint.h>
-#include "lc15bts.h"
-
-struct gsm_bts_trx;
-
-int band_lc152osmo(GsmL1_FreqBand_t band);
-
-int lc15bts_select_lc15_band(struct gsm_bts_trx *trx, uint16_t arfcn);
-
-#endif