[osmo-bts,5/5,v10] main: Added support for changing the max_power_red in sbts2050
diff mbox

Message ID 1400565048-11164-1-git-send-email-anayuso@sysmocom.de
State Changes Requested
Headers show

Commit Message

Alvaro Neira May 20, 2014, 5:50 a.m. UTC
From: Álvaro Neira Ayuso <anayuso@sysmocom.de>

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 <anayuso@sysmocom.de>
---
[changes in v10]
* Changed the variable NM_ATT_O_REDUCEPOWER to NM_ATT_OSMO_REDUCEPOWER.
* Changed abis_nm_att_tlvdef to abis_nm_osmo_att_tlvdef for parsing the
  the osmocom attributes
* Changed the function take_reduce_power for using abis_om_fom_hdr and the len
  of the l3h and not the message.
* Checked if the message that we have checked is the type that we expect.
* Used the new function for doing the sanity check to the ipa header and
  later the oml message

 src/osmo-bts-sysmo/main.c               |  128 ++++++++++++++++++++++++++++++-
 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 |   80 +++++++++++++++++++
 src/osmo-bts-sysmo/misc/sysmobts_misc.h |    2 +
 5 files changed, 245 insertions(+), 11 deletions(-)

Comments

Holger Freyther May 20, 2014, 7:05 a.m. UTC | #1
On Tue, May 20, 2014 at 07:50:48AM +0200, Alvaro Neira Ayuso wrote:
> From: Álvaro Neira Ayuso <anayuso@sysmocom.de>
> 
> 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.

Where is this coming from? I think it is an old/partially
updated patch?
Alvaro Neira May 20, 2014, 7:40 a.m. UTC | #2
Hello Holger

El 20/05/14 09:05, Holger Hans Peter Freyther escribió:
> On Tue, May 20, 2014 at 07:50:48AM +0200, Alvaro Neira Ayuso wrote:
>> From: Álvaro Neira Ayuso <anayuso@sysmocom.de>
>>
>> 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.
>
> Where is this coming from? I think it is an old/partially
> updated patch?

Yes, this is a old/partially updated patch with the new functions that I 
have done in utils and using the new variable of the patch 
430c771244ae37d7cd95960fc1781ed6aeed1213, Fix introducing osmocom 
speficic OML attributes. That patch was reverted for updating it.

Regards

Álvaro
Holger Freyther May 20, 2014, 7:52 a.m. UTC | #3
On Tue, May 20, 2014 at 09:40:35AM +0200, Álvaro Neira Ayuso wrote:

Hi,

> Yes, this is a old/partially updated patch with the new functions that I
> have done in utils and using the new variable of the patch
> 430c771244ae37d7cd95960fc1781ed6aeed1213, Fix introducing osmocom speficic
> OML attributes. That patch was reverted for updating it.

ah right. Harald reverted the patch. I didn't notice that yesterday.
Holger Freyther May 20, 2014, 8:05 a.m. UTC | #4
On Tue, May 20, 2014 at 07:50:48AM +0200, Alvaro Neira Ayuso wrote:

> +static int send_oml_fom_ack_nack(int fd_unix, struct msgb *old_msg,
> +				 uint8_t cause, int is_manuf)
> +{

Separate this method into several ones.

* You have modeled oml_fom_ack_nack and instead of copying it you
  should extend oml_fom_ack_nack to support your use case. The
  differences are:

  ** Support com.ipacces and org.osmocom manufacturer type
  ** Be able to send the message through a different socket.

The first can be achieved by modifying the parameter in oml_send_msg
to get the manufacturer name that can be put. E.g. by having the
cstring.

The later can be done by separating message creation and sending.
Please do the re-work like this. And create seaprate patches for
the refactoring.

> +static int take_reduce_power(struct abis_om_fom_hdr *fom, int len)
> +{

> +	rc = oml_tlv_parse(&tlv_out, fom->data,
> +			   len - sizeof(struct abis_om_fom_hdr));

			plese use sizeof(*fom)

P

Patch
diff mbox

diff --git a/src/osmo-bts-sysmo/main.c b/src/osmo-bts-sysmo/main.c
index 797f174..ec3ea78 100644
--- a/src/osmo-bts-sysmo/main.c
+++ b/src/osmo-bts-sysmo/main.c
@@ -39,6 +39,7 @@ 
 #include <osmocom/vty/telnet_interface.h>
 #include <osmocom/vty/logging.h>
 #include <osmocom/gsm/protocol/ipaccess.h>
+#include <osmocom/gsm/abis_nm.h>
 
 #include <osmo-bts/gsm_data.h>
 #include <osmo-bts/logging.h>
@@ -294,10 +295,100 @@  static int write_pid_file(char *procname)
 	return 0;
 }
 
+#define oml_tlv_parse(dec, buf, len)	\
+	tlv_parse(dec, &abis_nm_osmo_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 abis_om_fom_hdr *fom, int len)
+{
+	int recv_reduce_power;
+	struct tlv_parsed tlv_out;
+	struct gsm_bts_trx *trx = bts->c0;
+	int rc;
+
+	rc = oml_tlv_parse(&tlv_out, fom->data,
+			   len - sizeof(struct abis_om_fom_hdr));
+
+	if (rc < 0)
+		return -1;
+
+	if (TLVP_PRESENT(&tlv_out, NM_ATT_OSMO_REDUCEPOWER))
+		recv_reduce_power = *TLVP_VAL(&tlv_out,
+					      NM_ATT_OSMO_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();
@@ -333,9 +424,44 @@  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;
+
+	switch (fom->msg_type) {
+	case NM_MT_SET_RADIO_ATTR:
+		if (rc == MANUFACTURER_MSG_OSMO_TYPE)
+			rc = take_reduce_power(fom, msgb_l3len(msg));
+		else {
+			LOGP(DL1C, LOGL_ERROR, "Incorrect message type %d\n",
+			     rc);
+			rc = -1;
+		}
+		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:
+		if (rc == OML_MSG_TYPE)
+			rc = abis_oml_sendmsg(msg);
+		else {
+			LOGP(DL1C, LOGL_ERROR, "Incorrect message type %d\n",
+			     rc);
+			rc = -1;
+		}
+		break;
+	default:
+		LOGP(DL1C, LOGL_ERROR, "Unknown Fom message type %d\n",
+		     fom->msg_type);
+		goto err;
+	}
 
-	return abis_oml_sendmsg(msg);
+	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..4f08cfd 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,69 @@  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_OSMO_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_ipa_header(msg) < 0) {
+		close(fd_unix);
+		msgb_free(msg);
+		return -1;
+	}
+
+	msgb_pull(msg, sizeof(struct ipaccess_head));
+
+	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 {