[osmo-bts] src: Add OML support for sending failure message from manager
diff mbox

Message ID 1395850236-6570-1-git-send-email-anayuso@sysmocom.de
State Superseded
Headers show

Commit Message

Alvaro Neira March 26, 2014, 4:10 p.m. UTC
From: Álvaro Neira Ayuso <anayuso@sysmocom.de>

With this patch, the manager monitors the sensors and send
OML Failure message from the Manager to the BTS and the BTS
to BSC, for having a report system of the sensors.

Signed-off-by: Alvaro Neira Ayuso <anayuso@sysmocom.de>
---
 src/osmo-bts-sysmo/main.c               |   45 ++++++++++++
 src/osmo-bts-sysmo/misc/sysmobts_mgr.c  |   35 +++++++++
 src/osmo-bts-sysmo/misc/sysmobts_misc.c |  120 ++++++++++++++++++++++++++++++-
 src/osmo-bts-sysmo/misc/sysmobts_misc.h |   32 +++++++++
 4 files changed, 231 insertions(+), 1 deletion(-)

Comments

Holger Freyther March 26, 2014, 6:59 p.m. UTC | #1
On Wed, Mar 26, 2014 at 05:10:36PM +0100, Alvaro Neira Ayuso wrote:

Dear Alvaro,

is that anolder patch?


> +static int read_unix_sock(struct osmo_fd *fd, unsigned int what)
> +{

...

the connection should remain open, you should probably use the
IPA multiplex protocol here (or use sequential packet mode).

> +struct sbts2050_config_info confinfo;

make this static

> +#define OM_ALLOC_SIZE		1024
> +#define OM_HEADROOM_SIZE	128
> +#define SOCKET_PATH     "/tmp/echo_temp"

Why /tmp/echo_temp? In general we might want to not have this in a
public writable directory?

> +	if (sysmobts_par_get_int(SYSMOBTS_PAR_TRX_NR, &val) < 0)
> +		goto err;

Can't you remember the TRX_NR? We don't really want to read the
EEPROM all the time?

> +	strcpy(version, PACKAGE_VERSION);

neat idea!

Patch
diff mbox

diff --git a/src/osmo-bts-sysmo/main.c b/src/osmo-bts-sysmo/main.c
index 74ee47f..a86d41e 100644
--- a/src/osmo-bts-sysmo/main.c
+++ b/src/osmo-bts-sysmo/main.c
@@ -35,6 +35,7 @@ 
 
 #include <osmocom/core/talloc.h>
 #include <osmocom/core/application.h>
+#include <osmocom/core/socket.h>
 #include <osmocom/vty/telnet_interface.h>
 #include <osmocom/vty/logging.h>
 
@@ -45,8 +46,10 @@ 
 #include <osmo-bts/vty.h>
 #include <osmo-bts/bts_model.h>
 #include <osmo-bts/pcu_if.h>
+#include <osmo-bts/oml.h>
 
 #define SYSMOBTS_RF_LOCK_PATH	"/var/lock/bts_rf_lock"
+#define SOCKET_PATH     "/tmp/echo_temp"
 
 #include "utils.h"
 #include "eeprom.h"
@@ -258,6 +261,7 @@  static void signal_handler(int signal)
 	case SIGINT:
 		//osmo_signal_dispatch(SS_GLOBAL, S_GLOBAL_SHUTDOWN, NULL);
 		bts_shutdown(bts, "SIGINT");
+		unlink(SOCKET_PATH);
 		break;
 	case SIGABRT:
 	case SIGUSR1:
@@ -288,6 +292,38 @@  static int write_pid_file(char *procname)
 	return 0;
 }
 
+static int read_unix_sock(struct osmo_fd *fd, unsigned int what)
+{
+	int sfd = fd->fd, cl, rc = 1;
+	struct msgb *msg;
+	struct gsm_abis_mo *mo;
+
+	cl = accept(sfd, NULL, NULL);
+	if (cl < 0)
+		return -1;
+
+	msg = oml_msgb_alloc();
+	if (msg == NULL)
+		return -1;
+
+	while (rc > 0) {
+		rc = recv(cl, msg->tail, msg->data_len, 0);
+		if (rc < 0)
+			return -1;
+		else if (rc == 0)
+			break;
+
+		msgb_put(msg, rc);
+	}
+	close(cl);
+	mo = &bts->mo;
+	msg->trx = mo->bts->c0;
+	msg->l2h = msg->data;
+	msg->l3h = msg->data + sizeof(struct abis_om_fom_hdr);
+
+	return abis_oml_sendmsg(msg);
+}
+
 int main(int argc, char **argv)
 {
 	struct stat st;
@@ -295,6 +331,7 @@  int main(int argc, char **argv)
 	struct gsm_bts_role_bts *btsb;
 	struct e1inp_line *line;
 	void *tall_msgb_ctx;
+	struct osmo_fd fd;
 	int rc;
 
 	tall_bts_ctx = talloc_named_const(NULL, 1, "OsmoBTS context");
@@ -370,6 +407,14 @@  int main(int argc, char **argv)
 		fprintf(stderr, "unable to connect to BSC\n");
 		exit(1);
 	}
+	fd.cb = read_unix_sock;
+
+	rc = osmo_sock_unix_init_ofd(&fd, SOCK_STREAM, 0, SOCKET_PATH,
+				     OSMO_SOCK_F_BIND | OSMO_SOCK_F_NONBLOCK);
+	if (rc < 0) {
+		perror("Error creating socket domain creation");
+		exit(3);
+	}
 
 	if (daemonize) {
 		rc = osmo_daemonize();
diff --git a/src/osmo-bts-sysmo/misc/sysmobts_mgr.c b/src/osmo-bts-sysmo/misc/sysmobts_mgr.c
index 6c64d0f..d547dbe 100644
--- a/src/osmo-bts-sysmo/misc/sysmobts_mgr.c
+++ b/src/osmo-bts-sysmo/misc/sysmobts_mgr.c
@@ -36,6 +36,7 @@ 
 #include <osmocom/core/timer.h>
 #include <osmocom/core/msgb.h>
 #include <osmocom/core/serial.h>
+#include <osmocom/core/socket.h>
 #include <osmocom/vty/telnet_interface.h>
 #include <osmocom/vty/logging.h>
 
@@ -48,6 +49,7 @@ 
 static int no_eeprom_write = 0;
 static int daemonize = 0;
 void *tall_mgr_ctx;
+struct sbts2050_config_info confinfo;
 
 /* every 6 hours means 365*4 = 1460 EEprom writes per year (max) */
 #define TEMP_TIMER_SECS		(6 * 3600)
@@ -64,6 +66,39 @@  static void check_uctemp_timer_cb(void *data)
 
 	sbts2050_uc_check_temp(ucontrol0, &temp_pa, &temp_board);
 
+	confinfo.temp_pa_cur = temp_pa;
+	confinfo.temp_board_cur = temp_board;
+
+	if (confinfo.temp_min_pa_warn_limit > temp_pa ||
+	    confinfo.temp_max_pa_warn_limit < temp_pa) {
+		sendto_osmobts(ucontrol0, SBTS2050_WARN_ALERT,
+			       SBTS2050_TEMP_PA, &confinfo);
+	} else if (confinfo.temp_min_pa_sever_limit > temp_pa ||
+		   confinfo.temp_max_pa_sever_limit < temp_pa) {
+		sendto_osmobts(ucontrol0, SBTS2050_SEVER_ALERT,
+			       SBTS2050_TEMP_PA, &confinfo);
+		sbts2050_uc_power(ucontrol0,
+				  sbts2050_uc_status(ucontrol0,
+					  	     SBTS2050_STATUS_MASTER),
+				  sbts2050_uc_status(ucontrol0,
+					  	     SBTS2050_STATUS_SLAVE),
+				  		     confinfo.pa_power_act);
+	}
+
+	if (confinfo.temp_min_board_warn_limit > temp_board ||
+	    confinfo.temp_max_board_warn_limit < temp_board) {
+		sendto_osmobts(ucontrol0, SBTS2050_WARN_ALERT,
+			       SBTS2050_TEMP_BOARD, &confinfo);
+	} else if (confinfo.temp_min_board_sever_limit > temp_board ||
+		 confinfo.temp_max_board_sever_limit  < temp_board) {
+		sendto_osmobts(ucontrol0, SBTS2050_SEVER_ALERT,
+			       SBTS2050_TEMP_BOARD, &confinfo);
+		sbts2050_uc_power(ucontrol0, confinfo.master_power_act,
+				  confinfo.slave_power_act,
+				  sbts2050_uc_status(ucontrol0,
+					  	     SBTS2050_STATUS_PA));
+	}
+
 	osmo_timer_schedule(&temp_uc_timer, TEMP_TIMER_SECS, 0);
 }
 #endif
diff --git a/src/osmo-bts-sysmo/misc/sysmobts_misc.c b/src/osmo-bts-sysmo/misc/sysmobts_misc.c
index 9ea26c2..44bffad 100644
--- a/src/osmo-bts-sysmo/misc/sysmobts_misc.c
+++ b/src/osmo-bts-sysmo/misc/sysmobts_misc.c
@@ -29,13 +29,17 @@ 
 #include <sys/signal.h>
 #include <sys/types.h>
 #include <sys/stat.h>
+#include <arpa/inet.h>
 
 #include <osmocom/core/talloc.h>
 #include <osmocom/core/utils.h>
 #include <osmocom/core/msgb.h>
+#include <osmocom/core/serial.h>
+#include <osmocom/core/socket.h>
 #include <osmocom/core/application.h>
 #include <osmocom/vty/telnet_interface.h>
 #include <osmocom/vty/logging.h>
+#include <osmocom/gsm/abis_nm.h>
 
 #include "btsconfig.h"
 #include "sysmobts_misc.h"
@@ -49,10 +53,124 @@ 
 #define SERIAL_ALLOC_SIZE	300
 #define SIZE_HEADER_RSP		5
 #define SIZE_HEADER_CMD		4
-
+#define OM_ALLOC_SIZE		1024
+#define OM_HEADROOM_SIZE	128
+#define SOCKET_PATH     "/tmp/echo_temp"
 
 #ifdef BUILD_SBTS2050
 /**********************************************************************
+ *	Function send information to OsmoBts
+ *********************************************************************/
+static void create_oml_hdr_msg(struct msgb *msg, uint8_t msg_type,
+			       uint8_t obj_class, uint8_t bts_nr,
+			       uint8_t trx_nr, uint8_t ts_nr)
+{
+	struct abis_om_fom_hdr *foh;
+	struct abis_om_hdr *omh;
+
+	msg->l3h = msgb_push(msg, sizeof(*foh));
+	foh = (struct abis_om_fom_hdr *) msg->l3h;
+
+	foh->msg_type = msg_type;
+	foh->obj_class = obj_class;
+	foh->obj_inst.bts_nr = bts_nr;
+	foh->obj_inst.trx_nr = trx_nr;
+	foh->obj_inst.ts_nr = ts_nr;
+
+	msg->l2h = msgb_push(msg, sizeof(*omh));
+	omh = (struct abis_om_hdr *) msg->l2h;
+
+	omh->mdisc = ABIS_OM_MDISC_FOM;
+	omh->placement = ABIS_OM_PLACEMENT_ONLY;
+	omh->sequence = 0;
+	omh->length = msgb_l3len(msg);
+}
+
+int sendto_osmobts(struct uc *ucontrol, enum sbts2050_alert_lvl alert,
+		   enum sbts2050_temp_sensor sensor,
+		   struct sbts2050_config_info *add_info)
+{
+	int rc, val, fd;
+	struct msgb *msg;
+	const char *buf, *nsensor;
+	char version[20];
+
+	msg = msgb_alloc_headroom(OM_ALLOC_SIZE, OM_HEADROOM_SIZE, "OML");
+	if (msg == NULL) {
+		LOGP(DTEMP, LOGL_ERROR, "Error creating msg\n");
+		goto err;
+	}
+
+	if (sysmobts_par_get_int(SYSMOBTS_PAR_TRX_NR, &val) < 0)
+		goto err;
+
+	create_oml_hdr_msg(msg, NM_MT_FAILURE_EVENT_REP, 0, 0, val, 0);
+
+	msgb_tv_put(msg, NM_ATT_EVENT_TYPE, NM_EVT_ENV_FAIL);
+
+	switch (alert) {
+	case SBTS2050_WARN_ALERT:
+		msgb_tv_put(msg, NM_ATT_SEVERITY, NM_SEVER_WARNING);
+		break;
+	case SBTS2050_SEVER_ALERT:
+		msgb_tv_put(msg, NM_ATT_SEVERITY, NM_SEVER_CRITICAL);
+		break;
+	default:
+		goto err;
+	}
+
+	msgb_tv_put(msg, NM_ATT_PROB_CAUSE, NM_PCAUSE_T_MANUF);
+
+	strcpy(version, PACKAGE_VERSION);
+	msgb_v_put(msg, NM_ATT_SW_DESCR);
+	msgb_tl16v_put(msg, NM_ATT_FILE_ID, 0, 0);
+	msgb_tl16v_put(msg, NM_ATT_FILE_VERSION, strlen(version),
+						      (const uint8_t *)version);
+
+	switch (sensor){
+	case SBTS2050_TEMP_BOARD:
+		buf = "Unusual temperature on the Board";
+		nsensor = "Board";
+		break;
+	case SBTS2050_TEMP_PA:
+		buf = "Unusual temperature on the PA";
+		nsensor = "PA";
+		break;
+	default:
+		return -1;
+	}
+	strncpy(add_info->name_sensor, nsensor, strlen(nsensor));
+
+	msgb_tlv_put(msg, NM_ATT_ADD_TEXT, strlen(buf)+1, (const uint8_t *)buf);
+
+	//If we need to send this structure to other machine, we need to pass
+	//the integer inside the structure to internet format (big endian)
+	msgb_tlv_put(msg, NM_ATT_ADD_INFO, sizeof(struct sbts2050_config_info ),
+		     (const uint8_t *)add_info);
+
+	fd = osmo_sock_unix_init(SOCK_STREAM, 0, SOCKET_PATH,
+				 OSMO_SOCK_F_CONNECT);
+	if (fd < 0) {
+		LOGP(DTEMP, LOGL_ERROR, "Error creating unix socket\n");
+		goto err;
+	}
+
+	rc = write(fd, msg->data, msg->len);
+	if (rc < 0) {
+		LOGP(DTEMP, LOGL_ERROR, "Error writting in unix socket\n");
+		close(fd);
+		goto err;
+	}
+
+	close(fd);
+	msgb_free(msg);
+	return 0;
+err:
+	msgb_free(msg);
+	return -1;
+}
+
+/**********************************************************************
  *	Functions read/write from serial interface
  *********************************************************************/
 static int hand_serial_read(int fd, struct msgb *msg, int numbytes)
diff --git a/src/osmo-bts-sysmo/misc/sysmobts_misc.h b/src/osmo-bts-sysmo/misc/sysmobts_misc.h
index 01878f2..a2e90cf 100644
--- a/src/osmo-bts-sysmo/misc/sysmobts_misc.h
+++ b/src/osmo-bts-sysmo/misc/sysmobts_misc.h
@@ -32,6 +32,34 @@  struct ucinfo {
 	int pa;
 };
 
+enum sbts2050_alert_lvl {
+	SBTS2050_WARN_ALERT,
+	SBTS2050_SEVER_ALERT
+};
+
+enum sbts2050_temp_sensor {
+	SBTS2050_TEMP_BOARD,
+	SBTS2050_TEMP_PA
+};
+
+struct sbts2050_config_info {
+	char name_sensor[8];
+	int temp_max_pa_warn_limit;
+	int temp_min_pa_warn_limit;
+	int temp_max_pa_sever_limit;
+	int temp_min_pa_sever_limit;
+	int temp_max_board_warn_limit;
+	int temp_min_board_warn_limit;
+	int temp_max_board_sever_limit;
+	int temp_min_board_sever_limit;
+	int pa_power;
+	int slave_power_act;
+	int master_power_act;
+	int pa_power_act;
+	int temp_pa_cur;
+	int temp_board_cur;
+};
+
 int sysmobts_temp_get(enum sysmobts_temp_sensor sensor,
 		      enum sysmobts_temp_type type);
 
@@ -43,6 +71,10 @@  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 sendto_osmobts(struct uc *ucontrol, enum sbts2050_alert_lvl alert,
+		   enum sbts2050_temp_sensor sensor,
+		   struct sbts2050_config_info *add_info);
+
 int sysmobts_update_hours(int no_epprom_write);
 
 enum sysmobts_firmware_type {