From 035187b44ea12d0ff551973517c2525d0a8cf068 Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Thu, 31 Jul 2014 19:19:42 +0200 Subject: sysmobts: Move the sysmoBTS 2050 controller handling Move the code to a separate file to keep things nicely apart of each other. --- src/osmo-bts-sysmo/Makefile.am | 1 + src/osmo-bts-sysmo/misc/sysmobts_mgr_2050.c | 283 ++++++++++++++++++++++++++++ src/osmo-bts-sysmo/misc/sysmobts_misc.c | 260 ------------------------- src/osmo-bts-sysmo/misc/sysmobts_misc.h | 2 + 4 files changed, 286 insertions(+), 260 deletions(-) create mode 100644 src/osmo-bts-sysmo/misc/sysmobts_mgr_2050.c diff --git a/src/osmo-bts-sysmo/Makefile.am b/src/osmo-bts-sysmo/Makefile.am index 0071e136..fe318549 100644 --- a/src/osmo-bts-sysmo/Makefile.am +++ b/src/osmo-bts-sysmo/Makefile.am @@ -23,6 +23,7 @@ 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 \ + misc/sysmobts_mgr_2050.c \ misc/sysmobts_mgr_vty.c sysmobts_mgr_LDADD = $(LIBOSMOCORE_LIBS) $(LIBOSMOVTY_LIBS) 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..c772b531 --- /dev/null +++ b/src/osmo-bts-sysmo/misc/sysmobts_mgr_2050.c @@ -0,0 +1,283 @@ +/* (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 . + * + */ + +#include "sysmobts_misc.h" +#include "sysmobts_par.h" +#include "sysmobts_mgr.h" +#include "btsconfig.h" + +#include +#include + +#include +#include + +#ifdef BUILD_SBTS2050 +#include + +#define SERIAL_ALLOC_SIZE 300 +#define SIZE_HEADER_RSP 5 +#define SIZE_HEADER_CMD 4 + + +/********************************************************************** + * 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; +} + +/********************************************************************** + * Get power status function + *********************************************************************/ +int sbts2050_uc_status(struct uc *ucontrol, enum sbts2050_status_rqt status) +{ + 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; +} + +/********************************************************************** + * Uc Power Switching handling + *********************************************************************/ +void sbts2050_uc_power(struct uc *ucontrol, int pmaster, int pslave, int ppa) +{ + 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); +} + +/********************************************************************** + * Uc temperature handling + *********************************************************************/ +void sbts2050_uc_check_temp(struct uc *ucontrol, int *temp_pa, int *temp_board) +{ + 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 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 #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..dc576399 100644 --- a/src/osmo-bts-sysmo/misc/sysmobts_misc.h +++ b/src/osmo-bts-sysmo/misc/sysmobts_misc.h @@ -1,6 +1,8 @@ #ifndef _SYSMOBTS_MISC_H #define _SYSMOBTS_MISC_H +#include + enum sysmobts_temp_sensor { SYSMOBTS_TEMP_DIGITAL = 1, SYSMOBTS_TEMP_RF = 2, -- cgit v1.2.3