aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/osmo-bts-trx/l1_if.h3
-rw-r--r--src/osmo-bts-trx/trx_if.c18
2 files changed, 19 insertions, 2 deletions
diff --git a/src/osmo-bts-trx/l1_if.h b/src/osmo-bts-trx/l1_if.h
index d978c44d..e7b53866 100644
--- a/src/osmo-bts-trx/l1_if.h
+++ b/src/osmo-bts-trx/l1_if.h
@@ -3,6 +3,7 @@
#include <osmo-bts/scheduler.h>
#include <osmo-bts/phy_link.h>
+#include "trx_if.h"
struct trx_config {
uint8_t poweron; /* poweron(1) or poweroff(0) */
@@ -46,6 +47,8 @@ struct trx_config {
struct trx_l1h {
struct llist_head trx_ctrl_list;
+ /* Latest RSPed cmd, used to catch duplicate RSPs from sent retransmissions */
+ struct trx_ctrl_msg *last_acked;
//struct gsm_bts_trx *trx;
struct phy_instance *phy_inst;
diff --git a/src/osmo-bts-trx/trx_if.c b/src/osmo-bts-trx/trx_if.c
index a8026d49..35698ef5 100644
--- a/src/osmo-bts-trx/trx_if.c
+++ b/src/osmo-bts-trx/trx_if.c
@@ -455,6 +455,12 @@ static int trx_ctrl_read_cb(struct osmo_fd *ofd, unsigned int what)
/* get command for response message */
if (llist_empty(&l1h->trx_ctrl_list)) {
+ /* RSP from a retransmission, skip it */
+ if (l1h->last_acked && cmd_matches_rsp(l1h->last_acked, cmdname, params)) {
+ LOGP(DTRX, LOGL_NOTICE, "Discarding duplicated RSP "
+ "from old CMD '%s'\n", buf);
+ return 0;
+ }
LOGP(DTRX, LOGL_NOTICE, "Response message without "
"command\n");
return -EINVAL;
@@ -464,6 +470,12 @@ static int trx_ctrl_read_cb(struct osmo_fd *ofd, unsigned int what)
/* check if response matches command */
if (!cmd_matches_rsp(tcm, cmdname, params)) {
+ /* RSP from a retransmission, skip it */
+ if (l1h->last_acked && cmd_matches_rsp(l1h->last_acked, cmdname, params)) {
+ LOGP(DTRX, LOGL_NOTICE, "Discarding duplicated RSP "
+ "from old CMD '%s'\n", buf);
+ return 0;
+ }
LOGP(DTRX, (tcm->critical) ? LOGL_FATAL : LOGL_NOTICE,
"Response message '%s' does not match command "
"message 'CMD %s%s%s'\n",
@@ -481,9 +493,10 @@ static int trx_ctrl_read_cb(struct osmo_fd *ofd, unsigned int what)
goto rsp_error;
}
- /* remove command from list */
+ /* remove command from list, save it to last_acked and removed previous last_acked */
llist_del(&tcm->list);
- talloc_free(tcm);
+ talloc_free(l1h->last_acked);
+ l1h->last_acked = tcm;
trx_ctrl_send(l1h);
@@ -621,6 +634,7 @@ void trx_if_flush(struct trx_l1h *l1h)
llist_del(&tcm->list);
talloc_free(tcm);
}
+ talloc_free(l1h->last_acked);
}
/*! close the TRX for given handle (data + control socket) */