From patchwork Sat May 17 09:01:13 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Alvaro Neira X-Patchwork-Id: 349860 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from ganesha.gnumonks.org (ganesha.gnumonks.org [IPv6:2001:780:45:1d:225:90ff:fe52:c662]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 8A8CF14007B for ; Sat, 17 May 2014 19:03:15 +1000 (EST) Received: from localhost ([127.0.0.1] helo=ganesha.gnumonks.org) by ganesha.gnumonks.org with esmtp (Exim 4.72) (envelope-from ) id 1WlaWJ-0006Ay-LE; Sat, 17 May 2014 11:03:07 +0200 Received: from mail.sysmocom.de ([2a01:4f8:191:444c::2:4]) by ganesha.gnumonks.org with esmtp (Exim 4.72) (envelope-from ) id 1WlaW1-0006Aq-Mg for openbsc@lists.osmocom.org; Sat, 17 May 2014 11:02:53 +0200 Received: from localhost.localdomain (tmo-097-12.customers.d1-online.com [80.187.97.12]) by mail.sysmocom.de (Postfix) with ESMTPA id BC2EB5839B; Sat, 17 May 2014 09:02:48 +0000 (UTC) From: Alvaro Neira Ayuso To: openbsc@lists.osmocom.org Subject: [osmo-bts PATCH 3/3 v9] sysmobts: Add support for changing the transmit power in sbts2050 Date: Sat, 17 May 2014 11:01:13 +0200 Message-Id: <1400317273-24414-1-git-send-email-anayuso@sysmocom.de> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <1399299779-15739-1-git-send-email-anayuso@sysmocom.de> References: <1399299779-15739-1-git-send-email-anayuso@sysmocom.de> MIME-Version: 1.0 X-Spam-Score: 0.8 (/) X-Spam-Report: SpamASsassin versoin 3.3.1 on ganesha.gnumonks.org summary: Content analysis details: (0.8 points, 5.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- 0.6 RCVD_IN_SORBS_WEB RBL: SORBS: sender is an abusable web server [80.187.97.12 listed in dnsbl.sorbs.net] 0.1 TW_TR BODY: Odd Letter Triples with TR 0.1 TW_SB BODY: Odd Letter Triples with SB Cc: hwelte@sysmocom.de, hfreyther@sysmocom.de X-BeenThere: openbsc@lists.osmocom.org X-Mailman-Version: 2.1.13 Precedence: list List-Id: Development of the OpenBSC GSM base station controller List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: openbsc-bounces@lists.osmocom.org Errors-To: openbsc-bounces@lists.osmocom.org From: Álvaro Neira Ayuso Make the sysmobts-mgr sends a manufacturer O&M message with the relative value that we want to reduce in the sysmobts. The sysmobts receives this messages. Messages passing a sanity check takes the relative value that we want to reduce and the sysmobts reduces the transmit power. The sysmobts-mgr receives a ACK/NACK for knowing that the transmit power has been updated. Signed-off-by: Alvaro Neira Ayuso --- [changes in v9] * Removed the code for adding the manufacturer ID label and used the new function inside utils. * Removed leak when we send the ack/nack when we receive the reduce manufacturer O&M message and it has passed a sanity check. * Moved the code when we check if the PA or the Board is under a temperature warning situation and when we send the relative value that we want to use for reduce the transmit power to a new function for make easy future changes. * Changed some log messages for adding more util information for debugging. src/osmo-bts-sysmo/main.c | 122 ++++++++++++++++++++++++++++++- src/osmo-bts-sysmo/misc/sysmobts_mgr.c | 41 ++++++++--- src/osmo-bts-sysmo/misc/sysmobts_mgr.h | 5 ++ src/osmo-bts-sysmo/misc/sysmobts_misc.c | 72 ++++++++++++++++++ src/osmo-bts-sysmo/misc/sysmobts_misc.h | 2 + 5 files changed, 231 insertions(+), 11 deletions(-) diff --git a/src/osmo-bts-sysmo/main.c b/src/osmo-bts-sysmo/main.c index bd6a181..2c13a9c 100644 --- a/src/osmo-bts-sysmo/main.c +++ b/src/osmo-bts-sysmo/main.c @@ -39,6 +39,7 @@ #include #include #include +#include #include #include @@ -294,10 +295,106 @@ static int write_pid_file(char *procname) return 0; } +#define oml_tlv_parse(dec, buf, len) \ + tlv_parse(dec, &abis_nm_att_tlvdef, buf, len, 0, 0) + +static int send_oml_fom_ack_nack(int fd_unix, struct msgb *old_msg, + uint8_t cause, int is_manuf) +{ + struct abis_om_hdr *old_om = msgb_l2(old_msg); + struct abis_om_fom_hdr *old_foh = msgb_l3(old_msg); + struct msgb *msg; + struct abis_om_fom_hdr *foh; + struct abis_om_hdr *om; + int rc; + + msg = oml_msgb_alloc(); + if (!msg) + return -ENOMEM; + + msg->l3h = msgb_push(msg, sizeof(*foh)); + foh = (struct abis_om_fom_hdr *) msg->l3h; + memcpy(foh, old_foh, sizeof(*foh)); + + if (is_manuf) + add_manufacturer_id_label(msg, OSMOCOM_MANUF_ID); + + msg->l2h = msgb_push(msg, sizeof(*om)); + om = (struct abis_om_hdr *) msg->l2h; + memcpy(om, old_om, sizeof(*om)); + + /* alter message type */ + if (cause) { + LOGP(DOML, LOGL_ERROR, "Sending FOM NACK with cause %s.\n", + abis_nm_nack_cause_name(cause)); + foh->msg_type += 2; /* nack */ + msgb_tv_put(msg, NM_ATT_NACK_CAUSES, cause); + } else { + LOGP(DOML, LOGL_DEBUG, "Sending FOM ACK.\n"); + foh->msg_type++; /* ack */ + } + + prepend_oml_ipa_header(msg); + + rc = send(fd_unix, msg->data, msg->len, 0); + if (rc < 0 || rc != msg->len) { + LOGP(DTEMP, LOGL_ERROR, + "send error %s during ACK/NACK message send\n", + strerror(errno)); + close(fd_unix); + msgb_free(msg); + return -1; + } + + msgb_free(msg); + return rc; +} + +static void update_transmiter_power(struct gsm_bts_trx *trx) +{ + struct femtol1_hdl *fl1h = trx_femtol1_hdl(trx); + + if (fl1h->hLayer1) + l1if_set_txpower(fl1h, sysmobts_get_power_trx(trx)); +} + +static int take_reduce_power(struct msgb *msg) +{ + int recv_reduce_power; + struct tlv_parsed tlv_out; + struct gsm_bts_trx *trx = bts->c0; + int rc, abis_oml_hdr_len; + + abis_oml_hdr_len = sizeof(struct abis_om_hdr); + abis_oml_hdr_len += sizeof(struct abis_om_fom_hdr); + abis_oml_hdr_len += sizeof(osmocom_magic) + 1; + + rc = oml_tlv_parse(&tlv_out, msg->data + abis_oml_hdr_len, + msg->len - abis_oml_hdr_len); + + if (rc < 0) { + msgb_free(msg); + return -1; + } + + if (TLVP_PRESENT(&tlv_out, NM_ATT_O_REDUCEPOWER)) + recv_reduce_power = *TLVP_VAL(&tlv_out, + NM_ATT_O_REDUCEPOWER); + else + return -1; + + trx->power_reduce = recv_reduce_power; + + update_transmiter_power(trx); + + return 0; +} + static int read_sock(struct osmo_fd *fd, unsigned int what) { struct msgb *msg; struct gsm_abis_mo *mo; + struct abis_om_fom_hdr *fom; int rc; msg = oml_msgb_alloc(); @@ -324,9 +421,32 @@ static int read_sock(struct osmo_fd *fd, unsigned int what) mo = &bts->mo; msg->trx = mo->bts->c0; + fom = (struct abis_om_fom_hdr *) msg->l3h; - return abis_oml_sendmsg(msg); + switch (fom->msg_type) { + case NM_MT_SET_RADIO_ATTR: + rc = take_reduce_power(msg); + if (rc < 0) { + rc = send_oml_fom_ack_nack(fd->fd, msg, + NM_NACK_INCORR_STRUCT, 1); + } else { + rc = send_oml_fom_ack_nack(fd->fd, msg, 0, 1); + } + msgb_free(msg); + break; + case NM_MT_FAILURE_EVENT_REP: + rc = abis_oml_sendmsg(msg); + break; + default: + LOGP(DL1C, LOGL_ERROR, "Unknown Fom message type %d\n", + fom->msg_type); + goto err; + } + if (rc < 0) + goto err; + + return rc; err: msgb_free(msg); return -1; diff --git a/src/osmo-bts-sysmo/misc/sysmobts_mgr.c b/src/osmo-bts-sysmo/misc/sysmobts_mgr.c index e45d41f..4aa2cbf 100644 --- a/src/osmo-bts-sysmo/misc/sysmobts_mgr.c +++ b/src/osmo-bts-sysmo/misc/sysmobts_mgr.c @@ -82,6 +82,7 @@ static struct vty_app_info vty_info = { static int fd_unix = -1; static int trx_nr = -1; static int state_connection; +static int status_change_power_red; static struct osmo_timer_list temp_uc_timer; static struct osmo_timer_list connect_timer; @@ -135,21 +136,39 @@ static int check_temperature(struct uc *ucontrol0, int lowlimit, int highlimit, return 1; } +static int check_warning_state(int pa_warning, int board_warning) +{ + if ((pa_warning || board_warning) && + status_change_power_red == SBTS2050_DISABLE_CHANGE_POWER) { + status_change_power_red = SBTS2050_ENABLE_CHANGE_POWER; + send_manufacturer_reduce_msg(fd_unix, confinfo.reduce_max_power, + trx_nr); + } else if (!pa_warning && !board_warning && + status_change_power_red == SBTS2050_ENABLE_CHANGE_POWER) { + status_change_power_red = SBTS2050_DISABLE_CHANGE_POWER; + send_manufacturer_reduce_msg(fd_unix, 0, trx_nr); + } else + return -1; + + return 0; +} + static void check_uctemp_timer_cb(void *data) { int temp_pa = 0, temp_board = 0; struct uc *ucontrol0 = data; + int pa_warning, board_warning; sbts2050_uc_check_temp(ucontrol0, &temp_pa, &temp_board); confinfo.temp_pa_cur = temp_pa; confinfo.temp_board_cur = temp_board; - check_temperature(ucontrol0, - confinfo.temp_min_pa_warn_limit, - confinfo.temp_max_pa_warn_limit, - temp_pa, SBTS2050_TEMP_PA, - SBTS2050_WARN_ALERT); + pa_warning = check_temperature(ucontrol0, + confinfo.temp_min_pa_warn_limit, + confinfo.temp_max_pa_warn_limit, + temp_pa, SBTS2050_TEMP_PA, + SBTS2050_WARN_ALERT); check_temperature(ucontrol0, confinfo.temp_min_pa_severe_limit, @@ -157,11 +176,11 @@ static void check_uctemp_timer_cb(void *data) temp_pa, SBTS2050_TEMP_PA, SBTS2050_SEVERE_ALERT); - check_temperature(ucontrol0, - confinfo.temp_min_board_warn_limit, - confinfo.temp_max_board_warn_limit, - temp_board, SBTS2050_TEMP_BOARD, - SBTS2050_WARN_ALERT); + board_warning = check_temperature(ucontrol0, + confinfo.temp_min_board_warn_limit, + confinfo.temp_max_board_warn_limit, + temp_board, SBTS2050_TEMP_BOARD, + SBTS2050_WARN_ALERT); check_temperature(ucontrol0, confinfo.temp_min_board_severe_limit, @@ -169,6 +188,8 @@ static void check_uctemp_timer_cb(void *data) temp_board, SBTS2050_TEMP_BOARD, SBTS2050_SEVERE_ALERT); + check_warning_state(pa_warning, board_warning); + osmo_timer_schedule(&temp_uc_timer, TEMP_TIMER_SECS, 0); } #endif diff --git a/src/osmo-bts-sysmo/misc/sysmobts_mgr.h b/src/osmo-bts-sysmo/misc/sysmobts_mgr.h index 5e0d4a7..026afd5 100644 --- a/src/osmo-bts-sysmo/misc/sysmobts_mgr.h +++ b/src/osmo-bts-sysmo/misc/sysmobts_mgr.h @@ -15,6 +15,11 @@ enum { SYSMO_MGR_CONNECTED, }; +enum { + SBTS2050_DISABLE_CHANGE_POWER = 0, + SBTS2050_ENABLE_CHANGE_POWER, +}; + #define SOCKET_PATH "/var/run/bts_oml" struct sbts2050_config_info; diff --git a/src/osmo-bts-sysmo/misc/sysmobts_misc.c b/src/osmo-bts-sysmo/misc/sysmobts_misc.c index 2417c3d..6277a6b 100644 --- a/src/osmo-bts-sysmo/misc/sysmobts_misc.c +++ b/src/osmo-bts-sysmo/misc/sysmobts_misc.c @@ -58,6 +58,23 @@ #define OM_HEADROOM_SIZE 128 #ifdef BUILD_SBTS2050 + +static int check_manufacturer_reduce_nach_ack(struct msgb *msg) +{ + struct abis_om_fom_hdr *foh = msgb_l3(msg); + + if (foh->msg_type == NM_MT_SET_RADIO_ATTR + 2) { /* NACK */ + LOGP(DTEMP, LOGL_ERROR, "Reduce Power: Received a BTS NACK\n"); + return -1; + } else if (foh->msg_type != NM_MT_SET_RADIO_ATTR + 1) { /* ACK */ + LOGP(DTEMP, LOGL_ERROR, "Unknown message type %d\n", + foh->msg_type); + return -1; + } + + return 0; +} + static void add_sw_descr(struct msgb *msg) { char file_version[255]; @@ -112,6 +129,61 @@ static void add_oml_hdr_msg(struct msgb *msg, uint8_t msg_type, omh->length = msgb_l3len(msg); } +int send_manufacturer_reduce_msg(int fd_unix, int reduce_power, int trx_nr) +{ + int rc; + struct msgb *msg; + + msg = msgb_alloc_headroom(OM_ALLOC_SIZE, OM_HEADROOM_SIZE, "OML"); + if (msg == NULL) { + LOGP(DTEMP, LOGL_ERROR, "Error creating oml msg\n"); + return -1; + } + + add_oml_hdr_msg(msg, NM_MT_SET_RADIO_ATTR, 2, 0, trx_nr, 255, 1); + + msgb_tv_put(msg, NM_ATT_O_REDUCEPOWER, reduce_power); + + prepend_oml_ipa_header(msg); + + rc = send(fd_unix, msg->data, msg->len, 0); + if (rc < 0 || rc != msg->len) { + LOGP(DTEMP, LOGL_ERROR, + "send error %s during Reduce Manufacturer O&M msg send\n", + strerror(errno)); + goto err; + } + + msgb_reset(msg); + rc = recv(fd_unix, msg->tail, msg->data_len, 0); + if (rc <= 0) { + LOGP(DTEMP, LOGL_ERROR, "recv error %s during ACK/NACK recv\n", + strerror(errno)); + goto err; + } + msgb_put(msg, rc); + + if (check_oml_msg(msg) < 0) { + close(fd_unix); + msgb_free(msg); + return -1; + } + + if (check_manufacturer_reduce_nach_ack(msg) < 0) { + close(fd_unix); + msgb_free(msg); + return -1; + } + + msgb_free(msg); + return SYSMO_MGR_CONNECTED; + +err: + close(fd_unix); + msgb_free(msg); + return SYSMO_MGR_DISCONNECTED; +} + int send_omlfailure(int fd_unix, enum sbts2050_alert_lvl alert, enum sbts2050_temp_sensor sensor, struct sbts2050_config_info *add_info, int trx_nr) diff --git a/src/osmo-bts-sysmo/misc/sysmobts_misc.h b/src/osmo-bts-sysmo/misc/sysmobts_misc.h index c22a54b..740ce2d 100644 --- a/src/osmo-bts-sysmo/misc/sysmobts_misc.h +++ b/src/osmo-bts-sysmo/misc/sysmobts_misc.h @@ -75,6 +75,8 @@ int send_omlfailure(int fd_unix, enum sbts2050_alert_lvl alert, enum sbts2050_temp_sensor sensor, struct sbts2050_config_info *add_info, int trx_nr); +int send_manufacturer_reduce_msg(int fd_unix, int reduce_power, int trx_nr); + int sysmobts_update_hours(int no_epprom_write); enum sysmobts_firmware_type {