From 2d2fca434209f96ae2c3b9e0221c6a063d23dfd9 Mon Sep 17 00:00:00 2001 From: Max Date: Tue, 18 Jul 2017 18:34:29 +0200 Subject: lc15: port lc15bts-mgr changes That's mostly changes related to lc15bts-mgr from https://gitlab.com/nrw_noa/osmo-bts branch nrw/litecell15 based on eb5b7f80510b603579f7af6d7d5ead296c2fa260 commit. I wanted to incorporate vty and hardcoded paths changes so we can use it from this point without major backward-incompatible changes as a base for future ports. Change-Id: Iabbaedc84aaaa594150a4e5445c16dd1f6f89858 Related: SYS#3679 --- src/osmo-bts-litecell15/Makefile.am | 12 +- src/osmo-bts-litecell15/hw_misc.c | 2 + src/osmo-bts-litecell15/misc/lc15bts_bts.c | 131 ++++ src/osmo-bts-litecell15/misc/lc15bts_bts.h | 21 + src/osmo-bts-litecell15/misc/lc15bts_clock.c | 23 - src/osmo-bts-litecell15/misc/lc15bts_led.c | 333 ++++++++++ src/osmo-bts-litecell15/misc/lc15bts_led.h | 22 + src/osmo-bts-litecell15/misc/lc15bts_mgr.c | 142 +++-- src/osmo-bts-litecell15/misc/lc15bts_mgr.h | 375 ++++++++++- src/osmo-bts-litecell15/misc/lc15bts_mgr_temp.c | 154 ++--- src/osmo-bts-litecell15/misc/lc15bts_mgr_vty.c | 799 +++++++++++++++++++----- src/osmo-bts-litecell15/misc/lc15bts_misc.c | 170 ++++- src/osmo-bts-litecell15/misc/lc15bts_misc.h | 2 + src/osmo-bts-litecell15/misc/lc15bts_par.c | 80 ++- src/osmo-bts-litecell15/misc/lc15bts_par.h | 11 +- src/osmo-bts-litecell15/misc/lc15bts_power.c | 45 +- src/osmo-bts-litecell15/misc/lc15bts_power.h | 11 +- src/osmo-bts-litecell15/misc/lc15bts_temp.c | 25 +- src/osmo-bts-litecell15/misc/lc15bts_temp.h | 5 +- 19 files changed, 1988 insertions(+), 375 deletions(-) create mode 100644 src/osmo-bts-litecell15/misc/lc15bts_bts.c create mode 100644 src/osmo-bts-litecell15/misc/lc15bts_bts.h create mode 100644 src/osmo-bts-litecell15/misc/lc15bts_led.c create mode 100644 src/osmo-bts-litecell15/misc/lc15bts_led.h (limited to 'src/osmo-bts-litecell15') diff --git a/src/osmo-bts-litecell15/Makefile.am b/src/osmo-bts-litecell15/Makefile.am index 3026e969..90e6c463 100644 --- a/src/osmo-bts-litecell15/Makefile.am +++ b/src/osmo-bts-litecell15/Makefile.am @@ -4,9 +4,11 @@ AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -I$(OPENBSC_INCDIR) -I$(LI AM_CFLAGS = -Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOCODEC_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBOSMOVTY_CFLAGS) $(LIBOSMOTRAU_CFLAGS) $(LIBOSMOABIS_CFLAGS) $(LIBOSMOCTRL_CFLAGS) $(LIBOSMOABIS_CFLAGS) $(LIBGPS_CFLAGS) $(ORTP_CFLAGS) COMMON_LDADD = $(LIBOSMOCORE_LIBS) $(LIBOSMOCODEC_LIBS) $(LIBOSMOGSM_LIBS) $(LIBOSMOVTY_LIBS) $(LIBOSMOTRAU_LIBS) $(LIBOSMOABIS_LIBS) $(LIBOSMOCTRL_LIBS) $(ORTP_LIBS) -EXTRA_DIST = misc/lc15bts_mgr.h misc/lc15bts_misc.h misc/lc15bts_par.h \ +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_bid.h misc/lc15bts_nl.h misc/lc15bts_bts.h \ hw_misc.h l1_if.h l1_transp.h lc15bts.h oml_router.h utils.h bin_PROGRAMS = osmo-bts-lc15 lc15bts-mgr lc15bts-util @@ -25,9 +27,11 @@ lc15bts_mgr_SOURCES = \ misc/lc15bts_mgr_vty.c \ misc/lc15bts_mgr_nl.c \ misc/lc15bts_mgr_temp.c \ - misc/lc15bts_mgr_calib.c + misc/lc15bts_mgr_calib.c \ + misc/lc15bts_led.c \ + misc/lc15bts_bts.c -lc15bts_mgr_LDADD = $(top_builddir)/src/common/libbts.a $(LIBGPS_LIBS) $(LIBOSMOCORE_LIBS) $(LIBOSMOVTY_LIBS) $(LIBOSMOABIS_LIBS) $(LIBOSMOGSM_LIBS) $(LIBOSMOCTRL_LIBS) +lc15bts_mgr_LDADD = $(top_builddir)/src/common/libbts.a $(LIBGPS_LIBS) $(LIBOSMOCORE_LIBS) $(LIBOSMOVTY_LIBS) $(LIBOSMOABIS_LIBS) $(LIBOSMOGSM_LIBS) $(LIBOSMOCTRL_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/hw_misc.c b/src/osmo-bts-litecell15/hw_misc.c index 49232b2d..9f070bba 100644 --- a/src/osmo-bts-litecell15/hw_misc.c +++ b/src/osmo-bts-litecell15/hw_misc.c @@ -69,6 +69,7 @@ int lc15bts_led_set(enum lc15bts_led_color c) rc = write(fd, cmd[0] ? "1" : "0", 2); if (rc != 2) { + close(fd); return -1; } close(fd); @@ -79,6 +80,7 @@ int lc15bts_led_set(enum lc15bts_led_color c) rc = write(fd, cmd[1] ? "1" : "0", 2); if (rc != 2) { + close(fd); return -1; } close(fd); diff --git a/src/osmo-bts-litecell15/misc/lc15bts_bts.c b/src/osmo-bts-litecell15/misc/lc15bts_bts.c new file mode 100644 index 00000000..0343e930 --- /dev/null +++ b/src/osmo-bts-litecell15/misc/lc15bts_bts.c @@ -0,0 +1,131 @@ +/* Copyright (C) 2016 by NuRAN Wireless + * + * 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 . + * + */ + +#include +#include +#include +#include +#include +#include +#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 new file mode 100644 index 00000000..3918b870 --- /dev/null +++ b/src/osmo-bts-litecell15/misc/lc15bts_bts.h @@ -0,0 +1,21 @@ +#ifndef _LC15BTS_BTS_H_ +#define _LC15BTS_BTS_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +/* 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 index f4df5d34..71701496 100644 --- a/src/osmo-bts-litecell15/misc/lc15bts_clock.c +++ b/src/osmo-bts-litecell15/misc/lc15bts_clock.c @@ -100,9 +100,6 @@ static int sysfs_write_str(int fd, const char *str) int lc15bts_clock_err_open(void) { - int rc; - int fault; - if (clkerr_fd_err < 0) { clkerr_fd_err = open(CLKERR_ERR_SYSFS, O_RDONLY); if (clkerr_fd_err < 0) { @@ -150,26 +147,6 @@ int lc15bts_clock_err_open(void) return clkerr_fd_reset; } } - - rc = sysfs_write_str(clkerr_fd_refresh, "once"); - if (rc < 0) { - lc15bts_clock_err_close(); - return rc; - } - - rc = sysfs_read_val(clkerr_fd_fault, &fault); - if (rc < 0) { - lc15bts_clock_err_close(); - return rc; - } - - if (fault) { - rc = sysfs_write_val(clkerr_fd_reset, 1); - if (rc < 0) { - lc15bts_clock_err_close(); - return rc; - } - } return 0; } diff --git a/src/osmo-bts-litecell15/misc/lc15bts_led.c b/src/osmo-bts-litecell15/misc/lc15bts_led.c new file mode 100644 index 00000000..603e0fb8 --- /dev/null +++ b/src/osmo-bts-litecell15/misc/lc15bts_led.c @@ -0,0 +1,333 @@ +/* Copyright (C) 2016 by NuRAN Wireless + * + * 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 . + * + */ +#include "lc15bts_led.h" +#include "lc15bts_bts.h" +#include +#include + +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, &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 new file mode 100644 index 00000000..b6d9d28b --- /dev/null +++ b/src/osmo-bts-litecell15/misc/lc15bts_led.h @@ -0,0 +1,22 @@ +#ifndef _LC15BTS_LED_H +#define _LC15BTS_LED_H + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#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 index 3a7d3a1f..51a05f93 100644 --- a/src/osmo-bts-litecell15/misc/lc15bts_mgr.c +++ b/src/osmo-bts-litecell15/misc/lc15bts_mgr.c @@ -46,13 +46,14 @@ #include "misc/lc15bts_par.h" #include "misc/lc15bts_bid.h" #include "misc/lc15bts_power.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 TEMP_TIMER_SECS (6 * 3600) +#define SENSOR_TIMER_SECS (6 * 3600) /* every 1 hours means 365*24 = 8760 rom writes per year (max) */ #define HOURS_TIMER_SECS (1 * 3600) @@ -62,54 +63,106 @@ void *tall_mgr_ctx; static struct lc15bts_mgr_instance manager = { .config_file = "lc15bts-mgr.cfg", .temp = { - .supply_limit = { - .thresh_warn = 60, - .thresh_crit = 78, + .supply_temp_limit = { + .thresh_warn_max = 80, + .thresh_crit_max = 85, + .thresh_warn_min = -40, }, - .soc_limit = { - .thresh_warn = 60, - .thresh_crit = 78, + .soc_temp_limit = { + .thresh_warn_max = 95, + .thresh_crit_max = 100, + .thresh_warn_min = -40, }, - .fpga_limit = { - .thresh_warn = 60, - .thresh_crit = 78, + .fpga_temp_limit = { + .thresh_warn_max = 95, + .thresh_crit_max = 100, + .thresh_warn_min = -40, }, - .logrf_limit = { - .thresh_warn = 60, - .thresh_crit = 78, + .rmsdet_temp_limit = { + .thresh_warn_max = 80, + .thresh_crit_max = 85, + .thresh_warn_min = -40, }, - .ocxo_limit = { - .thresh_warn = 60, - .thresh_crit = 78, + .ocxo_temp_limit = { + .thresh_warn_max = 80, + .thresh_crit_max = 85, + .thresh_warn_min = -40, }, - .tx0_limit = { - .thresh_warn = 60, - .thresh_crit = 78, + .tx0_temp_limit = { + .thresh_warn_max = 80, + .thresh_crit_max = 85, + .thresh_warn_min = -20, }, - .tx1_limit = { - .thresh_warn = 60, - .thresh_crit = 78, + .tx1_temp_limit = { + .thresh_warn_max = 80, + .thresh_crit_max = 85, + .thresh_warn_min = -20, }, - .pa0_limit = { - .thresh_warn = 60, - .thresh_crit = 78, + .pa0_temp_limit = { + .thresh_warn_max = 80, + .thresh_crit_max = 85, + .thresh_warn_min = -40, }, - .pa1_limit = { - .thresh_warn = 60, - .thresh_crit = 78, + .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 = TEMP_ACT_PA0_OFF | TEMP_ACT_PA1_OFF, + .action_crit = 0, + .action_comb = 0, .state = STATE_NORMAL, } }; -static struct osmo_timer_list temp_timer; -static void check_temp_timer_cb(void *unused) +static struct osmo_timer_list sensor_timer; +static void check_sensor_timer_cb(void *unused) { lc15bts_check_temp(no_rom_write); - - osmo_timer_schedule(&temp_timer, TEMP_TIMER_SECS, 0); + 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 */ } static struct osmo_timer_list hours_timer; @@ -118,6 +171,7 @@ 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 */ } static void print_help(void) @@ -169,6 +223,8 @@ static void signal_handler(int signal) switch (signal) { case SIGINT: 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; @@ -207,6 +263,12 @@ static struct log_info_cat mgr_log_info_cat[] = { .color = "\033[1;37m", .enabled = 1, .loglevel = LOGL_INFO, }, + [DSWD] = { + .name = "DSWD", + .description = "Software Watchdog", + .color = "\033[1;37m", + .enabled = 1, .loglevel = LOGL_INFO, + }, }; static const struct log_info mgr_log_info = { @@ -224,7 +286,6 @@ 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); @@ -253,9 +314,12 @@ int main(int argc, char **argv) exit(1); } + INIT_LLIST_HEAD(&manager.lc15bts_leds.list); + INIT_LLIST_HEAD(&manager.alarms.list); + /* start temperature check timer */ - temp_timer.cb = check_temp_timer_cb; - check_temp_timer_cb(NULL); + sensor_timer.cb = check_sensor_timer_cb; + check_sensor_timer_cb(NULL); /* start operational hours timer */ hours_timer.cb = hours_timer_cb; @@ -271,14 +335,13 @@ int main(int argc, char **argv) if (rc < 0) { exit(3); } - /* handle broadcast messages for ipaccess-find */ if (lc15bts_mgr_nl_init() != 0) exit(3); - /* Initialize the temperature control */ - lc15bts_mgr_temp_init(&manager); + /* Initialize the sensor control */ + lc15bts_mgr_sensor_init(&manager); if (lc15bts_mgr_calib_init(&manager) != 0) exit(3); @@ -291,7 +354,6 @@ int main(int argc, char **argv) } } - while (1) { log_reset_context(); osmo_select_main(0); diff --git a/src/osmo-bts-litecell15/misc/lc15bts_mgr.h b/src/osmo-bts-litecell15/misc/lc15bts_mgr.h index 98bd7010..4bfbdbc9 100644 --- a/src/osmo-bts-litecell15/misc/lc15bts_mgr.h +++ b/src/osmo-bts-litecell15/misc/lc15bts_mgr.h @@ -9,48 +9,154 @@ #include +#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 - TEMP_ACT_PWR_CONTRL = 0x1, + SENSOR_ACT_PWR_CONTRL = 0x1, #endif - TEMP_ACT_PA0_OFF = 0x2, - TEMP_ACT_PA1_OFF = 0x4, - TEMP_ACT_BTS_SRV_OFF = 0x10, + SENSOR_ACT_PA0_OFF = 0x2, + SENSOR_ACT_PA1_OFF = 0x4, + SENSOR_ACT_BTS_SRV_OFF = 0x10, }; /* actions only for normal state */ enum { #if 0 - TEMP_ACT_NORM_PW_CONTRL = 0x1, + SENSOR_ACT_NORM_PW_CONTRL = 0x1, #endif - TEMP_ACT_NORM_PA0_ON = 0x2, - TEMP_ACT_NORM_PA1_ON = 0x4, - TEMP_ACT_NORM_BTS_SRV_ON= 0x10, + SENSOR_ACT_NORM_PA0_ON = 0x2, + SENSOR_ACT_NORM_PA1_ON = 0x4, + SENSOR_ACT_NORM_BTS_SRV_ON= 0x10, }; -enum lc15bts_temp_state { +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; - int thresh_crit; + 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 { @@ -59,55 +165,258 @@ enum mgr_vty_node { ACT_NORM_NODE, ACT_WARN_NODE, ACT_CRIT_NODE, - LIMIT_SUPPLY_NODE, + LIMIT_SUPPLY_TEMP_NODE, LIMIT_SOC_NODE, LIMIT_FPGA_NODE, - LIMIT_LOGRF_NODE, + LIMIT_RMSDET_NODE, LIMIT_OCXO_NODE, - LIMIT_TX0_NODE, - LIMIT_TX1_NODE, - LIMIT_PA0_NODE, - LIMIT_PA1_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_temp_state state; - - struct lc15bts_temp_limit supply_limit; - struct lc15bts_temp_limit soc_limit; - struct lc15bts_temp_limit fpga_limit; - struct lc15bts_temp_limit logrf_limit; - struct lc15bts_temp_limit ocxo_limit; - struct lc15bts_temp_limit tx0_limit; - struct lc15bts_temp_limit tx1_limit; - struct lc15bts_temp_limit pa0_limit; - struct lc15bts_temp_limit pa1_limit; - } temp; + 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_temp_init(struct lc15bts_mgr_instance *mgr); -const char *lc15bts_mgr_temp_get_state(enum lc15bts_temp_state state); - +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_temp.c b/src/osmo-bts-litecell15/misc/lc15bts_mgr_temp.c index 042fc875..9d2dfecf 100644 --- a/src/osmo-bts-litecell15/misc/lc15bts_mgr_temp.c +++ b/src/osmo-bts-litecell15/misc/lc15bts_mgr_temp.c @@ -22,19 +22,22 @@ * along with this program. If not, see . * */ - +#include #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 "limits.h" #include #include #include +#include -static struct lc15bts_mgr_instance *s_mgr; -static struct osmo_timer_list temp_ctrl_timer; +struct lc15bts_mgr_instance *s_mgr; +static struct osmo_timer_list sensor_ctrl_timer; static const struct value_string state_names[] = { { STATE_NORMAL, "NORMAL" }, @@ -44,12 +47,12 @@ static const struct value_string state_names[] = { { 0, NULL } }; -const char *lc15bts_mgr_temp_get_state(enum lc15bts_temp_state state) +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_temp_state current_state, int critical, int warning) +static int next_state(enum lc15bts_sensor_state current_state, int critical, int warning) { int next_state = -1; switch (current_state) { @@ -85,7 +88,7 @@ static int next_state(enum lc15bts_temp_state current_state, int critical, int w static void handle_normal_actions(int actions) { /* switch on the PA */ - if (actions & TEMP_ACT_NORM_PA0_ON) { + 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"); @@ -95,7 +98,7 @@ static void handle_normal_actions(int actions) } } - if (actions & TEMP_ACT_NORM_PA1_ON) { + 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"); @@ -105,7 +108,7 @@ static void handle_normal_actions(int actions) } } - if (actions & TEMP_ACT_NORM_BTS_SRV_ON) { + if (actions & SENSOR_ACT_NORM_BTS_SRV_ON) { LOGP(DTEMP, LOGL_NOTICE, "Going to switch on the BTS service\n"); /* @@ -120,7 +123,7 @@ static void handle_normal_actions(int actions) static void handle_actions(int actions) { /* switch off the PA */ - if (actions & TEMP_ACT_PA1_OFF) { + 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"); @@ -130,7 +133,7 @@ static void handle_actions(int actions) } } - if (actions & TEMP_ACT_PA0_OFF) { + 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"); @@ -140,7 +143,7 @@ static void handle_actions(int actions) } } - if (actions & TEMP_ACT_BTS_SRV_OFF) { + if (actions & SENSOR_ACT_BTS_SRV_OFF) { LOGP(DTEMP, LOGL_NOTICE, "Going to switch off the BTS service\n"); /* @@ -161,36 +164,36 @@ static void handle_actions(int actions) */ static void execute_normal_act(struct lc15bts_mgr_instance *manager) { - LOGP(DTEMP, LOGL_NOTICE, "System is back to normal temperature.\n"); - handle_normal_actions(manager->temp.action_norm); + 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 temperature warning.\n"); - handle_actions(manager->temp.action_warn); + 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->temp.action_crit); + handle_actions(manager->state.action_crit); } -static void lc15bts_mgr_temp_handle(struct lc15bts_mgr_instance *manager, +static void lc15bts_mgr_sensor_handle(struct lc15bts_mgr_instance *manager, int critical, int warning) { - int new_state = next_state(manager->temp.state, critical, 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->temp.state), + get_value_string(state_names, manager->state.state), get_value_string(state_names, new_state)); - manager->temp.state = new_state; - switch (manager->temp.state) { + manager->state.state = new_state; + switch (manager->state.state) { case STATE_NORMAL: execute_normal_act(manager); break; @@ -206,163 +209,168 @@ static void lc15bts_mgr_temp_handle(struct lc15bts_mgr_instance *manager, }; } -static void temp_ctrl_check() +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); + 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 { - int temp = rc / 1000; - if (temp > s_mgr->temp.supply_limit.thresh_warn) + temp = temp / 1000; + if (temp > mgr->temp.supply_temp_limit.thresh_warn_max) warn_thresh_passed = 1; - if (temp > s_mgr->temp.supply_limit.thresh_crit) + 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); + 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 { - int temp = rc / 1000; - if (temp > s_mgr->temp.soc_limit.thresh_warn) + temp = temp / 1000; + if (temp > mgr->temp.soc_temp_limit.thresh_warn_max) warn_thresh_passed = 1; - if (temp > s_mgr->temp.soc_limit.thresh_crit) + 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); + 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 { - int temp = rc / 1000; - if (temp > s_mgr->temp.fpga_limit.thresh_warn) + temp = temp / 1000; + if (temp > mgr->temp.fpga_temp_limit.thresh_warn_max) warn_thresh_passed = 1; - if (temp > s_mgr->temp.fpga_limit.thresh_crit) + 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 RF log detector temperature */ - rc = lc15bts_temp_get(LC15BTS_TEMP_LOGRF); + /* 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 RF log detector temperature. rc=%d\n", rc); + "Failed to read the RMS detector temperature. rc=%d\n", rc); warn_thresh_passed = crit_thresh_passed = 1; } else { - int temp = rc / 1000; - if (temp > s_mgr->temp.logrf_limit.thresh_warn) + temp = temp / 1000; + if (temp > mgr->temp.rmsdet_temp_limit.thresh_warn_max) warn_thresh_passed = 1; - if (temp > s_mgr->temp.logrf_limit.thresh_crit) + if (temp > mgr->temp.rmsdet_temp_limit.thresh_crit_max) crit_thresh_passed = 1; - LOGP(DTEMP, LOGL_DEBUG, "RF log detector temperature is: %d\n", temp); + LOGP(DTEMP, LOGL_DEBUG, "RMS detector temperature is: %d\n", temp); } /* Read the current OCXO temperature */ - rc = lc15bts_temp_get(LC15BTS_TEMP_OCXO); + 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 { - int temp = rc / 1000; - if (temp > s_mgr->temp.ocxo_limit.thresh_warn) + temp = temp / 1000; + if (temp > mgr->temp.ocxo_temp_limit.thresh_warn_max) warn_thresh_passed = 1; - if (temp > s_mgr->temp.ocxo_limit.thresh_crit) + 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 #1 temperature */ - rc = lc15bts_temp_get(LC15BTS_TEMP_TX0); + /* 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 { - int temp = rc / 1000; - if (temp > s_mgr->temp.tx0_limit.thresh_warn) + temp = temp / 1000; + if (temp > mgr->temp.tx0_temp_limit.thresh_warn_max) warn_thresh_passed = 1; - if (temp > s_mgr->temp.tx0_limit.thresh_crit) + 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 #2 temperature */ - rc = lc15bts_temp_get(LC15BTS_TEMP_TX1); + /* 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 { - int temp = rc / 1000; - if (temp > s_mgr->temp.tx1_limit.thresh_warn) + temp = temp / 1000; + if (temp > mgr->temp.tx1_temp_limit.thresh_warn_max) warn_thresh_passed = 1; - if (temp > s_mgr->temp.tx1_limit.thresh_crit) + 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 #1 temperature */ - rc = lc15bts_temp_get(LC15BTS_TEMP_PA0); + /* 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 { - int temp = rc / 1000; - if (temp > s_mgr->temp.pa0_limit.thresh_warn) + temp = temp / 1000; + if (temp > mgr->temp.pa0_temp_limit.thresh_warn_max) warn_thresh_passed = 1; - if (temp > s_mgr->temp.pa0_limit.thresh_crit) + 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 #2 temperature */ - rc = lc15bts_temp_get(LC15BTS_TEMP_PA1); + /* 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 { - int temp = rc / 1000; - if (temp > s_mgr->temp.pa1_limit.thresh_warn) + temp = temp / 1000; + if (temp > mgr->temp.pa1_temp_limit.thresh_warn_max) warn_thresh_passed = 1; - if (temp > s_mgr->temp.pa1_limit.thresh_crit) + 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_temp_handle(s_mgr, crit_thresh_passed, warn_thresh_passed); + lc15bts_mgr_sensor_handle(mgr, crit_thresh_passed, warn_thresh_passed); } -static void temp_ctrl_check_cb(void *unused) +static void sensor_ctrl_check_cb(void *_data) { - temp_ctrl_check(); - /* Check every two minutes? XXX make it configurable! */ - osmo_timer_schedule(&temp_ctrl_timer, 2 * 60, 0); + 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? */ } -int lc15bts_mgr_temp_init(struct lc15bts_mgr_instance *mgr) +int lc15bts_mgr_sensor_init(struct lc15bts_mgr_instance *mgr) { s_mgr = mgr; - temp_ctrl_timer.cb = temp_ctrl_check_cb; - temp_ctrl_check_cb(NULL); + 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 index 280c9c75..b96349eb 100644 --- a/src/osmo-bts-litecell15/misc/lc15bts_mgr_vty.c +++ b/src/osmo-bts-litecell15/misc/lc15bts_mgr_vty.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include @@ -43,6 +44,7 @@ #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; @@ -64,15 +66,21 @@ static int go_to_parent(struct vty *vty) case ACT_NORM_NODE: case ACT_WARN_NODE: case ACT_CRIT_NODE: - case LIMIT_SUPPLY_NODE: + case LIMIT_SUPPLY_TEMP_NODE: case LIMIT_SOC_NODE: case LIMIT_FPGA_NODE: - case LIMIT_LOGRF_NODE: + case LIMIT_RMSDET_NODE: case LIMIT_OCXO_NODE: - case LIMIT_TX0_NODE: - case LIMIT_TX1_NODE: - case LIMIT_PA0_NODE: - case LIMIT_PA1_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: @@ -88,15 +96,21 @@ static int is_config_node(struct vty *vty, int node) case ACT_NORM_NODE: case ACT_WARN_NODE: case ACT_CRIT_NODE: - case LIMIT_SUPPLY_NODE: + case LIMIT_SUPPLY_TEMP_NODE: case LIMIT_SOC_NODE: case LIMIT_FPGA_NODE: - case LIMIT_LOGRF_NODE: + case LIMIT_RMSDET_NODE: case LIMIT_OCXO_NODE: - case LIMIT_TX0_NODE: - case LIMIT_TX1_NODE: - case LIMIT_PA0_NODE: - case LIMIT_PA1_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; @@ -122,25 +136,25 @@ static struct cmd_node mgr_node = { static struct cmd_node act_norm_node = { ACT_NORM_NODE, - "%s(action-normal)# ", + "%s(actions-normal)# ", 1, }; static struct cmd_node act_warn_node = { ACT_WARN_NODE, - "%s(action-warn)# ", + "%s(actions-warn)# ", 1, }; static struct cmd_node act_crit_node = { ACT_CRIT_NODE, - "%s(action-critical)# ", + "%s(actions-critical)# ", 1, }; -static struct cmd_node limit_supply_node = { - LIMIT_SUPPLY_NODE, - "%s(limit-supply)# ", +static struct cmd_node limit_supply_temp_node = { + LIMIT_SUPPLY_TEMP_NODE, + "%s(limit-supply-temp)# ", 1, }; @@ -156,9 +170,9 @@ static struct cmd_node limit_fpga_node = { 1, }; -static struct cmd_node limit_logrf_node = { - LIMIT_LOGRF_NODE, - "%s(limit-logrf)# ", +static struct cmd_node limit_rmsdet_node = { + LIMIT_RMSDET_NODE, + "%s(limit-rmsdet)# ", 1, }; @@ -168,24 +182,60 @@ static struct cmd_node limit_ocxo_node = { 1, }; -static struct cmd_node limit_tx0_node = { - LIMIT_TX0_NODE, - "%s(limit-tx0)# ", +static struct cmd_node limit_tx0_temp_node = { + LIMIT_TX0_TEMP_NODE, + "%s(limit-tx0-temp)# ", 1, }; -static struct cmd_node limit_tx1_node = { - LIMIT_TX1_NODE, - "%s(limit-tx1)# ", +static struct cmd_node limit_tx1_temp_node = { + LIMIT_TX1_TEMP_NODE, + "%s(limit-tx1-temp)# ", 1, }; -static struct cmd_node limit_pa0_node = { - LIMIT_PA0_NODE, - "%s(limit-pa0)# ", +static struct cmd_node limit_pa0_temp_node = { + LIMIT_PA0_TEMP_NODE, + "%s(limit-pa0-temp)# ", 1, }; -static struct cmd_node limit_pa1_node = { - LIMIT_PA1_NODE, - "%s(limit-pa1)# ", +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, }; @@ -197,55 +247,68 @@ DEFUN(cfg_mgr, cfg_mgr_cmd, return CMD_SUCCESS; } -static void write_temp_limit(struct vty *vty, const char *name, - struct lc15bts_temp_limit *limit) +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 %d%s", - limit->thresh_warn, VTY_NEWLINE); - vty_out(vty, " threshold critical %d%s", - limit->thresh_crit, 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 & TEMP_ACT_NORM_PA0_ON) ? "" : "no ", VTY_NEWLINE); + (actions & SENSOR_ACT_NORM_PA0_ON) ? "" : "no ", VTY_NEWLINE); vty_out(vty, " %spa1-on%s", - (actions & TEMP_ACT_NORM_PA1_ON) ? "" : "no ", VTY_NEWLINE); + (actions & SENSOR_ACT_NORM_PA1_ON) ? "" : "no ", VTY_NEWLINE); vty_out(vty, " %sbts-service-on%s", - (actions & TEMP_ACT_NORM_BTS_SRV_ON) ? "" : "no ", VTY_NEWLINE); + (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 & TEMP_ACT_PA0_OFF) ? "" : "no ", VTY_NEWLINE); + (actions & SENSOR_ACT_PA0_OFF) ? "" : "no ", VTY_NEWLINE); vty_out(vty, " %spa1-off%s", - (actions & TEMP_ACT_PA1_OFF) ? "" : "no ", VTY_NEWLINE); + (actions & SENSOR_ACT_PA1_OFF) ? "" : "no ", VTY_NEWLINE); vty_out(vty, " %sbts-service-off%s", - (actions & TEMP_ACT_BTS_SRV_OFF) ? "" : "no ", VTY_NEWLINE); + (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_temp_limit(vty, "limits supply", &s_mgr->temp.supply_limit); - write_temp_limit(vty, "limits soc", &s_mgr->temp.soc_limit); - write_temp_limit(vty, "limits fpga", &s_mgr->temp.fpga_limit); - write_temp_limit(vty, "limits logrf", &s_mgr->temp.logrf_limit); - write_temp_limit(vty, "limits ocxo", &s_mgr->temp.ocxo_limit); - write_temp_limit(vty, "limits tx0", &s_mgr->temp.tx0_limit); - write_temp_limit(vty, "limits tx1", &s_mgr->temp.tx1_limit); - write_temp_limit(vty, "limits pa0", &s_mgr->temp.pa0_limit); - write_temp_limit(vty, "limits pa1", &s_mgr->temp.pa1_limit); + 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->temp.action_norm); - write_action(vty, "actions warn", s_mgr->temp.action_warn); - write_action(vty, "actions critical", s_mgr->temp.action_crit); + 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; } @@ -255,7 +318,7 @@ static int config_write_dummy(struct vty *vty) return CMD_SUCCESS; } -#define CFG_LIMIT(name, expl, switch_to, variable) \ +#define CFG_LIMIT_TEMP(name, expl, switch_to, variable) \ DEFUN(cfg_limit_##name, cfg_limit_##name##_cmd, \ "limits " #name, \ "Configure Limits\n" expl) \ @@ -265,32 +328,123 @@ DEFUN(cfg_limit_##name, cfg_limit_##name##_cmd, \ return CMD_SUCCESS; \ } -CFG_LIMIT(supply, "SUPPLY\n", LIMIT_SUPPLY_NODE, supply_limit) -CFG_LIMIT(soc, "SOC\n", LIMIT_SOC_NODE, soc_limit) -CFG_LIMIT(fpga, "FPGA\n", LIMIT_FPGA_NODE, fpga_limit) -CFG_LIMIT(logrf, "LOGRF\n", LIMIT_LOGRF_NODE, logrf_limit) -CFG_LIMIT(ocxo, "OCXO\n", LIMIT_OCXO_NODE, ocxo_limit) -CFG_LIMIT(tx0, "TX0\n", LIMIT_TX0_NODE, tx0_limit) -CFG_LIMIT(tx1, "TX1\n", LIMIT_TX1_NODE, tx1_limit) -CFG_LIMIT(pa0, "PA0\n", LIMIT_PA0_NODE, pa0_limit) -CFG_LIMIT(pa1, "PA1\n", LIMIT_PA1_NODE, pa1_limit) -#undef CFG_LIMIT +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 -DEFUN(cfg_limit_warning, cfg_thresh_warning_cmd, - "threshold warning <0-200>", +#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_temp_limit *limit = vty->index; - limit->thresh_warn = atoi(argv[0]); + struct lc15bts_volt_limit *limit = vty->index; + limit->thresh_warn_min = atoi(argv[0]); return CMD_SUCCESS; } -DEFUN(cfg_limit_crit, cfg_thresh_crit_cmd, - "threshold critical <0-200>", - "Threshold to reach\n" "Severe level\n" "Range\n") +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_temp_limit *limit = vty->index; - limit->thresh_crit = atoi(argv[0]); + 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" "Warning 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" "Warning level\n" "Range\n") +{ + struct lc15bts_pwr_limit *limit = vty->index; + limit->thresh_crit_max = atoi(argv[0]); return CMD_SUCCESS; } @@ -300,7 +454,7 @@ DEFUN(cfg_action_##name, cfg_action_##name##_cmd, \ "Configure Actions\n" expl) \ { \ vty->node = switch_to; \ - vty->index = &s_mgr->temp.variable; \ + vty->index = &s_mgr->state.variable; \ return CMD_SUCCESS; \ } CFG_ACTION(normal, "Normal Actions\n", ACT_NORM_NODE, action_norm) @@ -313,7 +467,7 @@ DEFUN(cfg_action_pa0_on, cfg_action_pa0_on_cmd, "Switch the Power Amplifier #0 on\n") { int *action = vty->index; - *action |= TEMP_ACT_NORM_PA0_ON; + *action |= SENSOR_ACT_NORM_PA0_ON; return CMD_SUCCESS; } @@ -322,7 +476,7 @@ DEFUN(cfg_no_action_pa0_on, cfg_no_action_pa0_on_cmd, NO_STR "Switch the Power Amplifieri #0 on\n") { int *action = vty->index; - *action &= ~TEMP_ACT_NORM_PA0_ON; + *action &= ~SENSOR_ACT_NORM_PA0_ON; return CMD_SUCCESS; } @@ -331,7 +485,7 @@ DEFUN(cfg_action_pa1_on, cfg_action_pa1_on_cmd, "Switch the Power Amplifier #1 on\n") { int *action = vty->index; - *action |= TEMP_ACT_NORM_PA1_ON; + *action |= SENSOR_ACT_NORM_PA1_ON; return CMD_SUCCESS; } @@ -340,7 +494,7 @@ DEFUN(cfg_no_action_pa1_on, cfg_no_action_pa1_on_cmd, NO_STR "Switch the Power Amplifieri #1 on\n") { int *action = vty->index; - *action &= ~TEMP_ACT_NORM_PA1_ON; + *action &= ~SENSOR_ACT_NORM_PA1_ON; return CMD_SUCCESS; } @@ -349,7 +503,7 @@ DEFUN(cfg_action_bts_srv_on, cfg_action_bts_srv_on_cmd, "Start the systemd lc15bts.service\n") { int *action = vty->index; - *action |= TEMP_ACT_NORM_BTS_SRV_ON; + *action |= SENSOR_ACT_NORM_BTS_SRV_ON; return CMD_SUCCESS; } @@ -358,7 +512,7 @@ DEFUN(cfg_no_action_bts_srv_on, cfg_no_action_bts_srv_on_cmd, NO_STR "Start the systemd lc15bts.service\n") { int *action = vty->index; - *action &= ~TEMP_ACT_NORM_BTS_SRV_ON; + *action &= ~SENSOR_ACT_NORM_BTS_SRV_ON; return CMD_SUCCESS; } @@ -367,7 +521,7 @@ DEFUN(cfg_action_pa0_off, cfg_action_pa0_off_cmd, "Switch the Power Amplifier #0 off\n") { int *action = vty->index; - *action |= TEMP_ACT_PA0_OFF; + *action |= SENSOR_ACT_PA0_OFF; return CMD_SUCCESS; } @@ -376,7 +530,7 @@ DEFUN(cfg_no_action_pa0_off, cfg_no_action_pa0_off_cmd, NO_STR "Do not switch off the Power Amplifier #0\n") { int *action = vty->index; - *action &= ~TEMP_ACT_PA0_OFF; + *action &= ~SENSOR_ACT_PA0_OFF; return CMD_SUCCESS; } @@ -385,7 +539,7 @@ DEFUN(cfg_action_pa1_off, cfg_action_pa1_off_cmd, "Switch the Power Amplifier #1 off\n") { int *action = vty->index; - *action |= TEMP_ACT_PA1_OFF; + *action |= SENSOR_ACT_PA1_OFF; return CMD_SUCCESS; } @@ -394,7 +548,7 @@ DEFUN(cfg_no_action_pa1_off, cfg_no_action_pa1_off_cmd, NO_STR "Do not switch off the Power Amplifier #1\n") { int *action = vty->index; - *action &= ~TEMP_ACT_PA1_OFF; + *action &= ~SENSOR_ACT_PA1_OFF; return CMD_SUCCESS; } @@ -403,7 +557,7 @@ DEFUN(cfg_action_bts_srv_off, cfg_action_bts_srv_off_cmd, "Stop the systemd lc15bts.service\n") { int *action = vty->index; - *action |= TEMP_ACT_BTS_SRV_OFF; + *action |= SENSOR_ACT_BTS_SRV_OFF; return CMD_SUCCESS; } @@ -412,75 +566,177 @@ DEFUN(cfg_no_action_bts_srv_off, cfg_no_action_bts_srv_off_cmd, NO_STR "Stop the systemd lc15bts.service\n") { int *action = vty->index; - *action &= ~TEMP_ACT_BTS_SRV_OFF; + *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_temp_get_state(s_mgr->temp.state), VTY_NEWLINE); + lc15bts_mgr_sensor_get_state(s_mgr->state.state), VTY_NEWLINE); vty_out(vty, "Current Temperatures%s", VTY_NEWLINE); - vty_out(vty, " Main Supply : %f Celcius%s", - lc15bts_temp_get(LC15BTS_TEMP_SUPPLY) / 1000.0f, + lc15bts_temp_get(LC15BTS_TEMP_SUPPLY, &temp); + vty_out(vty, " Main Supply : %4.2f Celcius%s", + temp/ 1000.0f, VTY_NEWLINE); - vty_out(vty, " SoC : %f Celcius%s", - lc15bts_temp_get(LC15BTS_TEMP_SOC) / 1000.0f, + lc15bts_temp_get(LC15BTS_TEMP_SOC, &temp); + vty_out(vty, " SoC : %4.2f Celcius%s", + temp / 1000.0f, VTY_NEWLINE); - vty_out(vty, " FPGA : %f Celcius%s", - lc15bts_temp_get(LC15BTS_TEMP_FPGA) / 1000.0f, + lc15bts_temp_get(LC15BTS_TEMP_FPGA, &temp); + vty_out(vty, " FPGA : %4.2f Celcius%s", + temp / 1000.0f, VTY_NEWLINE); - vty_out(vty, " LogRF : %f Celcius%s", - lc15bts_temp_get(LC15BTS_TEMP_LOGRF) / 1000.0f, + lc15bts_temp_get(LC15BTS_TEMP_RMSDET, &temp); + vty_out(vty, " RMSDet : %4.2f Celcius%s", + temp / 1000.0f, VTY_NEWLINE); - vty_out(vty, " OCXO : %f Celcius%s", - lc15bts_temp_get(LC15BTS_TEMP_OCXO) / 1000.0f, + lc15bts_temp_get(LC15BTS_TEMP_OCXO, &temp); + vty_out(vty, " OCXO : %4.2f Celcius%s", + temp / 1000.0f, VTY_NEWLINE); - vty_out(vty, " TX 0 : %f Celcius%s", - lc15bts_temp_get(LC15BTS_TEMP_TX0) / 1000.0f, + lc15bts_temp_get(LC15BTS_TEMP_TX0, &temp); + vty_out(vty, " TX 0 : %4.2f Celcius%s", + temp / 1000.0f, VTY_NEWLINE); - vty_out(vty, " TX 1 : %f Celcius%s", - lc15bts_temp_get(LC15BTS_TEMP_TX1) / 1000.0f, + lc15bts_temp_get(LC15BTS_TEMP_TX1, &temp); + vty_out(vty, " TX 1 : %4.2f Celcius%s", + temp / 1000.0f, VTY_NEWLINE); - vty_out(vty, " Power Amp #0: %f Celcius%s", - lc15bts_temp_get(LC15BTS_TEMP_PA0) / 1000.0f, + lc15bts_temp_get(LC15BTS_TEMP_PA0, &temp); + vty_out(vty, " Power Amp #0: %4.2f Celcius%s", + temp / 1000.0f, VTY_NEWLINE); - vty_out(vty, " Power Amp #1: %f Celcius%s", - lc15bts_temp_get(LC15BTS_TEMP_PA1) / 1000.0f, + lc15bts_temp_get(LC15BTS_TEMP_PA1, &temp); + vty_out(vty, " Power Amp #1: %4.2f Celcius%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, ¤t); + 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", - lc15bts_power_sensor_get(LC15BTS_POWER_SUPPLY, - LC15BTS_POWER_VOLTAGE)/1000.0f, - lc15bts_power_sensor_get(LC15BTS_POWER_SUPPLY, - LC15BTS_POWER_CURRENT)/1000.0f, - lc15bts_power_sensor_get(LC15BTS_POWER_SUPPLY, - LC15BTS_POWER_POWER)/1000000.0f, + 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, ¤t); + 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", - lc15bts_power_sensor_get(LC15BTS_POWER_PA0, - LC15BTS_POWER_VOLTAGE)/1000.0f, - lc15bts_power_sensor_get(LC15BTS_POWER_PA0, - LC15BTS_POWER_CURRENT)/1000.0f, - lc15bts_power_sensor_get(LC15BTS_POWER_PA0, - LC15BTS_POWER_POWER)/1000000.0f, + 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, ¤t); + 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", - lc15bts_power_sensor_get(LC15BTS_POWER_PA1, - LC15BTS_POWER_VOLTAGE)/1000.0f, - lc15bts_power_sensor_get(LC15BTS_POWER_PA1, - LC15BTS_POWER_CURRENT)/1000.0f, - lc15bts_power_sensor_get(LC15BTS_POWER_PA1, - LC15BTS_POWER_POWER)/1000000.0f, + 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" @@ -493,10 +749,153 @@ DEFUN(calibrate_clock, calibrate_clock_cmd, return CMD_SUCCESS; } -static void register_limit(int limit) +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") { - install_element(limit, &cfg_thresh_warning_cmd); - install_element(limit, &cfg_thresh_crit_cmd); + 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) @@ -519,11 +918,62 @@ static void register_action(int act) 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); @@ -532,50 +982,73 @@ int lc15bts_mgr_vty_init(void) vty_install_default(MGR_NODE); /* install the limit nodes */ - install_node(&limit_supply_node, config_write_dummy); - install_element(MGR_NODE, &cfg_limit_supply_cmd); - register_limit(LIMIT_SUPPLY_NODE); - vty_install_default(LIMIT_SUPPLY_NODE); + install_node(&limit_supply_temp_node, config_write_dummy); + install_element(MGR_NODE, &cfg_limit_supply_temp_cmd); + vty_install_default(LIMIT_SUPPLY_TEMP_NODE); install_node(&limit_soc_node, config_write_dummy); - install_element(MGR_NODE, &cfg_limit_soc_cmd); - register_limit(LIMIT_SOC_NODE); + install_element(MGR_NODE, &cfg_limit_soc_temp_cmd); vty_install_default(LIMIT_SOC_NODE); install_node(&limit_fpga_node, config_write_dummy); - install_element(MGR_NODE, &cfg_limit_fpga_cmd); - register_limit(LIMIT_FPGA_NODE); + install_element(MGR_NODE, &cfg_limit_fpga_temp_cmd); vty_install_default(LIMIT_FPGA_NODE); - install_node(&limit_logrf_node, config_write_dummy); - install_element(MGR_NODE, &cfg_limit_logrf_cmd); - register_limit(LIMIT_LOGRF_NODE); - vty_install_default(LIMIT_LOGRF_NODE); + install_node(&limit_rmsdet_node, config_write_dummy); + install_element(MGR_NODE, &cfg_limit_rmsdet_temp_cmd); + vty_install_default(LIMIT_RMSDET_NODE); install_node(&limit_ocxo_node, config_write_dummy); - install_element(MGR_NODE, &cfg_limit_ocxo_cmd); - register_limit(LIMIT_OCXO_NODE); + install_element(MGR_NODE, &cfg_limit_ocxo_temp_cmd); vty_install_default(LIMIT_OCXO_NODE); - install_node(&limit_tx0_node, config_write_dummy); - install_element(MGR_NODE, &cfg_limit_tx0_cmd); - register_limit(LIMIT_TX0_NODE); - vty_install_default(LIMIT_TX0_NODE); + install_node(&limit_tx0_temp_node, config_write_dummy); + install_element(MGR_NODE, &cfg_limit_tx0_temp_cmd); + vty_install_default(LIMIT_TX0_TEMP_NODE); + + install_node(&limit_tx1_temp_node, config_write_dummy); + install_element(MGR_NODE, &cfg_limit_tx1_temp_cmd); + vty_install_default(LIMIT_TX1_TEMP_NODE); - install_node(&limit_tx1_node, config_write_dummy); - install_element(MGR_NODE, &cfg_limit_tx1_cmd); - register_limit(LIMIT_TX1_NODE); - vty_install_default(LIMIT_TX1_NODE); + install_node(&limit_pa0_temp_node, config_write_dummy); + install_element(MGR_NODE, &cfg_limit_pa0_temp_cmd); + vty_install_default(LIMIT_PA0_TEMP_NODE); - install_node(&limit_pa0_node, config_write_dummy); - install_element(MGR_NODE, &cfg_limit_pa0_cmd); - register_limit(LIMIT_PA0_NODE); - vty_install_default(LIMIT_PA0_NODE); + install_node(&limit_pa1_temp_node, config_write_dummy); + install_element(MGR_NODE, &cfg_limit_pa1_temp_cmd); + vty_install_default(LIMIT_PA1_TEMP_NODE); - install_node(&limit_pa1_node, config_write_dummy); - install_element(MGR_NODE, &cfg_limit_pa1_cmd); - register_limit(LIMIT_PA1_NODE); - vty_install_default(LIMIT_PA1_NODE); + 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); + vty_install_default(LIMIT_SUPPLY_VOLT_NODE); + + 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); + vty_install_default(LIMIT_TX0_VSWR_NODE); + + 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); + vty_install_default(LIMIT_TX1_VSWR_NODE); + + 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); + vty_install_default(LIMIT_SUPPLY_PWR_NODE); + + install_node(&limit_pa0_pwr_node, config_write_dummy); + install_element(MGR_NODE, &cfg_limit_pa0_pwr_cmd); + vty_install_default(LIMIT_PA0_PWR_NODE); + + install_node(&limit_pa1_pwr_node, config_write_dummy); + install_element(MGR_NODE, &cfg_limit_pa1_pwr_cmd); + vty_install_default(LIMIT_PA1_PWR_NODE); + + install_node(&limit_gps_fix_node, config_write_dummy); + install_element(MGR_NODE, &cfg_limit_gps_fix_cmd); + vty_install_default(LIMIT_GPS_FIX_NODE); /* install the normal node */ install_node(&act_norm_node, config_write_dummy); @@ -593,6 +1066,12 @@ int lc15bts_mgr_vty_init(void) register_action(ACT_CRIT_NODE); vty_install_default(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; } diff --git a/src/osmo-bts-litecell15/misc/lc15bts_misc.c b/src/osmo-bts-litecell15/misc/lc15bts_misc.c index fa59b7c8..2cedc5d8 100644 --- a/src/osmo-bts-litecell15/misc/lc15bts_misc.c +++ b/src/osmo-bts-litecell15/misc/lc15bts_misc.c @@ -41,11 +41,13 @@ #include #include +#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 @@ -58,54 +60,113 @@ static const struct { enum lc15bts_par ee_par; } temp_data[] = { { - .name = "supply", + .name = "supply_temp", .has_max = 1, .sensor = LC15BTS_TEMP_SUPPLY, .ee_par = LC15BTS_PAR_TEMP_SUPPLY_MAX, }, { - .name = "soc", + .name = "soc_temp", .has_max = 0, .sensor = LC15BTS_TEMP_SOC, .ee_par = LC15BTS_PAR_TEMP_SOC_MAX, }, { - .name = "fpga", + .name = "fpga_temp", .has_max = 0, .sensor = LC15BTS_TEMP_FPGA, .ee_par = LC15BTS_PAR_TEMP_FPGA_MAX, }, { - .name = "logrf", + .name = "rmsdet_temp", .has_max = 1, - .sensor = LC15BTS_TEMP_LOGRF, - .ee_par = LC15BTS_PAR_TEMP_LOGRF_MAX, + .sensor = LC15BTS_TEMP_RMSDET, + .ee_par = LC15BTS_PAR_TEMP_RMSDET_MAX, }, { - .name = "ocxo", + .name = "ocxo_temp", .has_max = 1, .sensor = LC15BTS_TEMP_OCXO, .ee_par = LC15BTS_PAR_TEMP_OCXO_MAX, }, { - .name = "tx0", + .name = "tx0_temp", .has_max = 0, .sensor = LC15BTS_TEMP_TX0, .ee_par = LC15BTS_PAR_TEMP_TX0_MAX, }, { - .name = "tx1", + .name = "tx1_temp", .has_max = 0, .sensor = LC15BTS_TEMP_TX1, .ee_par = LC15BTS_PAR_TEMP_TX1_MAX, }, { - .name = "pa0", + .name = "pa0_temp", .has_max = 1, .sensor = LC15BTS_TEMP_PA0, .ee_par = LC15BTS_PAR_TEMP_PA0_MAX, }, { - .name = "pa1", + .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)]; @@ -117,7 +178,7 @@ void lc15bts_check_temp(int no_rom_write) rc = lc15bts_par_get_int(tall_mgr_ctx, temp_data[i].ee_par, &ret); temp_old[i] = ret * 1000; - temp_cur[i] = lc15bts_temp_get(temp_data[i].sensor); + 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]); @@ -143,6 +204,91 @@ void lc15bts_check_temp(int no_rom_write) } } +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 *********************************************************************/ diff --git a/src/osmo-bts-litecell15/misc/lc15bts_misc.h b/src/osmo-bts-litecell15/misc/lc15bts_misc.h index 4c3a862a..79e9e686 100644 --- a/src/osmo-bts-litecell15/misc/lc15bts_misc.h +++ b/src/osmo-bts-litecell15/misc/lc15bts_misc.h @@ -4,6 +4,8 @@ #include 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); diff --git a/src/osmo-bts-litecell15/misc/lc15bts_par.c b/src/osmo-bts-litecell15/misc/lc15bts_par.c index 13b00803..75314a44 100644 --- a/src/osmo-bts-litecell15/misc/lc15bts_par.c +++ b/src/osmo-bts-litecell15/misc/lc15bts_par.c @@ -43,12 +43,19 @@ 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_LOGRF_MAX, "temp-logrf-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" }, @@ -60,17 +67,23 @@ 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_LOGRF_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_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; @@ -168,3 +181,52 @@ int lc15bts_par_set_buf(void *ctx, enum lc15bts_par par, const uint8_t *buf, uns 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(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 index dd869d33..217ae5f2 100644 --- a/src/osmo-bts-litecell15/misc/lc15bts_par.h +++ b/src/osmo-bts-litecell15/misc/lc15bts_par.h @@ -10,12 +10,19 @@ enum lc15bts_par { LC15BTS_PAR_TEMP_SUPPLY_MAX, LC15BTS_PAR_TEMP_SOC_MAX, LC15BTS_PAR_TEMP_FPGA_MAX, - LC15BTS_PAR_TEMP_LOGRF_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, @@ -31,5 +38,7 @@ int lc15bts_par_get_buf(void *ctx, enum lc15bts_par par, uint8_t *buf, unsigned 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 index 5b01d36b..1a37d8e6 100644 --- a/src/osmo-bts-litecell15/misc/lc15bts_power.c +++ b/src/osmo-bts-litecell15/misc/lc15bts_power.c @@ -39,7 +39,7 @@ static const char *power_enable_devs[_NUM_POWER_SOURCES] = { }; static const char *power_sensor_devs[_NUM_POWER_SOURCES] = { - [LC15BTS_POWER_SUPPLY] = "/var/lc15/pwr-sense/pa-supply/", + [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/", }; @@ -52,7 +52,8 @@ static const char *power_sensor_type_str[_NUM_POWER_TYPES] = { int lc15bts_power_sensor_get( enum lc15bts_power_source source, - enum lc15bts_power_type type) + enum lc15bts_power_type type, + int *power) { char buf[PATH_MAX]; char pwrstr[10]; @@ -82,8 +83,8 @@ int lc15bts_power_sensor_get( return -EIO; } close(fd); - - return atoi(pwrstr); + *power = atoi(pwrstr); + return 0; } @@ -171,3 +172,39 @@ int lc15bts_power_get( 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 index 8963b761..b48cfdcd 100644 --- a/src/osmo-bts-litecell15/misc/lc15bts_power.h +++ b/src/osmo-bts-litecell15/misc/lc15bts_power.h @@ -17,7 +17,8 @@ enum lc15bts_power_type { int lc15bts_power_sensor_get( enum lc15bts_power_source source, - enum lc15bts_power_type type); + enum lc15bts_power_type type, + int *volt); int lc15bts_power_set( enum lc15bts_power_source source, @@ -26,4 +27,12 @@ int lc15bts_power_set( 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_temp.c b/src/osmo-bts-litecell15/misc/lc15bts_temp.c index aa358547..45602dcc 100644 --- a/src/osmo-bts-litecell15/misc/lc15bts_temp.c +++ b/src/osmo-bts-litecell15/misc/lc15bts_temp.c @@ -29,20 +29,19 @@ #include "lc15bts_temp.h" - static const char *temp_devs[_NUM_TEMP_SENSORS] = { - [LC15BTS_TEMP_SUPPLY] = "/var/lc15/temp/pa-supply/temp", - [LC15BTS_TEMP_SOC] = "/var/lc15/temp/cpu/temp", - [LC15BTS_TEMP_FPGA] = "/var/lc15/temp/fpga/temp", - [LC15BTS_TEMP_LOGRF] = "/var/lc15/temp/logrf/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", + [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 lc15bts_temp_get(enum lc15bts_temp_sensor sensor, int *temp) { char buf[PATH_MAX]; char tempstr[8]; @@ -69,7 +68,7 @@ int lc15bts_temp_get(enum lc15bts_temp_sensor sensor) return -EIO; } close(fd); - - return atoi(tempstr); + *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 index aca8fe26..35d81f1b 100644 --- a/src/osmo-bts-litecell15/misc/lc15bts_temp.h +++ b/src/osmo-bts-litecell15/misc/lc15bts_temp.h @@ -5,7 +5,7 @@ enum lc15bts_temp_sensor { LC15BTS_TEMP_SUPPLY, LC15BTS_TEMP_SOC, LC15BTS_TEMP_FPGA, - LC15BTS_TEMP_LOGRF, + LC15BTS_TEMP_RMSDET, LC15BTS_TEMP_OCXO, LC15BTS_TEMP_TX0, LC15BTS_TEMP_TX1, @@ -22,6 +22,7 @@ enum lc15bts_temp_type { _NUM_TEMP_TYPES }; -int lc15bts_temp_get(enum lc15bts_temp_sensor sensor); +int lc15bts_temp_get(enum lc15bts_temp_sensor sensor, int *temp); + #endif -- cgit v1.2.3