aboutsummaryrefslogtreecommitdiffstats
path: root/src/osmo-bts-sysmo
diff options
context:
space:
mode:
authorHolger Hans Peter Freyther <holger@moiji-mobile.com>2014-08-21 15:49:55 +0200
committerHolger Hans Peter Freyther <holger@moiji-mobile.com>2014-08-21 15:50:40 +0200
commitffe1d2e1e0bc99debf5cc826c43632680d969825 (patch)
tree6b052239de319a45616286fa403c35aac61b224e /src/osmo-bts-sysmo
parent07198750b29fa891dd6c1d6266964691aa9e9095 (diff)
parent575f633483d09e5d6666aed4d7e132614c2e1847 (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.
Diffstat (limited to 'src/osmo-bts-sysmo')
-rw-r--r--src/osmo-bts-sysmo/Makefile.am6
-rw-r--r--src/osmo-bts-sysmo/misc/sysmobts_mgr.c82
-rw-r--r--src/osmo-bts-sysmo/misc/sysmobts_mgr.h13
-rw-r--r--src/osmo-bts-sysmo/misc/sysmobts_mgr_2050.c349
-rw-r--r--src/osmo-bts-sysmo/misc/sysmobts_mgr_vty.c133
-rw-r--r--src/osmo-bts-sysmo/misc/sysmobts_misc.c260
-rw-r--r--src/osmo-bts-sysmo/misc/sysmobts_misc.h33
7 files changed, 534 insertions, 342 deletions
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