diff options
author | Holger Hans Peter Freyther <holger@moiji-mobile.com> | 2014-08-21 15:49:55 +0200 |
---|---|---|
committer | Holger Hans Peter Freyther <holger@moiji-mobile.com> | 2014-08-21 15:50:40 +0200 |
commit | ffe1d2e1e0bc99debf5cc826c43632680d969825 (patch) | |
tree | 6b052239de319a45616286fa403c35aac61b224e | |
parent | 07198750b29fa891dd6c1d6266964691aa9e9095 (diff) | |
parent | 575f633483d09e5d6666aed4d7e132614c2e1847 (diff) |
Merge commit 'sysmocom/features/sysmobts-mgr-vty'
Some re-factorings. Still a very long way to go. It should
work with haralds re-based but that wasn't verified due my
toolchain not having the most recent libosmocore. The service
file and screenrc change has not been verified either.
-rw-r--r-- | Makefile.am | 3 | ||||
-rw-r--r-- | contrib/screenrc-sysmobts | 2 | ||||
-rw-r--r-- | contrib/sysmobts-mgr.service | 2 | ||||
-rw-r--r-- | doc/examples/sysmobts-mgr.cfg | 24 | ||||
-rw-r--r-- | src/osmo-bts-sysmo/Makefile.am | 6 | ||||
-rw-r--r-- | src/osmo-bts-sysmo/misc/sysmobts_mgr.c | 82 | ||||
-rw-r--r-- | src/osmo-bts-sysmo/misc/sysmobts_mgr.h | 13 | ||||
-rw-r--r-- | src/osmo-bts-sysmo/misc/sysmobts_mgr_2050.c | 349 | ||||
-rw-r--r-- | src/osmo-bts-sysmo/misc/sysmobts_mgr_vty.c | 133 | ||||
-rw-r--r-- | src/osmo-bts-sysmo/misc/sysmobts_misc.c | 260 | ||||
-rw-r--r-- | src/osmo-bts-sysmo/misc/sysmobts_misc.h | 33 |
11 files changed, 562 insertions, 345 deletions
diff --git a/Makefile.am b/Makefile.am index 733e80f6..afb4d273 100644 --- a/Makefile.am +++ b/Makefile.am @@ -11,4 +11,5 @@ EXTRA_DIST = \ contrib/sysmobts-calib/sysmobts-calib.c \ contrib/sysmobts-calib/sysmobts-layer1.c \ contrib/sysmobts-calib/sysmobts-layer1.h \ - doc/examples/osmo-bts.cfg + doc/examples/osmo-bts.cfg \ + doc/examples/sysmobts-mgr.cfg diff --git a/contrib/screenrc-sysmobts b/contrib/screenrc-sysmobts index 1bd510ce..80e78cc5 100644 --- a/contrib/screenrc-sysmobts +++ b/contrib/screenrc-sysmobts @@ -1,5 +1,5 @@ chdir /tmp screen -t BTS 0 /etc/osmocom/respawn.sh /usr/bin/sysmobts -c /etc/osmocom/osmo-bts.cfg -r 1 -M screen -t PCU 1 /etc/osmocom/respawn-only.sh /usr/bin/osmo-pcu -c /etc/osmocom/osmo-pcu.cfg -e -screen -t MGR 2 /etc/osmocom/respawn-only.sh /usr/bin/sysmobts-mgr -n +screen -t MGR 2 /etc/osmocom/respawn-only.sh /usr/bin/sysmobts-mgr -n -c /etc/osmocom/sysmobts-mgr.cfg detach diff --git a/contrib/sysmobts-mgr.service b/contrib/sysmobts-mgr.service index 20adba0b..4a15bd8d 100644 --- a/contrib/sysmobts-mgr.service +++ b/contrib/sysmobts-mgr.service @@ -3,7 +3,7 @@ Description=sysmocom sysmoBTS manager [Service] Type=simple -ExecStart=/usr/bin/sysmobts-mgr -ns +ExecStart=/usr/bin/sysmobts-mgr -ns -c /etc/osmocom/sysmobts-mgr.cfg Restart=always RestartSec=2 diff --git a/doc/examples/sysmobts-mgr.cfg b/doc/examples/sysmobts-mgr.cfg new file mode 100644 index 00000000..3b28d785 --- /dev/null +++ b/doc/examples/sysmobts-mgr.cfg @@ -0,0 +1,24 @@ +! +! SysmoMgr (0.3.0.141-33e5) configuration saved from vty +!! +! +log stderr + logging filter all 1 + logging color 1 + logging timestamp 0 + logging level all everything + logging level temp info + logging level fw info + logging level find info + logging level lglobal notice + logging level llapd notice + logging level linp notice + logging level lmux notice + logging level lmi notice + logging level lmib notice + logging level lsms notice +! +line vty + no login +! +sysmobts-mgr diff --git a/src/osmo-bts-sysmo/Makefile.am b/src/osmo-bts-sysmo/Makefile.am index a213759e..fe318549 100644 --- a/src/osmo-bts-sysmo/Makefile.am +++ b/src/osmo-bts-sysmo/Makefile.am @@ -22,8 +22,10 @@ l1fwd_proxy_LDADD = $(top_builddir)/src/common/libbts.a $(COMMON_LDADD) sysmobts_mgr_SOURCES = \ misc/sysmobts_mgr.c misc/sysmobts_misc.c \ - misc/sysmobts_par.c misc/sysmobts_nl.c -sysmobts_mgr_LDADD = $(LIBOSMOCORE_LIBS) + misc/sysmobts_par.c misc/sysmobts_nl.c \ + misc/sysmobts_mgr_2050.c \ + misc/sysmobts_mgr_vty.c +sysmobts_mgr_LDADD = $(LIBOSMOCORE_LIBS) $(LIBOSMOVTY_LIBS) sysmobts_util_SOURCES = misc/sysmobts_util.c misc/sysmobts_par.c sysmobts_util_LDADD = $(LIBOSMOCORE_LIBS) diff --git a/src/osmo-bts-sysmo/misc/sysmobts_mgr.c b/src/osmo-bts-sysmo/misc/sysmobts_mgr.c index 41ee8143..2864ec9b 100644 --- a/src/osmo-bts-sysmo/misc/sysmobts_mgr.c +++ b/src/osmo-bts-sysmo/misc/sysmobts_mgr.c @@ -39,7 +39,6 @@ #include <osmocom/vty/telnet_interface.h> #include <osmocom/vty/logging.h> -#include "btsconfig.h" #include "misc/sysmobts_misc.h" #include "misc/sysmobts_mgr.h" #include "misc/sysmobts_nl.h" @@ -47,66 +46,9 @@ static int no_eeprom_write = 0; static int daemonize = 0; +static const char *cfgfile = "sysmobts-mgr.cfg"; void *tall_mgr_ctx; -/* every 6 hours means 365*4 = 1460 EEprom writes per year (max) */ -#define TEMP_TIMER_SECS (6 * 3600) - -/* every 1 hours means 365*24 = 8760 EEprom writes per year (max) */ -#define HOURS_TIMER_SECS (1 * 3600) - -#ifdef BUILD_SBTS2050 -static struct osmo_timer_list temp_uc_timer; -static void check_uctemp_timer_cb(void *data) -{ - int temp_pa = 0, temp_board = 0; - struct uc *ucontrol0 = data; - - sbts2050_uc_check_temp(ucontrol0, &temp_pa, &temp_board); - - osmo_timer_schedule(&temp_uc_timer, TEMP_TIMER_SECS, 0); -} -#endif - -static void initialize_sbts2050(void) -{ -#ifdef BUILD_SBTS2050 - static struct uc ucontrol0 = { - .id = 0, - .path = "/dev/ttyS0" - }; - int val; - - if (sysmobts_par_get_int(SYSMOBTS_PAR_MODEL_NR, &val) < 0) { - LOGP(DFIND, LOGL_ERROR, - "Failed to get Model number\n"); - return; - } - - if (val != 2050) - return; - - if (sysmobts_par_get_int(SYSMOBTS_PAR_TRX_NR, &val) < 0) { - LOGP(DFIND, LOGL_ERROR, "Failed to get the TRX number\n"); - return; - } - - if (val != 0) - return; - - ucontrol0.fd = osmo_serial_init(ucontrol0.path, 115200); - if (ucontrol0.fd < 0) { - LOGP(DFIND, LOGL_ERROR, - "Failed to open the serial interface\n"); - return; - } - - temp_uc_timer.cb = check_uctemp_timer_cb; - temp_uc_timer.data = &ucontrol0; - check_uctemp_timer_cb(&ucontrol0); -#endif -} - static struct osmo_timer_list temp_timer; static void check_temp_timer_cb(void *unused) { @@ -130,13 +72,14 @@ static void print_help(void) printf(" -s Disable color\n"); printf(" -d CAT enable debugging\n"); printf(" -D daemonize\n"); + printf(" -c Specify the filename of the config file\n"); } static int parse_options(int argc, char **argv) { int opt; - while ((opt = getopt(argc, argv, "nhsd:")) != -1) { + while ((opt = getopt(argc, argv, "nhsd:c:")) != -1) { switch (opt) { case 'n': no_eeprom_write = 1; @@ -153,6 +96,9 @@ static int parse_options(int argc, char **argv) case 'D': daemonize = 1; break; + case 'c': + cfgfile = optarg; + break; default: return -1; } @@ -386,6 +332,20 @@ int main(int argc, char **argv) if (rc < 0) exit(2); + sysmobts_mgr_vty_init(); + logging_vty_add_cmds(&mgr_log_info); + rc = sysmobts_mgr_parse_config(cfgfile); + if (rc < 0) { + LOGP(DFIND, LOGL_FATAL, "Cannot parse config file\n"); + exit(1); + } + + rc = telnet_init(tall_msgb_ctx, NULL, 4252); + if (rc < 0) { + fprintf(stderr, "Error initializing telnet\n"); + exit(1); + } + /* start temperature check timer */ temp_timer.cb = check_temp_timer_cb; check_temp_timer_cb(NULL); @@ -395,7 +355,7 @@ int main(int argc, char **argv) hours_timer_cb(NULL); /* start uc temperature check timer */ - initialize_sbts2050(); + sbts2050_uc_initialize(); /* handle broadcast messages for ipaccess-find */ fd.cb = ipaccess_bcast; diff --git a/src/osmo-bts-sysmo/misc/sysmobts_mgr.h b/src/osmo-bts-sysmo/misc/sysmobts_mgr.h index ddb6774a..aaa43736 100644 --- a/src/osmo-bts-sysmo/misc/sysmobts_mgr.h +++ b/src/osmo-bts-sysmo/misc/sysmobts_mgr.h @@ -1,10 +1,23 @@ #ifndef _SYSMOBTS_MGR_H #define _SYSMOBTS_MGR_H +#include <osmocom/vty/vty.h> +#include <osmocom/vty/command.h> + enum { DTEMP, DFW, DFIND, }; +enum mgr_vty_node { + MGR_NODE = _LAST_OSMOVTY_NODE + 1, +}; + +int sysmobts_mgr_vty_init(void); +int sysmobts_mgr_parse_config(const char *config_file); + +struct sysmobts_mgr_instance { + const char *config_file; +}; #endif diff --git a/src/osmo-bts-sysmo/misc/sysmobts_mgr_2050.c b/src/osmo-bts-sysmo/misc/sysmobts_mgr_2050.c new file mode 100644 index 00000000..e3cd104b --- /dev/null +++ b/src/osmo-bts-sysmo/misc/sysmobts_mgr_2050.c @@ -0,0 +1,349 @@ +/* (C) 2014 by s.f.m.c. GmbH + * + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + +#include "sysmobts_misc.h" +#include "sysmobts_par.h" +#include "sysmobts_mgr.h" +#include "btsconfig.h" + +#include <osmocom/core/logging.h> +#include <osmocom/core/msgb.h> +#include <osmocom/core/timer.h> + +#include <errno.h> +#include <unistd.h> + +#ifdef BUILD_SBTS2050 +#include <sysmocom/femtobts/sbts2050_header.h> + +#define SERIAL_ALLOC_SIZE 300 +#define SIZE_HEADER_RSP 5 +#define SIZE_HEADER_CMD 4 + +struct uc { + int id; + int fd; + const char *path; +}; + +struct ucinfo { + uint16_t id; + int master; + int slave; + int pa; +}; + +static struct uc ucontrol0 = { + .id = 0, + .path = "/dev/ttyS0" +}; + +/********************************************************************** + * Functions read/write from serial interface + *********************************************************************/ +static int hand_serial_read(int fd, struct msgb *msg, int numbytes) +{ + int rc, bread = 0; + + if (numbytes > msgb_tailroom(msg)) + return -ENOSPC; + + while (bread < numbytes) { + rc = read(fd, msg->tail, numbytes - bread); + if (rc < 0) + return -1; + if (rc == 0) + break; + + bread += rc; + msgb_put(msg, rc); + } + + return bread; +} + +static int hand_serial_write(int fd, struct msgb *msg) +{ + int rc, bwritten = 0; + + while (msg->len > 0) { + rc = write(fd, msg->data, msg->len); + if (rc <= 0) + return -1; + + msgb_pull(msg, rc); + bwritten += rc; + } + + return bwritten; +} + +/********************************************************************** + * Functions request information to Microcontroller + *********************************************************************/ +static void add_parity(cmdpkt_t *command) +{ + int n; + uint8_t parity = 0x00; + for (n = 0; n < SIZE_HEADER_CMD+command->u8Len; n++) + parity ^= ((uint8_t *)command)[n]; + + command->cmd.raw[command->u8Len] = parity; +} + +static struct msgb *sbts2050_ucinfo_get(struct uc *ucontrol, const struct ucinfo *info) +{ + int num, rc; + cmdpkt_t *command; + rsppkt_t *response; + struct msgb *msg; + fd_set fdread; + struct timeval tout = { + .tv_sec = 10, + }; + + switch (info->id) { + case SBTS2050_TEMP_RQT: + num = sizeof(command->cmd.tempGet); + break; + case SBTS2050_PWR_RQT: + num = sizeof(command->cmd.pwrSetState); + break; + case SBTS2050_PWR_STATUS: + num = sizeof(command->cmd.pwrGetStatus); + break; + default: + return NULL; + } + num = num + SIZE_HEADER_CMD+1; + + msg = msgb_alloc(SERIAL_ALLOC_SIZE, "Message Microcontroller"); + if (msg == NULL) { + LOGP(DTEMP, LOGL_ERROR, "Error creating msg\n"); + return NULL; + } + command = (cmdpkt_t *) msgb_put(msg, num); + + command->u16Magic = 0xCAFE; + switch (info->id) { + case SBTS2050_TEMP_RQT: + command->u8Id = info->id; + command->u8Len = sizeof(command->cmd.tempGet); + break; + case SBTS2050_PWR_RQT: + command->u8Id = info->id; + command->u8Len = sizeof(command->cmd.pwrSetState); + command->cmd.pwrSetState.u1MasterEn = !!info->master; + command->cmd.pwrSetState.u1SlaveEn = !!info->slave; + command->cmd.pwrSetState.u1PwrAmpEn = !!info->pa; + break; + case SBTS2050_PWR_STATUS: + command->u8Id = info->id; + command->u8Len = sizeof(command->cmd.pwrGetStatus); + break; + default: + goto err; + } + + add_parity(command); + + if (hand_serial_write(ucontrol->fd, msg) < 0) + goto err; + + msgb_reset(msg); + + FD_ZERO(&fdread); + FD_SET(ucontrol->fd, &fdread); + + num = SIZE_HEADER_RSP; + while (1) { + rc = select(ucontrol->fd+1, &fdread, NULL, NULL, &tout); + if (rc > 0) { + if (hand_serial_read(ucontrol->fd, msg, num) < 0) + goto err; + + response = (rsppkt_t *)msg->data; + + if (response->u8Id != info->id || msg->len <= 0 || + response->i8Error != RQT_SUCCESS) + goto err; + + if (msg->len == SIZE_HEADER_RSP + response->u8Len + 1) + break; + + num = response->u8Len + 1; + } else + goto err; + } + + return msg; + +err: + msgb_free(msg); + return NULL; +} + +/********************************************************************** + * Get power status function + *********************************************************************/ +int sbts2050_uc_get_status(enum sbts2050_status_rqt status) +{ + struct msgb *msg; + const struct ucinfo info = { + .id = SBTS2050_PWR_STATUS, + }; + rsppkt_t *response; + int val_status; + + msg = sbts2050_ucinfo_get(&ucontrol0, &info); + + if (msg == NULL) { + LOGP(DTEMP, LOGL_ERROR, + "Error requesting power status: %d\n", status); + return -1; + } + + response = (rsppkt_t *)msg->data; + + switch (status) { + case SBTS2050_STATUS_MASTER: + val_status = response->rsp.pwrGetStatus.u1MasterEn; + break; + case SBTS2050_STATUS_SLAVE: + val_status = response->rsp.pwrGetStatus.u1SlaveEn; + break; + case SBTS2050_STATUS_PA: + val_status = response->rsp.pwrGetStatus.u1PwrAmpEn; + break; + default: + msgb_free(msg); + return -1; + } + msgb_free(msg); + return val_status; +} + +/********************************************************************** + * Uc Power Switching handling + *********************************************************************/ +void sbts2050_uc_set_power(int pmaster, int pslave, int ppa) +{ + struct msgb *msg; + const struct ucinfo info = { + .id = SBTS2050_PWR_RQT, + .master = pmaster, + .slave = pslave, + .pa = ppa + }; + + msg = sbts2050_ucinfo_get(&ucontrol0, &info); + + if (msg == NULL) { + LOGP(DTEMP, LOGL_ERROR, "Error switching off some unit.\n"); + return; + } + + LOGP(DTEMP, LOGL_DEBUG, "Switch off/on success:\n" + "MASTER %s\n" + "SLAVE %s\n" + "PA %s\n", + pmaster ? "ON" : "OFF", + pslave ? "ON" : "OFF", + ppa ? "ON" : "OFF"); + + msgb_free(msg); +} + +/********************************************************************** + * Uc temperature handling + *********************************************************************/ +void sbts2050_uc_check_temp(int *temp_pa, int *temp_board) +{ + rsppkt_t *response; + struct msgb *msg; + const struct ucinfo info = { + .id = SBTS2050_TEMP_RQT, + }; + + msg = sbts2050_ucinfo_get(&ucontrol0, &info); + + if (msg == NULL) { + LOGP(DTEMP, LOGL_ERROR, "Error reading temperature\n"); + return; + } + + response = (rsppkt_t *)msg->data; + + *temp_board = response->rsp.tempGet.i8BrdTemp; + *temp_pa = response->rsp.tempGet.i8PaTemp; + + LOGP(DTEMP, LOGL_DEBUG, "Temperature Board: %+3d C\n" + "Tempeture PA: %+3d C\n", + response->rsp.tempGet.i8BrdTemp, + response->rsp.tempGet.i8PaTemp); + msgb_free(msg); +} + +static struct osmo_timer_list temp_uc_timer; +static void check_uctemp_timer_cb(void *data) +{ + int temp_pa = 0, temp_board = 0; + + sbts2050_uc_check_temp(&temp_pa, &temp_board); + + osmo_timer_schedule(&temp_uc_timer, TEMP_TIMER_SECS, 0); +} + +void sbts2050_uc_initialize(void) +{ + int val; + + if (sysmobts_par_get_int(SYSMOBTS_PAR_MODEL_NR, &val) < 0) { + LOGP(DTEMP, LOGL_ERROR, + "Failed to get Model number\n"); + return; + } + + if (val != 2050) + return; + + if (sysmobts_par_get_int(SYSMOBTS_PAR_TRX_NR, &val) < 0) { + LOGP(DTEMP, LOGL_ERROR, "Failed to get the TRX number\n"); + return; + } + + if (val != 0) + return; + + ucontrol0.fd = osmo_serial_init(ucontrol0.path, 115200); + if (ucontrol0.fd < 0) { + LOGP(DTEMP, LOGL_ERROR, + "Failed to open the serial interface\n"); + return; + } + + temp_uc_timer.cb = check_uctemp_timer_cb; + check_uctemp_timer_cb(NULL); +} +#else +void sbts2050_uc_initialize(void) +{ + LOGP(DTEMP, LOGL_NOTICE, "sysmoBTS2050 was not enabled at compile time.\n"); +} +#endif diff --git a/src/osmo-bts-sysmo/misc/sysmobts_mgr_vty.c b/src/osmo-bts-sysmo/misc/sysmobts_mgr_vty.c new file mode 100644 index 00000000..50d8e152 --- /dev/null +++ b/src/osmo-bts-sysmo/misc/sysmobts_mgr_vty.c @@ -0,0 +1,133 @@ +/* (C) 2014 by sysmocom - s.f.m.c. GmbH + * + * All Rights Reserved + * + * Author: Alvaro Neira Ayuso <anayuso@sysmocom.de> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + +#include <stdlib.h> +#include <unistd.h> +#include <errno.h> +#include <stdint.h> +#include <ctype.h> +#include <string.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> + +#include <osmocom/vty/vty.h> +#include <osmocom/vty/command.h> +#include <osmocom/vty/misc.h> + +#include <osmo-bts/logging.h> + +#include "sysmobts_misc.h" +#include "sysmobts_mgr.h" +#include "btsconfig.h" + +static const char copyright[] = + "(C) 2012 by Harald Welte <laforge@gnumonks.org>\r\n" + "(C) 2014 by Holger Hans Peter Freyther\r\n" + "License AGPLv3+: GNU AGPL version 2 or later <http://gnu.org/licenses/agpl-3.0.html>\r\n" + "This is free software: you are free to change and redistribute it.\r\n" + "There is NO WARRANTY, to the extent permitted by law.\r\n"; + +static enum node_type go_to_parent(struct vty *vty) +{ + switch (vty->node) { + case MGR_NODE: + vty->node = CONFIG_NODE; + break; + default: + vty->node = CONFIG_NODE; + } + return vty->node; +} + +static int is_config_node(struct vty *vty, int node) +{ + switch (node) { + case MGR_NODE: + return 1; + default: + return 0; + } +} + +static struct vty_app_info vty_info = { + .name = "sysmobts-mgr", + .version = PACKAGE_VERSION, + .go_parent_cb = go_to_parent, + .is_config_node = is_config_node, + .copyright = copyright, +}; + + +#define MGR_STR "Configure sysmobts-mgr\n" + +static struct cmd_node mgr_node = { + MGR_NODE, + "%s(sysmobts-mgr)# ", + 1, +}; + +DEFUN(cfg_mgr, cfg_mgr_cmd, + "sysmobts-mgr", + MGR_STR) +{ + vty->node = MGR_NODE; + return CMD_SUCCESS; +} + +DEFUN(show_mgr, show_mgr_cmd, "show manager", + SHOW_STR "Display information about the manager") +{ + return CMD_SUCCESS; +} + +static int config_write_mgr(struct vty *vty) +{ + vty_out(vty, "sysmobts-mgr%s", VTY_NEWLINE); + return CMD_SUCCESS; +} + +int sysmobts_mgr_vty_init(void) +{ + vty_init(&vty_info); + + install_element_ve(&show_mgr_cmd); + + install_node(&mgr_node, config_write_mgr); + install_element(CONFIG_NODE, &cfg_mgr_cmd); + vty_install_default(MGR_NODE); + + return 0; +} + +int sysmobts_mgr_parse_config(const char *config_file) +{ + int rc; + + rc = vty_read_config_file(config_file, NULL); + if (rc < 0) { + fprintf(stderr, "Failed to parse the config file: '%s'\n", + config_file); + return rc; + } + + return 0; +} diff --git a/src/osmo-bts-sysmo/misc/sysmobts_misc.c b/src/osmo-bts-sysmo/misc/sysmobts_misc.c index 9ea26c29..94f73857 100644 --- a/src/osmo-bts-sysmo/misc/sysmobts_misc.c +++ b/src/osmo-bts-sysmo/misc/sysmobts_misc.c @@ -46,266 +46,6 @@ #include <sysmocom/femtobts/sbts2050_header.h> #endif -#define SERIAL_ALLOC_SIZE 300 -#define SIZE_HEADER_RSP 5 -#define SIZE_HEADER_CMD 4 - - -#ifdef BUILD_SBTS2050 -/********************************************************************** - * Functions read/write from serial interface - *********************************************************************/ -static int hand_serial_read(int fd, struct msgb *msg, int numbytes) -{ - int rc, bread = 0; - - if (numbytes > msgb_tailroom(msg)) - return -ENOSPC; - - while (bread < numbytes) { - rc = read(fd, msg->tail, numbytes - bread); - if (rc < 0) - return -1; - if (rc == 0) - break; - - bread += rc; - msgb_put(msg, rc); - } - - return bread; -} - -static int hand_serial_write(int fd, struct msgb *msg) -{ - int rc, bwritten = 0; - - while (msg->len > 0) { - rc = write(fd, msg->data, msg->len); - if (rc <= 0) - return -1; - - msgb_pull(msg, rc); - bwritten += rc; - } - - return bwritten; -} - -/********************************************************************** - * Functions request information to Microcontroller - *********************************************************************/ -static void add_parity(cmdpkt_t *command) -{ - int n; - uint8_t parity = 0x00; - for (n = 0; n < SIZE_HEADER_CMD+command->u8Len; n++) - parity ^= ((uint8_t *)command)[n]; - - command->cmd.raw[command->u8Len] = parity; -} - -static struct msgb *sbts2050_ucinfo_get(struct uc *ucontrol, struct ucinfo info) -{ - int num, rc; - cmdpkt_t *command; - rsppkt_t *response; - struct msgb *msg; - fd_set fdread; - struct timeval tout = { - .tv_sec = 10, - }; - - switch (info.id) { - case SBTS2050_TEMP_RQT: - num = sizeof(command->cmd.tempGet); - break; - case SBTS2050_PWR_RQT: - num = sizeof(command->cmd.pwrSetState); - break; - case SBTS2050_PWR_STATUS: - num = sizeof(command->cmd.pwrGetStatus); - break; - default: - return NULL; - } - num = num + SIZE_HEADER_CMD+1; - - msg = msgb_alloc(SERIAL_ALLOC_SIZE, "Message Microcontroller"); - if (msg == NULL) { - LOGP(DTEMP, LOGL_ERROR, "Error creating msg\n"); - return NULL; - } - command = (cmdpkt_t *) msgb_put(msg, num); - - command->u16Magic = 0xCAFE; - switch (info.id) { - case SBTS2050_TEMP_RQT: - command->u8Id = info.id; - command->u8Len = sizeof(command->cmd.tempGet); - break; - case SBTS2050_PWR_RQT: - command->u8Id = info.id; - command->u8Len = sizeof(command->cmd.pwrSetState); - command->cmd.pwrSetState.u1MasterEn = !!info.master; - command->cmd.pwrSetState.u1SlaveEn = !!info.slave; - command->cmd.pwrSetState.u1PwrAmpEn = !!info.pa; - break; - case SBTS2050_PWR_STATUS: - command->u8Id = info.id; - command->u8Len = sizeof(command->cmd.pwrGetStatus); - break; - default: - goto err; - } - - add_parity(command); - - if (hand_serial_write(ucontrol->fd, msg) < 0) - goto err; - - msgb_reset(msg); - - FD_ZERO(&fdread); - FD_SET(ucontrol->fd, &fdread); - - num = SIZE_HEADER_RSP; - while (1) { - rc = select(ucontrol->fd+1, &fdread, NULL, NULL, &tout); - if (rc > 0) { - if (hand_serial_read(ucontrol->fd, msg, num) < 0) - goto err; - - response = (rsppkt_t *)msg->data; - - if (response->u8Id != info.id || msg->len <= 0 || - response->i8Error != RQT_SUCCESS) - goto err; - - if (msg->len == SIZE_HEADER_RSP + response->u8Len + 1) - break; - - num = response->u8Len + 1; - } else - goto err; - } - - return msg; - -err: - msgb_free(msg); - return NULL; -} -#endif - -/********************************************************************** - * Get power status function - *********************************************************************/ -int sbts2050_uc_status(struct uc *ucontrol, enum sbts2050_status_rqt status) -{ -#ifdef BUILD_SBTS2050 - struct msgb *msg; - struct ucinfo info = { - .id = SBTS2050_PWR_STATUS, - }; - rsppkt_t *response; - int val_status; - - msg = sbts2050_ucinfo_get(ucontrol, info); - - if (msg == NULL) { - LOGP(DTEMP, LOGL_ERROR, "Error switching off some unit"); - return -1; - } - - response = (rsppkt_t *)msg->data; - - switch (status) { - case SBTS2050_STATUS_MASTER: - val_status = response->rsp.pwrGetStatus.u1MasterEn; - break; - case SBTS2050_STATUS_SLAVE: - val_status = response->rsp.pwrGetStatus.u1SlaveEn; - break; - case SBTS2050_STATUS_PA: - val_status = response->rsp.pwrGetStatus.u1PwrAmpEn; - break; - default: - msgb_free(msg); - return -1; - } - msgb_free(msg); - return val_status; -#else - return -1; -#endif -} - -/********************************************************************** - * Uc Power Switching handling - *********************************************************************/ -void sbts2050_uc_power(struct uc *ucontrol, int pmaster, int pslave, int ppa) -{ -#ifdef BUILD_SBTS2050 - struct msgb *msg; - struct ucinfo info = { - .id = 0x00, - .master = pmaster, - .slave = pslave, - .pa = ppa - }; - - msg = sbts2050_ucinfo_get(ucontrol, info); - - if (msg == NULL) { - LOGP(DTEMP, LOGL_ERROR, "Error switching off some unit"); - return; - } - - LOGP(DTEMP, LOGL_DEBUG, "Switch off/on success:\n" - "MASTER %s\n" - "SLAVE %s\n" - "PA %s\n", - pmaster ? "ON" : "OFF", - pslave ? "ON" : "OFF", - ppa ? "ON" : "OFF"); - - msgb_free(msg); -#endif -} - -/********************************************************************** - * Uc temperature handling - *********************************************************************/ -void sbts2050_uc_check_temp(struct uc *ucontrol, int *temp_pa, int *temp_board) -{ -#ifdef BUILD_SBTS2050 - rsppkt_t *response; - struct msgb *msg; - struct ucinfo info = { - .id = SBTS2050_TEMP_RQT, - }; - - msg = sbts2050_ucinfo_get(ucontrol, info); - - if (msg == NULL) { - LOGP(DTEMP, LOGL_ERROR, "Error reading temperature\n"); - return; - } - - response = (rsppkt_t *)msg->data; - - *temp_board = response->rsp.tempGet.i8BrdTemp; - *temp_pa = response->rsp.tempGet.i8PaTemp; - - LOGP(DTEMP, LOGL_DEBUG, "Temperature Board: %+3d C\n" - "Tempeture PA: %+3d C\n", - response->rsp.tempGet.i8BrdTemp, - response->rsp.tempGet.i8PaTemp); - msgb_free(msg); -#endif -} - /********************************************************************* * Temperature handling *********************************************************************/ diff --git a/src/osmo-bts-sysmo/misc/sysmobts_misc.h b/src/osmo-bts-sysmo/misc/sysmobts_misc.h index 01878f24..f3b85c2c 100644 --- a/src/osmo-bts-sysmo/misc/sysmobts_misc.h +++ b/src/osmo-bts-sysmo/misc/sysmobts_misc.h @@ -1,6 +1,14 @@ #ifndef _SYSMOBTS_MISC_H #define _SYSMOBTS_MISC_H +#include <stdint.h> + +/* every 6 hours means 365*4 = 1460 EEprom writes per year (max) */ +#define TEMP_TIMER_SECS (6 * 3600) + +/* every 1 hours means 365*24 = 8760 EEprom writes per year (max) */ +#define HOURS_TIMER_SECS (1 * 3600) + enum sysmobts_temp_sensor { SYSMOBTS_TEMP_DIGITAL = 1, SYSMOBTS_TEMP_RF = 2, @@ -19,30 +27,11 @@ enum sbts2050_status_rqt { SBTS2050_STATUS_PA }; -struct uc { - int id; - int fd; - const char *path; -}; - -struct ucinfo { - uint16_t id; - int master; - int slave; - int pa; -}; - int sysmobts_temp_get(enum sysmobts_temp_sensor sensor, enum sysmobts_temp_type type); void sysmobts_check_temp(int no_eeprom_write); -void sbts2050_uc_check_temp(struct uc *ucontrol, int *temp_pa, int *temp_board); - -void sbts2050_uc_power(struct uc *ucontrol, int pmaster, int pslave, int ppa); - -int sbts2050_uc_status(struct uc *ucontrol, enum sbts2050_status_rqt status); - int sysmobts_update_hours(int no_epprom_write); enum sysmobts_firmware_type { @@ -53,4 +42,10 @@ enum sysmobts_firmware_type { int sysmobts_firmware_reload(enum sysmobts_firmware_type type); + +void sbts2050_uc_check_temp(int *temp_pa, int *temp_board); +void sbts2050_uc_set_power(int pmaster, int pslave, int ppa); +int sbts2050_uc_get_status(enum sbts2050_status_rqt status); +void sbts2050_uc_initialize(); + #endif |