This is merely a historical archive of years 2008-2021, before the migration to mailman3.
A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/OpenBSC@lists.osmocom.org/.
Alvaro Neira Ayuso anayuso at sysmocom.deWith 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 at sysmocom.de> --- [changes in v12] * Changed check_oml_msg for making a general function that we can use in the future for check and restructure received oml message. 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 | 139 ++++++++++++++++++++++++++++++ src/osmo-bts-sysmo/utils.h | 9 ++ 8 files changed, 516 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 <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> +#include <osmocom/gsm/protocol/ipaccess.h> #include <osmo-bts/gsm_data.h> #include <osmo-bts/logging.h> @@ -45,6 +47,9 @@ #include <osmo-bts/vty.h> #include <osmo-bts/bts_model.h> #include <osmo-bts/pcu_if.h> +#include <osmo-bts/oml.h> + +#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 <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> @@ -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..2030888 100644 --- a/src/osmo-bts-sysmo/misc/sysmobts_misc.c +++ b/src/osmo-bts-sysmo/misc/sysmobts_misc.c @@ -29,14 +29,19 @@ #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/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 <osmocom/gsm/protocol/ipaccess.h> +#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(osmocom_magic)); + manuf[0] = strlen(osmocom_magic)+1; + memcpy(manuf+1, osmocom_magic, strlen(osmocom_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, 255, 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..36ba198 100644 --- a/src/osmo-bts-sysmo/utils.c +++ b/src/osmo-bts-sysmo/utils.c @@ -27,6 +27,9 @@ #include <osmo-bts/gsm_data.h> #include <osmo-bts/logging.h> +#include <osmocom/core/msgb.h> +#include <osmocom/gsm/protocol/ipaccess.h> + #include "femtobts.h" #include "l1_if.h" @@ -147,3 +150,139 @@ 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; + char label_id[255]; + + 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(ipaccess_magic); + + if (msg->len < abis_oml_hdr_len) { + LOGP(DL1C, LOGL_ERROR, + "ID manuf label 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) { + strncpy(label_id, (const char *) msg->l3h + 1, + sizeof(ipaccess_magic) + 1); + + if (strncmp(ipaccess_magic, label_id, + sizeof(ipaccess_magic) + 1) == 0) + msg->l3h = msg->l3h + sizeof(ipaccess_magic) + 1; + else if (strncmp(osmocom_magic, label_id, + sizeof(osmocom_magic) + 1) == 0) + msg->l3h = msg->l3h + sizeof(osmocom_magic) + 1; + else { + msg->l3h = NULL; + LOGP(DL1C, LOGL_ERROR, + "Manuf Label Unknown %s\n", label_id); + return -1; + } + } + + return 0; +} + diff --git a/src/osmo-bts-sysmo/utils.h b/src/osmo-bts-sysmo/utils.h index aef774c..b1ca0c0 100644 --- a/src/osmo-bts-sysmo/utils.h +++ b/src/osmo-bts-sysmo/utils.h @@ -13,4 +13,13 @@ 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 osmocom_magic[] = "org.osmocom"; +static const char ipaccess_magic[] = "com.ipaccess"; + +void prepend_oml_ipa_header(struct msgb *msg); + +int check_oml_msg(struct msgb *msg); #endif -- 1.7.10.4