From: Álvaro Neira Ayuso anayuso@sysmocom.de
Added functions for changing the max_power_red in case of we receive a Failure Event report from the manager. The sbts2050 change the max_power_red to the value that we have configured in the manager and the sbts2050 restore this value to the initial value if the bts don't receive another Failure Event report in the same time that we check the temperature in the manager.
Signed-off-by: Alvaro Neira Ayuso anayuso@sysmocom.de --- src/osmo-bts-sysmo/main.c | 67 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+)
diff --git a/src/osmo-bts-sysmo/main.c b/src/osmo-bts-sysmo/main.c index 61a5716..b492327 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> @@ -55,11 +56,14 @@ #define IPA_HEADER_SIZE 3 #define IPA_OML_PROTO 0xFF
+#define TEMP_TIMER_SECS (6 * 3600) + 1 + #include "utils.h" #include "eeprom.h" #include "l1_if.h" #include "hw_misc.h" #include "btsconfig.h" +#include <misc/sysmobts_misc.h>
/* FIXME: read from real hardware */ const uint8_t abis_mac[6] = { 0,1,2,3,4,5 }; @@ -297,6 +301,60 @@ static int write_pid_file(char *procname) return 0; } #ifdef BUILD_SBTS2050 +static int init_max_power_red; +static int new_max_power_red; +static int status_change_power_red = 0; + +enum { + SBTS2050_DISABLE_CHANGE_POWER = 0, + SBTS2050_ENABLE_CHANGE_POWER, +}; + +#define oml_tlv_parse(dec, buf, len) \ + tlv_parse(dec, &abis_nm_att_tlvdef, buf, len, 0, 0) + +/* Size of the struct plus 1 Bytes of tag and 2 Bytes for the length */ +#define tlv_add_info_len() (sizeof(struct sbts2050_config_info) + 3) + +static struct osmo_timer_list power_timer; +static void change_max_power_red_cb(void *data) +{ + struct gsm_bts *bts = data; + + if (status_change_power_red == SBTS2050_ENABLE_CHANGE_POWER) { + if (bts->c0->max_power_red != new_max_power_red) { + init_max_power_red = bts->c0->max_power_red; + bts->c0->max_power_red = new_max_power_red; + } + status_change_power_red = SBTS2050_DISABLE_CHANGE_POWER; + osmo_timer_schedule(&power_timer, TEMP_TIMER_SECS, 0); + } else if (status_change_power_red == SBTS2050_DISABLE_CHANGE_POWER) + bts->c0->max_power_red = init_max_power_red; +} + +static int take_max_power_red(struct msgb *msg) +{ + struct sbts2050_config_info *config_info; + struct tlv_parsed tlv_out; + int rc; + + rc = oml_tlv_parse(&tlv_out, msg->tail - tlv_add_info_len(), + tlv_add_info_len()); + + if (rc < 0) + return -1; + + config_info = + (struct sbts2050_config_info *) TLVP_VAL(&tlv_out, NM_ATT_ADD_INFO); + + new_max_power_red = config_info->max_power_red; + + status_change_power_red = SBTS2050_ENABLE_CHANGE_POWER; + change_max_power_red_cb(bts); + + return 0; +} + static int test_recv_msg(struct msgb *msg) { struct ipaccess_head *hh = (struct ipaccess_head *)msg->data; @@ -355,6 +413,11 @@ static int read_sock(struct osmo_fd *fd, unsigned int what) return -1; }
+ if (take_max_power_red(msg) < 0) { + LOGP(DL1C, LOGL_NOTICE, "Failed Add_info: Malformed message"); + return -1; + } + mo = &bts->mo; msg->trx = mo->bts->c0;
@@ -478,6 +541,10 @@ int main(int argc, char **argv) read_fd.fd = -1; accept_fd.data = &read_fd;
+ init_max_power_red = bts->c0->max_power_red; + power_timer.cb = change_max_power_red_cb; + power_timer.data = bts; + rc = osmo_sock_unix_init_ofd(&accept_fd, SOCK_SEQPACKET, 0, SOCKET_PATH, OSMO_SOCK_F_BIND | OSMO_SOCK_F_NONBLOCK); if (rc < 0) {
On Tue, Apr 08, 2014 at 02:40:35PM +0200, Alvaro Neira Ayuso wrote:
From: Álvaro Neira Ayuso anayuso@sysmocom.de
Added functions for changing the max_power_red in case of we receive a Failure Event report from the manager. The sbts2050 change the max_power_red to the value that we have configured in the manager and the sbts2050 restore this value to the initial value if the bts don't receive another Failure Event report in the same time that we check the temperature in the manager.
Signed-off-by: Alvaro Neira Ayuso anayuso@sysmocom.de
src/osmo-bts-sysmo/main.c | 67 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+)
diff --git a/src/osmo-bts-sysmo/main.c b/src/osmo-bts-sysmo/main.c index 61a5716..b492327 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> @@ -55,11 +56,14 @@ #define IPA_HEADER_SIZE 3 #define IPA_OML_PROTO 0xFF
+#define TEMP_TIMER_SECS (6 * 3600) + 1
#include "utils.h" #include "eeprom.h" #include "l1_if.h" #include "hw_misc.h" #include "btsconfig.h" +#include <misc/sysmobts_misc.h>
/* FIXME: read from real hardware */ const uint8_t abis_mac[6] = { 0,1,2,3,4,5 }; @@ -297,6 +301,60 @@ static int write_pid_file(char *procname) return 0; } #ifdef BUILD_SBTS2050 +static int init_max_power_red; +static int new_max_power_red; +static int status_change_power_red = 0;
+enum {
- SBTS2050_DISABLE_CHANGE_POWER = 0,
- SBTS2050_ENABLE_CHANGE_POWER,
+};
+#define oml_tlv_parse(dec, buf, len) \
tlv_parse(dec, &abis_nm_att_tlvdef, buf, len, 0, 0)+/* Size of the struct plus 1 Bytes of tag and 2 Bytes for the length */ +#define tlv_add_info_len() (sizeof(struct sbts2050_config_info) + 3)
^^
Better?
#define TLV_INFO_LEN (sizeof(struct sbts2050_config_info) + 3)
The remaning part looks good to me.
Thanks Alvaro.
+static struct osmo_timer_list power_timer; +static void change_max_power_red_cb(void *data) +{
- struct gsm_bts *bts = data;
- if (status_change_power_red == SBTS2050_ENABLE_CHANGE_POWER) {
if (bts->c0->max_power_red != new_max_power_red) {init_max_power_red = bts->c0->max_power_red;bts->c0->max_power_red = new_max_power_red;}status_change_power_red = SBTS2050_DISABLE_CHANGE_POWER;osmo_timer_schedule(&power_timer, TEMP_TIMER_SECS, 0);- } else if (status_change_power_red == SBTS2050_DISABLE_CHANGE_POWER)
bts->c0->max_power_red = init_max_power_red;+}
+static int take_max_power_red(struct msgb *msg) +{
- struct sbts2050_config_info *config_info;
- struct tlv_parsed tlv_out;
- int rc;
- rc = oml_tlv_parse(&tlv_out, msg->tail - tlv_add_info_len(),
tlv_add_info_len());- if (rc < 0)
return -1;- config_info =
(struct sbts2050_config_info *) TLVP_VAL(&tlv_out, NM_ATT_ADD_INFO);- new_max_power_red = config_info->max_power_red;
- status_change_power_red = SBTS2050_ENABLE_CHANGE_POWER;
- change_max_power_red_cb(bts);
- return 0;
+}
static int test_recv_msg(struct msgb *msg) { struct ipaccess_head *hh = (struct ipaccess_head *)msg->data; @@ -355,6 +413,11 @@ static int read_sock(struct osmo_fd *fd, unsigned int what) return -1; }
- if (take_max_power_red(msg) < 0) {
LOGP(DL1C, LOGL_NOTICE, "Failed Add_info: Malformed message");return -1;- }
- mo = &bts->mo; msg->trx = mo->bts->c0;
@@ -478,6 +541,10 @@ int main(int argc, char **argv) read_fd.fd = -1; accept_fd.data = &read_fd;
- init_max_power_red = bts->c0->max_power_red;
- power_timer.cb = change_max_power_red_cb;
- power_timer.data = bts;
- rc = osmo_sock_unix_init_ofd(&accept_fd, SOCK_SEQPACKET, 0, SOCKET_PATH, OSMO_SOCK_F_BIND | OSMO_SOCK_F_NONBLOCK); if (rc < 0) {
-- 1.7.10.4
From: Álvaro Neira Ayuso anayuso@sysmocom.de
Added functions for changing the max_power_red in case of we receive a Failure Event report from the manager. The sbts2050 change the max_power_red to the value that we have configured in the manager and the sbts2050 restore this value to the initial value if the bts don't receive another Failure Event report in the same time that we check the temperature in the manager.
Signed-off-by: Alvaro Neira Ayuso anayuso@sysmocom.de --- [changes in v2] * Renamed the constant variable tlv_add_info_len() to TLV_INFO_LEN
src/osmo-bts-sysmo/main.c | 66 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+)
diff --git a/src/osmo-bts-sysmo/main.c b/src/osmo-bts-sysmo/main.c index 7e332ad..9ced374 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> @@ -54,11 +55,14 @@
#define IPA_OML_PROTO 0xFF
+#define TEMP_TIMER_SECS ((6 * 3600) + 1) + #include "utils.h" #include "eeprom.h" #include "l1_if.h" #include "hw_misc.h" #include "btsconfig.h" +#include <misc/sysmobts_misc.h>
/* FIXME: read from real hardware */ const uint8_t abis_mac[6] = { 0,1,2,3,4,5 }; @@ -297,6 +301,60 @@ static int write_pid_file(char *procname) }
#ifdef BUILD_SBTS2050 +static int init_max_power_red; +static int new_max_power_red; +static int status_change_power_red = 0; + +enum { + SBTS2050_DISABLE_CHANGE_POWER = 0, + SBTS2050_ENABLE_CHANGE_POWER, +}; + +#define oml_tlv_parse(dec, buf, len) \ + tlv_parse(dec, &abis_nm_att_tlvdef, buf, len, 0, 0) + +/* size of the struct plus 1 Bytes of tag and 2 Bytes for the length */ +#define TLV_ADD_INFO_LEN (sizeof(struct sbts2050_config_info) + 3) + +static struct osmo_timer_list power_timer; +static void change_max_power_red_cb(void *data) +{ + struct gsm_bts *bts = data; + + if (status_change_power_red == SBTS2050_ENABLE_CHANGE_POWER) { + if (bts->c0->max_power_red != new_max_power_red) { + init_max_power_red = bts->c0->max_power_red; + bts->c0->max_power_red = new_max_power_red; + } + status_change_power_red = SBTS2050_DISABLE_CHANGE_POWER; + osmo_timer_schedule(&power_timer, TEMP_TIMER_SECS, 0); + } else if (status_change_power_red == SBTS2050_DISABLE_CHANGE_POWER) + bts->c0->max_power_red = init_max_power_red; +} + +static int take_max_power_red(struct msgb *msg) +{ + struct sbts2050_config_info *config_info; + struct tlv_parsed tlv_out; + int rc; + + rc = oml_tlv_parse(&tlv_out, msg->tail - TLV_ADD_INFO_LEN, + TLV_ADD_INFO_LEN); + + if (rc < 0) + return -1; + + config_info = + (struct sbts2050_config_info *) TLVP_VAL(&tlv_out, NM_ATT_ADD_INFO); + + new_max_power_red = config_info->max_power_red; + + status_change_power_red = SBTS2050_ENABLE_CHANGE_POWER; + change_max_power_red_cb(bts); + + return 0; +} + static int test_recv_msg(struct msgb *msg) { struct ipaccess_head *hh; @@ -376,6 +434,11 @@ static int read_sock(struct osmo_fd *fd, unsigned int what) goto err; }
+ if (take_max_power_red(msg) < 0) { + LOGP(DL1C, LOGL_NOTICE, "Failed Add_info: Malformed message"); + goto err; + } + mo = &bts->mo; msg->trx = mo->bts->c0;
@@ -422,6 +485,9 @@ static int sbts2050_sock_unix_init(struct osmo_fd *accept, struct osmo_fd *read) read->fd = -1; accept->data = read;
+ power_timer.cb = change_max_power_red_cb; + power_timer.data = bts; + rc = osmo_sock_unix_init_ofd(accept, SOCK_SEQPACKET, 0, SOCKET_PATH, OSMO_SOCK_F_BIND | OSMO_SOCK_F_NONBLOCK); return rc;
From: Álvaro Neira Ayuso anayuso@sysmocom.de
Added functions for changing the max_power_red in case of we receive a Failure Event report from the manager. The sbts2050 change the max_power_red to the value that we have configured in the manager and the sbts2050 restore this value to the initial value if the bts don't receive another Failure Event report in the same time that we check the temperature in the manager.
Signed-off-by: Alvaro Neira Ayuso anayuso@sysmocom.de --- [changes in v3] * Changed LOGL_NOTICE with LOGL_ERROR in error cases.
src/osmo-bts-sysmo/main.c | 66 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+)
diff --git a/src/osmo-bts-sysmo/main.c b/src/osmo-bts-sysmo/main.c index b93667d..a4927f0 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> @@ -54,11 +55,14 @@
#define IPA_OML_PROTO 0xFF
+#define TEMP_TIMER_SECS ((6 * 3600) + 1) + #include "utils.h" #include "eeprom.h" #include "l1_if.h" #include "hw_misc.h" #include "btsconfig.h" +#include <misc/sysmobts_misc.h>
/* FIXME: read from real hardware */ const uint8_t abis_mac[6] = { 0,1,2,3,4,5 }; @@ -297,6 +301,60 @@ static int write_pid_file(char *procname) }
#ifdef BUILD_SBTS2050 +static int init_max_power_red; +static int new_max_power_red; +static int status_change_power_red = 0; + +enum { + SBTS2050_DISABLE_CHANGE_POWER = 0, + SBTS2050_ENABLE_CHANGE_POWER, +}; + +#define oml_tlv_parse(dec, buf, len) \ + tlv_parse(dec, &abis_nm_att_tlvdef, buf, len, 0, 0) + +/* size of the struct plus 1 Bytes of tag and 2 Bytes for the length */ +#define TLV_ADD_INFO_LEN (sizeof(struct sbts2050_config_info) + 3) + +static struct osmo_timer_list power_timer; +static void change_max_power_red_cb(void *data) +{ + struct gsm_bts *bts = data; + + if (status_change_power_red == SBTS2050_ENABLE_CHANGE_POWER) { + if (bts->c0->max_power_red != new_max_power_red) { + init_max_power_red = bts->c0->max_power_red; + bts->c0->max_power_red = new_max_power_red; + } + status_change_power_red = SBTS2050_DISABLE_CHANGE_POWER; + osmo_timer_schedule(&power_timer, TEMP_TIMER_SECS, 0); + } else if (status_change_power_red == SBTS2050_DISABLE_CHANGE_POWER) + bts->c0->max_power_red = init_max_power_red; +} + +static int take_max_power_red(struct msgb *msg) +{ + struct sbts2050_config_info *config_info; + struct tlv_parsed tlv_out; + int rc; + + rc = oml_tlv_parse(&tlv_out, msg->tail - TLV_ADD_INFO_LEN, + TLV_ADD_INFO_LEN); + + if (rc < 0) + return -1; + + config_info = + (struct sbts2050_config_info *) TLVP_VAL(&tlv_out, NM_ATT_ADD_INFO); + + new_max_power_red = config_info->max_power_red; + + status_change_power_red = SBTS2050_ENABLE_CHANGE_POWER; + change_max_power_red_cb(bts); + + return 0; +} + static int test_recv_msg(struct msgb *msg) { struct ipaccess_head *hh; @@ -392,6 +450,11 @@ static int read_sock(struct osmo_fd *fd, unsigned int what) goto err; }
+ if (take_max_power_red(msg) < 0) { + LOGP(DL1C, LOGL_ERROR, "Failed Add_info: Malformed message\n"); + goto err; + } + mo = &bts->mo; msg->trx = mo->bts->c0;
@@ -441,6 +504,9 @@ static int sbts2050_sock_unix_init(struct osmo_fd *accept, struct osmo_fd *read) read->fd = -1; accept->data = read;
+ power_timer.cb = change_max_power_red_cb; + power_timer.data = bts; + rc = osmo_sock_unix_init_ofd(accept, SOCK_SEQPACKET, 0, SOCKET_PATH, OSMO_SOCK_F_BIND | OSMO_SOCK_F_NONBLOCK); return rc;
From: Álvaro Neira Ayuso anayuso@sysmocom.de
Added functions for changing the max_power_red in case of we receive a Failure Event report from the manager. The sbts2050 change the max_power_red to the value that we have configured in the manager and the sbts2050 restore this value to the initial value if the bts don't receive another Failure Event report in the same time that we check the temperature in the manager.
Signed-off-by: Alvaro Neira Ayuso anayuso@sysmocom.de --- [changes in v4] * Changed the message in the log functions for using a incorrect message format
src/osmo-bts-sysmo/main.c | 66 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+)
diff --git a/src/osmo-bts-sysmo/main.c b/src/osmo-bts-sysmo/main.c index 98da626..a3be9a3 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> @@ -54,11 +55,14 @@
#define IPA_OML_PROTO 0xFF
+#define TEMP_TIMER_SECS ((6 * 3600) + 1) + #include "utils.h" #include "eeprom.h" #include "l1_if.h" #include "hw_misc.h" #include "btsconfig.h" +#include <misc/sysmobts_misc.h>
/* FIXME: read from real hardware */ const uint8_t abis_mac[6] = { 0,1,2,3,4,5 }; @@ -297,6 +301,60 @@ static int write_pid_file(char *procname) }
#ifdef BUILD_SBTS2050 +static int init_max_power_red; +static int new_max_power_red; +static int status_change_power_red = 0; + +enum { + SBTS2050_DISABLE_CHANGE_POWER = 0, + SBTS2050_ENABLE_CHANGE_POWER, +}; + +#define oml_tlv_parse(dec, buf, len) \ + tlv_parse(dec, &abis_nm_att_tlvdef, buf, len, 0, 0) + +/* size of the struct plus 1 Bytes of tag and 2 Bytes for the length */ +#define TLV_ADD_INFO_LEN (sizeof(struct sbts2050_config_info) + 3) + +static struct osmo_timer_list power_timer; +static void change_max_power_red_cb(void *data) +{ + struct gsm_bts *bts = data; + + if (status_change_power_red == SBTS2050_ENABLE_CHANGE_POWER) { + if (bts->c0->max_power_red != new_max_power_red) { + init_max_power_red = bts->c0->max_power_red; + bts->c0->max_power_red = new_max_power_red; + } + status_change_power_red = SBTS2050_DISABLE_CHANGE_POWER; + osmo_timer_schedule(&power_timer, TEMP_TIMER_SECS, 0); + } else if (status_change_power_red == SBTS2050_DISABLE_CHANGE_POWER) + bts->c0->max_power_red = init_max_power_red; +} + +static int take_max_power_red(struct msgb *msg) +{ + struct sbts2050_config_info *config_info; + struct tlv_parsed tlv_out; + int rc; + + rc = oml_tlv_parse(&tlv_out, msg->tail - TLV_ADD_INFO_LEN, + TLV_ADD_INFO_LEN); + + if (rc < 0) + return -1; + + config_info = + (struct sbts2050_config_info *) TLVP_VAL(&tlv_out, NM_ATT_ADD_INFO); + + new_max_power_red = config_info->max_power_red; + + status_change_power_red = SBTS2050_ENABLE_CHANGE_POWER; + change_max_power_red_cb(bts); + + return 0; +} + static int test_recv_msg(struct msgb *msg) { struct ipaccess_head *hh; @@ -392,6 +450,11 @@ static int read_sock(struct osmo_fd *fd, unsigned int what) goto err; }
+ if (take_max_power_red(msg) < 0) { + LOGP(DL1C, LOGL_ERROR, "Add_info Malformed message\n"); + goto err; + } + mo = &bts->mo; msg->trx = mo->bts->c0;
@@ -441,6 +504,9 @@ static int sbts2050_sock_unix_init(struct osmo_fd *accept, struct osmo_fd *read) read->fd = -1; accept->data = read;
+ power_timer.cb = change_max_power_red_cb; + power_timer.data = bts; + rc = osmo_sock_unix_init_ofd(accept, SOCK_SEQPACKET, 0, SOCKET_PATH, OSMO_SOCK_F_BIND | OSMO_SOCK_F_NONBLOCK); return rc;
On Sun, Apr 13, 2014 at 03:26:35PM +0200, Alvaro Neira Ayuso wrote:
From: Álvaro Neira Ayuso anayuso@sysmocom.de
Added functions for changing the max_power_red in case of we receive a Failure Event report from the manager. The sbts2050 change the max_power_red to the value that we have configured in the manager and the sbts2050 restore this value to the initial value if the bts don't receive another Failure Event report in the same time that we check the temperature in the manager.
Acked-by: Pablo Neira Ayuso pablo@gnumonks.org
From: Álvaro Neira Ayuso anayuso@sysmocom.de
Added functions for changing the max_power_red in case of we receive a Failure Event report from the manager. The sbts2050 change the max_power_red to the value that we have configured in the manager and the sbts2050 restore this value to the initial value if the bts don't receive another Failure Event report in the same time that we check the temperature in the manager.
Signed-off-by: Alvaro Neira Ayuso anayuso@sysmocom.de --- [changed in v5] * Added the function for updating the power transmitter * Changed the transmitter reduce power for using a relative value and not a absolute value.
src/osmo-bts-sysmo/main.c | 79 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+)
diff --git a/src/osmo-bts-sysmo/main.c b/src/osmo-bts-sysmo/main.c index 11e1878..3f2a20d 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> @@ -53,11 +54,14 @@
#define SYSMOBTS_RF_LOCK_PATH "/var/lock/bts_rf_lock"
+#define TEMP_TIMER_SECS ((6 * 3600) + 1) + #include "utils.h" #include "eeprom.h" #include "l1_if.h" #include "hw_misc.h" #include "btsconfig.h" +#include <misc/sysmobts_misc.h>
/* FIXME: read from real hardware */ const uint8_t abis_mac[6] = { 0,1,2,3,4,5 }; @@ -295,6 +299,73 @@ static int write_pid_file(char *procname) return 0; }
+static int reduce_max_power; +static int status_change_power_red; + +enum { + SBTS2050_DISABLE_CHANGE_POWER = 0, + SBTS2050_ENABLE_CHANGE_POWER, +}; + +#define oml_tlv_parse(dec, buf, len) \ + tlv_parse(dec, &abis_nm_att_tlvdef, buf, len, 0, 0) + +/* size of the struct plus 1 Bytes of tag and 2 Bytes for the length */ +#define TLV_ADD_INFO_LEN (sizeof(struct sbts2050_config_info) + 3) + +/********************************************************************** + * Function for change the transmitter power + *********************************************************************/ +static void update_transmiter_power(struct gsm_bts_trx *trx, int reduce_power) +{ + struct femtol1_hdl *fl1h = trx_femtol1_hdl(trx); + int power_transmitter = trx->nominal_power - trx->max_power_red; + + if (fl1h->hLayer1) + l1if_set_txpower(fl1h, power_transmitter - reduce_power); +} + +static struct osmo_timer_list power_timer; +static void change_transmitter_power_cb(void *data) +{ + struct gsm_bts *bts = data; + struct gsm_bts_trx *trx = bts->c0; + + if (status_change_power_red == SBTS2050_ENABLE_CHANGE_POWER) { + update_transmiter_power(trx, reduce_max_power); + status_change_power_red = SBTS2050_DISABLE_CHANGE_POWER; + osmo_timer_schedule(&power_timer, TEMP_TIMER_SECS, 0); + } else if (status_change_power_red == SBTS2050_DISABLE_CHANGE_POWER) + update_transmiter_power(trx, 0); +} + +/********************************************************************** + * Function for take the power that we have configured for + * reduce the transmitter power + *********************************************************************/ +static int take_max_power_red(struct msgb *msg) +{ + struct sbts2050_config_info *config_info; + struct tlv_parsed tlv_out; + int rc; + + rc = oml_tlv_parse(&tlv_out, msg->tail - TLV_ADD_INFO_LEN, + TLV_ADD_INFO_LEN); + + if (rc < 0) + return -1; + + config_info = + (struct sbts2050_config_info *) TLVP_VAL(&tlv_out, NM_ATT_ADD_INFO); + + reduce_max_power = config_info->reduce_max_power; + + status_change_power_red = SBTS2050_ENABLE_CHANGE_POWER; + change_transmitter_power_cb(bts); + + return 0; +} + /********************************************************************** * Function for checking that the OML msg received is well-formed *********************************************************************/ @@ -405,6 +476,11 @@ static int read_sock(struct osmo_fd *fd, unsigned int what) goto err; }
+ if (take_max_power_red(msg) < 0) { + LOGP(DL1C, LOGL_ERROR, "Add_info Malformed message\n"); + goto err; + } + mo = &bts->mo; msg->trx = mo->bts->c0;
@@ -459,6 +535,9 @@ static int oml_sock_unix_init(struct osmo_fd *accept, struct osmo_fd *read) read->fd = -1; accept->data = read;
+ power_timer.cb = change_transmitter_power_cb; + power_timer.data = bts; + rc = osmo_sock_unix_init_ofd(accept, SOCK_SEQPACKET, 0, SOCKET_PATH, OSMO_SOCK_F_BIND | OSMO_SOCK_F_NONBLOCK); return rc;
From: Álvaro Neira Ayuso anayuso@sysmocom.de
Added functions for changing the max_power_red in case of we receive a Failure Event report from the manager. The sbts2050 change the max_power_red to the value that we have configured in the manager and the sbts2050 restore this value to the initial value if the bts don't receive another Failure Event report in the same time that we check the temperature in the manager.
Signed-off-by: Alvaro Neira Ayuso anayuso@sysmocom.de --- [changes in v6] * Added the floor 0 when the reduce_power is bigger than nominal_power - max_power_red
src/osmo-bts-sysmo/main.c | 80 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+)
diff --git a/src/osmo-bts-sysmo/main.c b/src/osmo-bts-sysmo/main.c index aafbc50..269a64d 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> @@ -53,11 +54,14 @@
#define SYSMOBTS_RF_LOCK_PATH "/var/lock/bts_rf_lock"
+#define TEMP_TIMER_SECS ((6 * 3600) + 1) + #include "utils.h" #include "eeprom.h" #include "l1_if.h" #include "hw_misc.h" #include "btsconfig.h" +#include <misc/sysmobts_misc.h>
/* FIXME: read from real hardware */ const uint8_t abis_mac[6] = { 0,1,2,3,4,5 }; @@ -295,6 +299,74 @@ static int write_pid_file(char *procname) return 0; }
+static int reduce_max_power; +static int status_change_power_red; +static int last_power_transmitter = -1; +enum { + SBTS2050_DISABLE_CHANGE_POWER = 0, + SBTS2050_ENABLE_CHANGE_POWER, +}; + +#define oml_tlv_parse(dec, buf, len) \ + tlv_parse(dec, &abis_nm_att_tlvdef, buf, len, 0, 0) + +/* size of the struct plus 1 Bytes of tag and 2 Bytes for the length */ +#define TLV_ADD_INFO_LEN (sizeof(struct sbts2050_config_info) + 3) + +static void update_transmiter_power(struct gsm_bts_trx *trx, int reduce_power) +{ + struct femtol1_hdl *fl1h = trx_femtol1_hdl(trx); + int power_transmitter = trx->nominal_power - trx->max_power_red; + + power_transmitter -= reduce_power; + if (power_transmitter < 0) + power_transmitter = 0; + + if (last_power_transmitter != power_transmitter) { + if (fl1h->hLayer1) { + l1if_set_txpower(fl1h, power_transmitter); + last_power_transmitter = power_transmitter; + } + } +} + +static struct osmo_timer_list power_timer; +static void change_transmitter_power_cb(void *data) +{ + struct gsm_bts *bts = data; + struct gsm_bts_trx *trx = bts->c0; + + if (status_change_power_red == SBTS2050_ENABLE_CHANGE_POWER) { + update_transmiter_power(trx, reduce_max_power); + status_change_power_red = SBTS2050_DISABLE_CHANGE_POWER; + osmo_timer_schedule(&power_timer, TEMP_TIMER_SECS, 0); + } else if (status_change_power_red == SBTS2050_DISABLE_CHANGE_POWER) + update_transmiter_power(trx, 0); +} + +static int take_max_power_red(struct msgb *msg) +{ + struct sbts2050_config_info *config_info; + struct tlv_parsed tlv_out; + int rc; + + rc = oml_tlv_parse(&tlv_out, msg->tail - TLV_ADD_INFO_LEN, + TLV_ADD_INFO_LEN); + + if (rc < 0) + return -1; + + config_info = + (struct sbts2050_config_info *) TLVP_VAL(&tlv_out, NM_ATT_ADD_INFO); + + reduce_max_power = config_info->reduce_max_power; + + status_change_power_red = SBTS2050_ENABLE_CHANGE_POWER; + change_transmitter_power_cb(bts); + + return 0; +} + /* * In succesfully case, this function set again the pointers of the l2h and l3h * of the OML message that we have received. In other case, we don't set the @@ -404,6 +476,11 @@ static int read_sock(struct osmo_fd *fd, unsigned int what) goto err; }
+ if (take_max_power_red(msg) < 0) { + LOGP(DL1C, LOGL_ERROR, "Add_info Malformed message\n"); + goto err; + } + mo = &bts->mo; msg->trx = mo->bts->c0;
@@ -452,6 +529,9 @@ static int oml_sock_unix_init(struct osmo_fd *accept, struct osmo_fd *read) read->fd = -1; accept->data = read;
+ power_timer.cb = change_transmitter_power_cb; + power_timer.data = bts; + rc = osmo_sock_unix_init_ofd(accept, SOCK_SEQPACKET, 0, SOCKET_PATH, OSMO_SOCK_F_BIND | OSMO_SOCK_F_NONBLOCK); return rc;
On Wed, Apr 16, 2014 at 02:09:39PM +0200, Alvaro Neira Ayuso wrote:
+static void update_transmiter_power(struct gsm_bts_trx *trx, int reduce_power) +{
- struct femtol1_hdl *fl1h = trx_femtol1_hdl(trx);
- int power_transmitter = trx->nominal_power - trx->max_power_red;
- power_transmitter -= reduce_power;
- if (power_transmitter < 0)
power_transmitter = 0;
This would be third place we calculate "trx->nominal_power - trx->max_power_red". The code is also fragile in regard to a sequence like this:
1.) BTS is powering up with lower power output 2.) It gets too hot already and the manager reduces the power 3.) BTS is increasing the power.
With 3rd your reduction in 2nd would be undone. The right and safe way to handle it is to:
* Store the manager power reduction in another variable (e.g. inside the fl1h or the trx) * Assign this variable * Have one function that works on the trx and returns you the nominal power to be used by the DSP/FPGA.
This way the order of power reduction changes does not matter.
- if (last_power_transmitter != power_transmitter) {
if (fl1h->hLayer1) {l1if_set_txpower(fl1h, power_transmitter);last_power_transmitter = power_transmitter;
global state? Why is that needed?
+static struct osmo_timer_list power_timer; +static void change_transmitter_power_cb(void *data) +{
- struct gsm_bts *bts = data;
- struct gsm_bts_trx *trx = bts->c0;
- if (status_change_power_red == SBTS2050_ENABLE_CHANGE_POWER) {
update_transmiter_power(trx, reduce_max_power);status_change_power_red = SBTS2050_DISABLE_CHANGE_POWER;osmo_timer_schedule(&power_timer, TEMP_TIMER_SECS, 0);- } else if (status_change_power_red == SBTS2050_DISABLE_CHANGE_POWER)
update_transmiter_power(trx, 0);+}
+static int take_max_power_red(struct msgb *msg) +{
- struct sbts2050_config_info *config_info;
- struct tlv_parsed tlv_out;
- int rc;
- rc = oml_tlv_parse(&tlv_out, msg->tail - TLV_ADD_INFO_LEN,
TLV_ADD_INFO_LEN);- if (rc < 0)
return -1;- config_info =
(struct sbts2050_config_info *) TLVP_VAL(&tlv_out, NM_ATT_ADD_INFO);- reduce_max_power = config_info->reduce_max_power;
- status_change_power_red = SBTS2050_ENABLE_CHANGE_POWER;
- change_transmitter_power_cb(bts);
- return 0;
+}
Why do we need a timer in the sysmobts binary? If the switching of the power should be delayed, the manager should do this as part of the management.
From: Álvaro Neira Ayuso anayuso@sysmocom.de
Added functions for changing the power transmitter in case of we receive a Failure Event report from the manager. The sbts2050 decress the power transmitter with the value that we have configured in the manager. For doing that the manager send a OML message with the power that we want to decress in warning case and too send another OML message for restoring the power transmitter.
Signed-off-by: Alvaro Neira Ayuso anayuso@sysmocom.de --- [changes in v7] * Changed the reduce support. Now, We have the timer in the manager and in warning case, we will send a OML MANUF message to the BTS for saying that the BTS need to reduce the power with the value that we have configured in the manager. If everything is correct on the BTS, the BTS send a ACK to the manager for confirm that the power has been updated. In other case, the BTS send a NACK.
src/osmo-bts-sysmo/main.c | 123 ++++++++++++++++++++++++++++++- src/osmo-bts-sysmo/misc/sysmobts_mgr.c | 32 +++++--- src/osmo-bts-sysmo/misc/sysmobts_mgr.h | 9 +++ src/osmo-bts-sysmo/misc/sysmobts_misc.c | 69 +++++++++++++++++ src/osmo-bts-sysmo/misc/sysmobts_misc.h | 2 + 5 files changed, 224 insertions(+), 11 deletions(-)
diff --git a/src/osmo-bts-sysmo/main.c b/src/osmo-bts-sysmo/main.c index acdf6fc..695bdaa 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,107 @@ 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) { + /* 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(*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, "Error writting in unix socket\n"); + close(fd_unix); + msgb_free(msg); + return -1; + } + + 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(osmobts_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_SBTS_REDUCEPOWER)) + recv_reduce_power = *TLVP_VAL(&tlv_out, + NM_ATT_SBTS_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(); @@ -323,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 99e95d5..bb9bcac 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 = { #ifdef BUILD_SBTS2050 static int trx_nr = -1; static int state_connection; +static int status_change_power_red;
static struct osmo_timer_list connect_timer; static void socket_connect_cb(void *data) @@ -138,17 +139,18 @@ 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, @@ -156,11 +158,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, @@ -168,6 +170,16 @@ static void check_uctemp_timer_cb(void *data) temp_board, SBTS2050_TEMP_BOARD, SBTS2050_SEVERE_ALERT);
+ if ((pa_warning || board_warning) && + status_change_power_red == SBTS2050_DISABLE_CHANGE_POWER) { + status_change_power_red = SBTS2050_ENABLE_CHANGE_POWER; + send_omlreduce(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_omlreduce(fd_unix, 0, trx_nr); + } + 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..cf549fe 100644 --- a/src/osmo-bts-sysmo/misc/sysmobts_mgr.h +++ b/src/osmo-bts-sysmo/misc/sysmobts_mgr.h @@ -15,8 +15,17 @@ enum { SYSMO_MGR_CONNECTED, };
+enum { + SBTS2050_DISABLE_CHANGE_POWER = 0, + SBTS2050_ENABLE_CHANGE_POWER, +}; + #define SOCKET_PATH "/var/run/bts_oml"
+enum { + NM_ATT_SBTS_REDUCEPOWER = 0x1b, +}; + struct sbts2050_config_info;
enum mgr_vty_node { diff --git a/src/osmo-bts-sysmo/misc/sysmobts_misc.c b/src/osmo-bts-sysmo/misc/sysmobts_misc.c index fbbd6ee..4023b01 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_omlreduce_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]; @@ -116,6 +133,58 @@ static void add_oml_hdr_msg(struct msgb *msg, uint8_t msg_type, omh->length = msgb_l3len(msg); }
+int send_omlreduce(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, 0, 0, trx_nr, 0, 1); + + msgb_tv_put(msg, NM_ATT_SBTS_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, "Error writting to unix socket\n"); + goto err; + } + + msgb_reset(msg); + rc = recv(fd_unix, msg->tail, msg->data_len, 0); + if (rc <= 0) { + LOGP(DTEMP, LOGL_ERROR, "Error reading from unix socket\n"); + goto err; + } + msgb_put(msg, rc); + + if (check_oml_msg(msg) < 0) { + close(fd_unix); + msgb_free(msg); + return -1; + } + + if (check_omlreduce_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..158e7a2 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_omlreduce(int fd_unix, int reduce_power, int trx_nr); + int sysmobts_update_hours(int no_epprom_write);
enum sysmobts_firmware_type {
From: Álvaro Neira Ayuso anayuso@sysmocom.de
Added functions for changing the power transmitter in case of we receive a Failure Event report from the manager. The sbts2050 decress the power transmitter with the value that we have configured in the manager. For doing that the manager send a OML message with the power that we want to decress in warning case and too send another OML message for restoring the power transmitter.
Signed-off-by: Alvaro Neira Ayuso anayuso@sysmocom.de --- [changes in v8] * Changed the variable NM_ATT_SBTS_REDUCEPOWER to NM_ATT_O_REDUCEPOWER
src/osmo-bts-sysmo/main.c | 123 ++++++++++++++++++++++++++++++- src/osmo-bts-sysmo/misc/sysmobts_mgr.c | 32 +++++--- src/osmo-bts-sysmo/misc/sysmobts_mgr.h | 5 ++ src/osmo-bts-sysmo/misc/sysmobts_misc.c | 69 +++++++++++++++++ src/osmo-bts-sysmo/misc/sysmobts_misc.h | 2 + 5 files changed, 220 insertions(+), 11 deletions(-)
diff --git a/src/osmo-bts-sysmo/main.c b/src/osmo-bts-sysmo/main.c index acdf6fc..76305be 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,107 @@ 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) { + /* 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(*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, "Error writting in unix socket\n"); + close(fd_unix); + msgb_free(msg); + return -1; + } + + 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(); @@ -323,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 99e95d5..bb9bcac 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 = { #ifdef BUILD_SBTS2050 static int trx_nr = -1; static int state_connection; +static int status_change_power_red;
static struct osmo_timer_list connect_timer; static void socket_connect_cb(void *data) @@ -138,17 +139,18 @@ 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, @@ -156,11 +158,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, @@ -168,6 +170,16 @@ static void check_uctemp_timer_cb(void *data) temp_board, SBTS2050_TEMP_BOARD, SBTS2050_SEVERE_ALERT);
+ if ((pa_warning || board_warning) && + status_change_power_red == SBTS2050_DISABLE_CHANGE_POWER) { + status_change_power_red = SBTS2050_ENABLE_CHANGE_POWER; + send_omlreduce(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_omlreduce(fd_unix, 0, trx_nr); + } + 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 2030888..14b2985 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_omlreduce_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]; @@ -116,6 +133,58 @@ static void add_oml_hdr_msg(struct msgb *msg, uint8_t msg_type, omh->length = msgb_l3len(msg); }
+int send_omlreduce(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, "Error writting to unix socket\n"); + goto err; + } + + msgb_reset(msg); + rc = recv(fd_unix, msg->tail, msg->data_len, 0); + if (rc <= 0) { + LOGP(DTEMP, LOGL_ERROR, "Error reading from unix socket\n"); + goto err; + } + msgb_put(msg, rc); + + if (check_oml_msg(msg) < 0) { + close(fd_unix); + msgb_free(msg); + return -1; + } + + if (check_omlreduce_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..158e7a2 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_omlreduce(int fd_unix, int reduce_power, int trx_nr); + int sysmobts_update_hours(int no_epprom_write);
enum sysmobts_firmware_type {
On Mon, May 05, 2014 at 04:22:59PM +0200, Alvaro Neira Ayuso wrote:
From: Álvaro Neira Ayuso anayuso@sysmocom.de
Added functions for changing the power transmitter in case of we receive
transmit power?
a Failure Event report from the manager. The sbts2050 decress the
This is not what happens. Is it? The manager will ask for the power being reduced. It is not related to a OML Failure Event report.
decress.. do you mean decrease?
power transmitter with the value that we have configured in the manager.
- 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));- }
Same as in the other mail. Maybe even share this with a function to put the osmocom manufacturer header.
- 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 -1;- }
- return rc;
Are you leaking the msgb here? I think I saw similar code in the previous patch. For previous leaks I asked you to send the messages in a loop to make it obvious that some meoyr is leaked..
- if ((pa_warning || board_warning) &&
status_change_power_red == SBTS2050_DISABLE_CHANGE_POWER) {status_change_power_red = SBTS2050_ENABLE_CHANGE_POWER;send_omlreduce(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_omlreduce(fd_unix, 0, trx_nr);- }
Move this into a method. We certainly will change the code in the future to not just go from 0 to X for power changes. The method should take pa_warning, board_warning, the state and it should return -1 if no change is required and otherwise the power it should be reduced to.
- rc = recv(fd_unix, msg->tail, msg->data_len, 0);
- if (rc <= 0) {
LOGP(DTEMP, LOGL_ERROR, "Error reading from unix socket\n");
print the kind of error like in the error log messages.
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 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 <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,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 {
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(-)
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 {
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?
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
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.
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
Hi Alvaro,
On Tue, Apr 08, 2014 at 02:40:35PM +0200, Alvaro Neira Ayuso wrote:
+#define oml_tlv_parse(dec, buf, len) \
tlv_parse(dec, &abis_nm_att_tlvdef, buf, len, 0, 0)
by doing so, you are using abis_nm_att_tlvdef, which is defining 0x01 as NM_ATT_ABIS_CHANNEL, which is a fixed-size attribute of 3 bytes length. That's quite something else than what you need, isn't it?
I've introduced abis_nm_att_osmo_tlvdef[] in libosmocore. Please either use tlv_def_patch() to merge abis_nm_att_osmo_tlvdef with abis_nm_att_tlvdef before calling tlv_parse from generic code. Or, if you are sure that only a org.osmocom specific message can arrive, you may use abis_nm_att_osmo_tlvdef directly.
+static int take_reduce_power(struct msgb *msg)
this function takes the msgb pointer, even though from where it is called in read_sock():
+ fom = (struct abis_om_fom_hdr *) msg->l3h;
+ switch (fom->msg_type) { + case NM_MT_SET_RADIO_ATTR: + rc = take_reduce_power(msg);
we already had computed the exact location of 'fom'.
Now in take_reduce_power, you do the following:
+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;
so you basically make blind assumptions that there is na osmocom_magic and its associated length.
However, the check_oml_msg() that you wrote accepts both the com.ipaccess and the org.osmocom magic values. So
a) a com.ipaccess message might end up in take_reduce_power() b) your static assumption that an osmocom magic being present is not true.
Please properly think about such logic.
It might be best if the check_oml_message or similar would return some information (or even store it in the msgb_cb() somewhere) which of the vendor specific messages (if any) it has detected. Later code could then base its processing on that distinction.
Also, as you had already resolved the fom pointer (from msg->l3,), thre is no point in starting to calculate abis_oml_hdr_len again (and wrongly).
Finally, regarding check_oml_msg(): It actually doedn't only check an OML message, but it checks also the IPA headre in front. Please create one function for one purpose. The check_oml_msg() shouldn't care about the ipaccess_head in front. If we make it more generic, we can move it to libosmocore as a general OML header sanity checking function. But that's not possible right now as it depends on an ipaccess_head, which is not present in E1 based OML.
Also, +int add_manufacturer_id_label(struct msgb *msg, int manuf_type_id)
why use an int there? You have defined an 'enum manuf_type_id', please use it :)
Regards, Harald