From patchwork Mon Apr 28 11:44:32 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Alvaro Neira X-Patchwork-Id: 343359 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from ganesha.gnumonks.org (ganesha.gnumonks.org [213.95.27.120]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 00D411400A1 for ; Mon, 28 Apr 2014 21:46:38 +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 1Wek0t-0007Cw-3K; Mon, 28 Apr 2014 13:46:24 +0200 Received: from mail.sysmocom.de ([2a01:4f8:191:444c::2:4]) by ganesha.gnumonks.org with esmtp (Exim 4.72) (envelope-from ) id 1WejzH-0006tr-3t for openbsc@lists.osmocom.org; Mon, 28 Apr 2014 13:44:47 +0200 Received: from Ph0enix.home (24-134-58-61-dynip.superkabel.de [24.134.58.61]) by mail.sysmocom.de (Postfix) with ESMTPA id E04F054873 for ; Mon, 28 Apr 2014 11:44:42 +0000 (UTC) From: Alvaro Neira Ayuso To: openbsc@lists.osmocom.org Subject: [osmo-bts PATCH 3/5 v11] src: Add OML support for sending failure message from manager Date: Mon, 28 Apr 2014 13:44:32 +0200 Message-Id: <1398685472-19232-1-git-send-email-anayuso@sysmocom.de> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <1397649982-17674-1-git-send-email-anayuso@sysmocom.de> References: <1397649982-17674-1-git-send-email-anayuso@sysmocom.de> MIME-Version: 1.0 X-Spam-Score: 0.1 (/) X-Spam-Report: SpamASsassin versoin 3.3.1 on ganesha.gnumonks.org summary: Content analysis details: (0.1 points, 5.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- 0.1 TW_TR BODY: Odd Letter Triples with TR 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 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 --- [changes in v11] * Moved the function prepend_oml_ipa_header and check_oml_msg to utils for using in the future. * Added Manufacture support in the function check_oml_msg * Changed the description of the function check_oml_msg for having more information about that function. * Changed the function check_temperature for returing 1 in the case that the current_temperature is between the parameters limit that we have used. Return 0 in the other case. src/osmo-bts-sysmo/Makefile.am | 4 +- src/osmo-bts-sysmo/main.c | 93 ++++++++++++++++++++ src/osmo-bts-sysmo/misc/sysmobts_mgr.c | 92 ++++++++++++++++++++ src/osmo-bts-sysmo/misc/sysmobts_mgr.h | 7 ++ src/osmo-bts-sysmo/misc/sysmobts_misc.c | 143 ++++++++++++++++++++++++++++++- src/osmo-bts-sysmo/misc/sysmobts_misc.h | 32 +++++++ src/osmo-bts-sysmo/utils.c | 124 +++++++++++++++++++++++++++ src/osmo-bts-sysmo/utils.h | 7 ++ 8 files changed, 499 insertions(+), 3 deletions(-) diff --git a/src/osmo-bts-sysmo/Makefile.am b/src/osmo-bts-sysmo/Makefile.am index 1c08af3..e9ba949 100644 --- a/src/osmo-bts-sysmo/Makefile.am +++ b/src/osmo-bts-sysmo/Makefile.am @@ -22,8 +22,8 @@ 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 utils.c +sysmobts_mgr_LDADD = $(COMMON_LDADD) sysmobts_util_SOURCES = misc/sysmobts_util.c misc/sysmobts_par.c sysmobts_util_LDADD = $(LIBOSMOCORE_LIBS) diff --git a/src/osmo-bts-sysmo/main.c b/src/osmo-bts-sysmo/main.c index 921103e..acdf6fc 100644 --- a/src/osmo-bts-sysmo/main.c +++ b/src/osmo-bts-sysmo/main.c @@ -35,8 +35,10 @@ #include #include +#include #include #include +#include #include #include @@ -45,6 +47,9 @@ #include #include #include +#include + +#include "misc/sysmobts_mgr.h" #define SYSMOBTS_RF_LOCK_PATH "/var/lock/bts_rf_lock" @@ -258,6 +263,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 +294,86 @@ static int write_pid_file(char *procname) return 0; } +static int read_sock(struct osmo_fd *fd, unsigned int what) +{ + struct msgb *msg; + struct gsm_abis_mo *mo; + int rc; + + msg = oml_msgb_alloc(); + if (msg == NULL) { + LOGP(DL1C, LOGL_ERROR, "Failed alloc oml message.\n"); + return -1; + } + + rc = recv(fd->fd, msg->tail, msg->data_len, 0); + if (rc <= 0) { + close(fd->fd); + osmo_fd_unregister(fd); + fd->fd = -1; + goto err; + } + + msgb_put(msg, rc); + + if (check_oml_msg(msg) < 0) { + LOGP(DL1C, LOGL_ERROR, "Malformed receive message\n"); + goto err; + } + + mo = &bts->mo; + msg->trx = mo->bts->c0; + + return abis_oml_sendmsg(msg); + +err: + msgb_free(msg); + return -1; +} + +static int accept_unix_sock(struct osmo_fd *fd, unsigned int what) +{ + int sfd = fd->fd, cl; + struct osmo_fd *read_fd = (struct osmo_fd *)fd->data; + + if (read_fd->fd > -1) { + close(read_fd->fd); + osmo_fd_unregister(read_fd); + read_fd->fd = -1; + } + + cl = accept(sfd, NULL, NULL); + if (cl < 0) { + LOGP(DL1C, LOGL_ERROR, "Accept new unix domain connection.\n"); + return -1; + } + + read_fd->fd = cl; + if (osmo_fd_register(read_fd) != 0) { + LOGP(DL1C, LOGL_ERROR, "Register the read file desc.\n"); + close(cl); + read_fd->fd = -1; + return -1; + } + + return 0; +} + +static int oml_sock_unix_init(struct osmo_fd *accept, struct osmo_fd *read) +{ + int rc; + + accept->cb = accept_unix_sock; + read->cb = read_sock; + read->when = BSC_FD_READ; + read->fd = -1; + accept->data = read; + + rc = osmo_sock_unix_init_ofd(accept, SOCK_SEQPACKET, 0, SOCKET_PATH, + OSMO_SOCK_F_BIND | OSMO_SOCK_F_NONBLOCK); + return rc; +} + int main(int argc, char **argv) { struct stat st; @@ -295,6 +381,7 @@ int main(int argc, char **argv) struct gsm_bts_role_bts *btsb; struct e1inp_line *line; void *tall_msgb_ctx; + struct osmo_fd accept_fd, read_fd; int rc; tall_bts_ctx = talloc_named_const(NULL, 1, "OsmoBTS context"); @@ -371,6 +458,12 @@ int main(int argc, char **argv) exit(1); } + rc = oml_sock_unix_init(&accept_fd, &read_fd); + if (rc < 0) { + perror("Error creating socket domain creation"); + exit(1); + } + if (daemonize) { rc = osmo_daemonize(); if (rc < 0) { diff --git a/src/osmo-bts-sysmo/misc/sysmobts_mgr.c b/src/osmo-bts-sysmo/misc/sysmobts_mgr.c index 6c64d0f..51fdd83 100644 --- a/src/osmo-bts-sysmo/misc/sysmobts_mgr.c +++ b/src/osmo-bts-sysmo/misc/sysmobts_mgr.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #include @@ -47,7 +48,9 @@ static int no_eeprom_write = 0; static int daemonize = 0; +static int fd_unix = -1; void *tall_mgr_ctx; +static struct sbts2050_config_info confinfo; /* every 6 hours means 365*4 = 1460 EEprom writes per year (max) */ #define TEMP_TIMER_SECS (6 * 3600) @@ -55,7 +58,63 @@ void *tall_mgr_ctx; /* every 1 hours means 365*24 = 8760 EEprom writes per year (max) */ #define HOURS_TIMER_SECS (1 * 3600) +/* every 5 minutes try to reconnect if we have a problem in the communication*/ +#define CONNECT_TIMER_SECS 300 + #ifdef BUILD_SBTS2050 +static int trx_nr = -1; +static int state_connection; + +static struct osmo_timer_list connect_timer; +static void socket_connect_cb(void *data) +{ + fd_unix = osmo_sock_unix_init(SOCK_SEQPACKET, 0, SOCKET_PATH, + OSMO_SOCK_F_CONNECT); + if (fd_unix < 0) { + osmo_timer_schedule(&connect_timer, CONNECT_TIMER_SECS, 0); + return; + } + + state_connection = SYSMO_MGR_CONNECTED; +} + +static int check_temperature(struct uc *ucontrol0, int lowlimit, int highlimit, + int current_temp, + enum sbts2050_temp_sensor sensor, + enum sbts2050_alert_lvl alert) +{ + int rc; + + if (lowlimit >= current_temp || highlimit <= current_temp) { + switch (alert) { + case SBTS2050_WARN_ALERT: + rc = send_omlfailure(fd_unix, alert, sensor, &confinfo, + trx_nr); + break; + case SBTS2050_SEVERE_ALERT: + rc = send_omlfailure(fd_unix, alert, sensor, + &confinfo, trx_nr); + sbts2050_uc_power(ucontrol0, confinfo.master_power_act, + confinfo.slave_power_act, + confinfo.pa_power_act); + break; + default: + LOGP(DFIND, LOGL_ERROR, "Unknown alert type %d\n", + alert); + return -1; + } + } else { + return 0; + } + + state_connection = rc; + + if (state_connection == SYSMO_MGR_DISCONNECTED) + socket_connect_cb(NULL); + + return 1; +} + static struct osmo_timer_list temp_uc_timer; static void check_uctemp_timer_cb(void *data) { @@ -64,6 +123,33 @@ 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; + + 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, + confinfo.temp_max_pa_severe_limit, + 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); + + check_temperature(ucontrol0, + confinfo.temp_min_board_severe_limit, + confinfo.temp_max_board_severe_limit, + temp_board, SBTS2050_TEMP_BOARD, + SBTS2050_SEVERE_ALERT); + osmo_timer_schedule(&temp_uc_timer, TEMP_TIMER_SECS, 0); } #endif @@ -93,6 +179,7 @@ static void initialize_sbts2050(void) if (val != 0) return; } + trx_nr = val; ucontrol0.fd = osmo_serial_init(ucontrol0.path, 115200); if (ucontrol0.fd < 0) { @@ -101,6 +188,10 @@ static void initialize_sbts2050(void) return; } + /* start handle for reconnect the socket in case of error */ + connect_timer.cb = socket_connect_cb; + socket_connect_cb(NULL); + temp_uc_timer.cb = check_uctemp_timer_cb; temp_uc_timer.data = &ucontrol0; check_uctemp_timer_cb(&ucontrol0); @@ -169,6 +260,7 @@ static void signal_handler(int signal) case SIGINT: sysmobts_check_temp(no_eeprom_write); sysmobts_update_hours(no_eeprom_write); + close(fd_unix); exit(0); break; case SIGABRT: diff --git a/src/osmo-bts-sysmo/misc/sysmobts_mgr.h b/src/osmo-bts-sysmo/misc/sysmobts_mgr.h index ddb6774..21f30a4 100644 --- a/src/osmo-bts-sysmo/misc/sysmobts_mgr.h +++ b/src/osmo-bts-sysmo/misc/sysmobts_mgr.h @@ -7,4 +7,11 @@ enum { DFIND, }; +enum { + SYSMO_MGR_DISCONNECTED = 0, + SYSMO_MGR_CONNECTED, +}; + +#define SOCKET_PATH "/var/run/bts_oml" + #endif diff --git a/src/osmo-bts-sysmo/misc/sysmobts_misc.c b/src/osmo-bts-sysmo/misc/sysmobts_misc.c index 9ea26c2..fbbd6ee 100644 --- a/src/osmo-bts-sysmo/misc/sysmobts_misc.c +++ b/src/osmo-bts-sysmo/misc/sysmobts_misc.c @@ -29,14 +29,19 @@ #include #include #include +#include #include #include #include +#include #include #include #include +#include +#include +#include "utils.h" #include "btsconfig.h" #include "sysmobts_misc.h" #include "sysmobts_par.h" @@ -49,9 +54,145 @@ #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 #ifdef BUILD_SBTS2050 +static void add_sw_descr(struct msgb *msg) +{ + char file_version[255]; + char file_id[255]; + + strncpy(file_id, "sysmomgr", sizeof("sysmomgr")); + file_id[sizeof(file_id) - 1] = '\0'; + strncpy(file_version, PACKAGE_VERSION, sizeof(PACKAGE_VERSION)); + file_version[sizeof(file_version) - 1] = '\0'; + msgb_v_put(msg, NM_ATT_SW_DESCR); + msgb_tl16v_put(msg, NM_ATT_FILE_ID, strlen(file_id), + (uint8_t *)file_id); + msgb_tl16v_put(msg, NM_ATT_FILE_VERSION, strlen(file_version), + (uint8_t *)file_version); +} + +static void add_probable_cause(struct msgb *msg) +{ + msgb_tv_put(msg, NM_ATT_PROB_CAUSE, NM_PCAUSE_T_MANUF); + msgb_v_put(msg, 0); + msgb_v_put(msg, 0); +} + +static void add_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, int is_manuf) +{ + 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; + + if (is_manuf) { + /* length byte, string + 0 termination */ + uint8_t *manuf = msgb_push(msg, 1 + sizeof(osmobts_magic)); + manuf[0] = strlen(osmobts_magic)+1; + memcpy(manuf+1, osmobts_magic, strlen(osmobts_magic)); + } + + msg->l2h = msgb_push(msg, sizeof(*omh)); + omh = (struct abis_om_hdr *) msg->l2h; + + if (is_manuf) + omh->mdisc = ABIS_OM_MDISC_MANUF; + else + omh->mdisc = ABIS_OM_MDISC_FOM; + omh->placement = ABIS_OM_PLACEMENT_ONLY; + omh->sequence = 0; + omh->length = msgb_l3len(msg); +} + +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 rc; + struct msgb *msg; + const char *buf, *nsensor; + + 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_FAILURE_EVENT_REP, 0, 0, trx_nr, 0, 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_SEVERE_ALERT: + msgb_tv_put(msg, NM_ATT_SEVERITY, NM_SEVER_CRITICAL); + break; + default: + LOGP(DTEMP, LOGL_ERROR, "Unknown attr severity type %d\n", + alert); + goto err; + } + + add_probable_cause(msg); + + add_sw_descr(msg); + + 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: + LOGP(DTEMP, LOGL_ERROR, "Unknown sensor type %d\n", sensor); + goto err; + } + strncpy(add_info->name_sensor, nsensor, sizeof(add_info->name_sensor)); + add_info->name_sensor[sizeof(add_info->name_sensor) - 1] = '\0'; + + msgb_tl16v_put(msg, NM_ATT_ADD_TEXT, strlen(buf), (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_tl16v_put(msg, NM_ATT_ADD_INFO, + sizeof(struct sbts2050_config_info), + (const uint8_t *)add_info); + + prepend_oml_ipa_header(msg); + + rc = send(fd_unix, msg->data, msg->len, 0); + if (rc < 0 || rc != msg->len) { + LOGP(DTEMP, LOGL_ERROR, "Error writting in unix socket\n"); + close(fd_unix); + msgb_free(msg); + return SYSMO_MGR_DISCONNECTED; + } + + msgb_free(msg); + return SYSMO_MGR_CONNECTED; +err: + msgb_free(msg); + return -1; +} + /********************************************************************** * Functions read/write from serial interface *********************************************************************/ diff --git a/src/osmo-bts-sysmo/misc/sysmobts_misc.h b/src/osmo-bts-sysmo/misc/sysmobts_misc.h index 01878f2..c22a54b 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_SEVERE_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_severe_limit; + int temp_min_pa_severe_limit; + int temp_max_board_warn_limit; + int temp_min_board_warn_limit; + int temp_max_board_severe_limit; + int temp_min_board_severe_limit; + int reduce_max_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 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 sysmobts_update_hours(int no_epprom_write); enum sysmobts_firmware_type { diff --git a/src/osmo-bts-sysmo/utils.c b/src/osmo-bts-sysmo/utils.c index af1e5d2..ecf3960 100644 --- a/src/osmo-bts-sysmo/utils.c +++ b/src/osmo-bts-sysmo/utils.c @@ -27,6 +27,9 @@ #include #include +#include +#include + #include "femtobts.h" #include "l1_if.h" @@ -147,3 +150,124 @@ int sysmobts_get_power_trx(struct gsm_bts_trx *trx) return power_transmitter; } + +void prepend_oml_ipa_header(struct msgb *msg) +{ + struct ipaccess_head *hh; + + hh = (struct ipaccess_head *) msgb_push(msg, sizeof(*hh)); + hh->proto = IPAC_PROTO_OML; + hh->len = htons(msg->len - sizeof(struct ipaccess_head)); +} + +/** + * \brief Check that the data in \param msg is a proper OML message + * + * This function verifies that the data in \param in msg is a proper + * OML message and can be handled by later functions. In the successful + * case the msg->l2h will now point to the OML header and the msg->l3h + * will point to the FOM header. The value of l2h/l3h is undefined in + * case the verification of the \param msg is failing. + * + * \param msg The message to analyze. msg->len starting from msg->data + * will be analyzed. + * \return This function returns the msg with the l2h/l3h pointers in the right + * direction on success and on failure, in the case that the msg doesn't contain + * the OML header or the OML header values aren't the expect, the function + * doesn't set the l2h and l3h. In the case that the msg don't contains the FOM + * header or the FOM header values aren't the expect, the function set the l2h + * but doesn't set the l3h. + */ + +int check_oml_msg(struct msgb *msg) +{ + struct ipaccess_head *hh; + struct abis_om_hdr *omh; + int abis_oml_hdr_len; + + if (msg->len < sizeof(struct ipaccess_head)) { + LOGP(DL1C, LOGL_ERROR, "Ipa header insufficient space %d %d\n", + msg->len, sizeof(struct ipaccess_head)); + return -1; + } + + hh = (struct ipaccess_head *)msg->data; + + if (hh->proto != IPAC_PROTO_OML) { + LOGP(DL1C, LOGL_ERROR, "Incorrect ipa header protocol %x %x\n", + hh->proto, IPAC_PROTO_OML); + return -1; + } + + if (ntohs(hh->len) != msg->len - sizeof(struct ipaccess_head)) { + LOGP(DL1C, LOGL_ERROR, "Incorrect ipa header msg size %d %d\n", + ntohs(hh->len), msg->len - sizeof(struct ipaccess_head)); + return -1; + } + + msgb_pull(msg, sizeof(struct ipaccess_head)); + + abis_oml_hdr_len = sizeof(struct abis_om_hdr); + + if (msg->len < abis_oml_hdr_len) { + LOGP(DL1C, LOGL_ERROR, "Om header insufficient space %d %d\n", + msg->len, abis_oml_hdr_len); + return -1; + } + + msg->l2h = msg->data; + + omh = (struct abis_om_hdr *) msg->l2h; + + if (omh->mdisc != ABIS_OM_MDISC_FOM && + omh->mdisc != ABIS_OM_MDISC_MANUF) { + LOGP(DL1C, LOGL_ERROR, "Incorrect om mdisc value %x\n", + omh->mdisc); + return -1; + } + + if (omh->placement != ABIS_OM_PLACEMENT_ONLY) { + LOGP(DL1C, LOGL_ERROR, "Incorrect om placement value %x %x\n", + omh->placement, ABIS_OM_PLACEMENT_ONLY); + return -1; + } + + if (omh->sequence != 0) { + LOGP(DL1C, LOGL_ERROR, "Incorrect om sequence value %d\n", + omh->sequence); + return -1; + } + + if (omh->length != sizeof(struct abis_om_fom_hdr)) { + LOGP(DL1C, LOGL_ERROR, "Incorrect om length value %d %d\n", + omh->length, sizeof(struct abis_om_fom_hdr)); + return -1; + } + + if (omh->mdisc == ABIS_OM_MDISC_MANUF) { + abis_oml_hdr_len += sizeof(osmobts_magic) + 1; + + if (msg->len < abis_oml_hdr_len) { + LOGP(DL1C, LOGL_ERROR, + "ID manuf osmobts insufficient space%d %d\n", + msg->len, abis_oml_hdr_len); + return -1; + } + } + + abis_oml_hdr_len += sizeof(struct abis_om_fom_hdr); + + if (msg->len < abis_oml_hdr_len) { + LOGP(DL1C, LOGL_ERROR, "Fom header insufficient space %d %d\n", + msg->len, abis_oml_hdr_len); + return -1; + } + + msg->l3h = msg->data + sizeof(struct abis_om_hdr); + + if (omh->mdisc == ABIS_OM_MDISC_MANUF) + msg->l3h = msg->l3h + sizeof(osmobts_magic) + 1; + + return 0; +} + diff --git a/src/osmo-bts-sysmo/utils.h b/src/osmo-bts-sysmo/utils.h index aef774c..10782bb 100644 --- a/src/osmo-bts-sysmo/utils.h +++ b/src/osmo-bts-sysmo/utils.h @@ -13,4 +13,11 @@ int sysmobts_select_femto_band(struct gsm_bts_trx *trx, uint16_t arfcn); int sysmobts_get_nominal_power(struct gsm_bts_trx *trx); int sysmobts_get_power_trx(struct gsm_bts_trx *trx); + +struct msgb; +static const char osmobts_magic[] = "com.osmobts"; + +void prepend_oml_ipa_header(struct msgb *msg); + +int check_oml_msg(struct msgb *msg); #endif