ctrl/abis: When the max_power_reduction changes, send it to the BTS

In case the max_power_reduction changes, issue a new Set Radio
Carrier Attributes command. OML 12.21 allows to not include the
ARFCN list and the semantic I picked/understand is that a partial
update is possible.

Fixes: SYS#267
diff --git a/openbsc/src/libbsc/abis_nm.c b/openbsc/src/libbsc/abis_nm.c
index f491a0c..5a96849 100644
--- a/openbsc/src/libbsc/abis_nm.c
+++ b/openbsc/src/libbsc/abis_nm.c
@@ -1466,6 +1466,12 @@
 	return abis_nm_sendmsg(trx->bts, msg);
 }
 
+int abis_nm_update_max_power_red(struct gsm_bts_trx *trx)
+{
+	uint8_t attr[] = { NM_ATT_RF_MAXPOWR_R, trx->max_power_red / 2 };
+	return abis_nm_set_radio_attr(trx, attr, ARRAY_SIZE(attr));
+}
+
 static int verify_chan_comb(struct gsm_bts_trx_ts *ts, uint8_t chan_comb,
 			const char **reason)
 {
diff --git a/openbsc/src/libbsc/bsc_ctrl_commands.c b/openbsc/src/libbsc/bsc_ctrl_commands.c
index 5959d27..3759593 100644
--- a/openbsc/src/libbsc/bsc_ctrl_commands.c
+++ b/openbsc/src/libbsc/bsc_ctrl_commands.c
@@ -22,6 +22,8 @@
 #include <openbsc/control_cmd.h>
 #include <openbsc/ipaccess.h>
 #include <openbsc/gsm_data.h>
+#include <openbsc/abis_nm.h>
+#include <openbsc/debug.h>
 
 #define CTRL_CMD_VTY_STRING(cmdname, cmdstr, dtype, element) \
 	CTRL_HELPER_GET_STRING(cmdname, dtype, element) \
@@ -153,7 +155,6 @@
 
 /* TRX related commands below here */
 CTRL_HELPER_GET_INT(trx_max_power, struct gsm_bts_trx, max_power_red);
-CTRL_HELPER_SET_INT(trx_max_power, struct gsm_bts_trx, max_power_red);
 static int verify_trx_max_power(struct ctrl_cmd *cmd, const char *value, void *_data)
 {
 	int tmp = atoi(value);
@@ -170,6 +171,26 @@
 
 	return 0;
 }
+
+static int set_trx_max_power(struct ctrl_cmd *cmd, void *_data)
+{
+	struct gsm_bts_trx *trx = cmd->node;
+	int old_power;
+
+	/* remember the old value, set the new one */
+	old_power = trx->max_power_red;
+	trx->max_power_red = atoi(cmd->value);
+
+	/* Maybe update the value */
+	if (old_power != trx->max_power_red) {
+		LOGP(DCTRL, LOGL_NOTICE,
+			"%s updating max_pwr_red(%d)\n",
+			gsm_trx_name(trx), trx->max_power_red);
+		abis_nm_update_max_power_red(trx);
+	}
+
+	return get_trx_max_power(cmd, _data);
+}
 CTRL_CMD_DEFINE(trx_max_power, "max-power-reduction");
 
 int bsc_base_ctrl_cmds_install(void)