blob: d9b280faf0e8663aa834eefdd5a73f4fcafccc9a [file] [log] [blame]
Andreas Eversberg050ace22013-03-16 16:22:02 +01001/* Measurements
2 *
3 * Copyright (C) 2012 Andreas Eversberg <jolly@eversberg.eu>
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 */
Pau Espin Pedrol488aa292019-09-25 17:48:35 +020019
Vadim Yanitskiyd2e50e72020-03-29 01:46:27 +070020extern "C" {
Stefan Sperling78ab6242018-05-31 12:28:55 +020021#include <osmocom/core/timer_compat.h>
Vadim Yanitskiyd2e50e72020-03-29 01:46:27 +070022}
Stefan Sperling78ab6242018-05-31 12:28:55 +020023
Andreas Eversberg050ace22013-03-16 16:22:02 +010024#include <gprs_rlcmac.h>
25#include <gprs_debug.h>
26#include <pcu_l1_if.h>
Holger Hans Peter Freyther099535a2013-10-16 17:42:31 +020027#include <tbf.h>
Pau Espin Pedrol9d1cdb12019-09-25 17:47:02 +020028#include <tbf_dl.h>
Pau Espin Pedrolf2dad592020-08-18 20:26:25 +020029#include <gprs_ms.h>
Pau Espin Pedroldeed90d2021-05-26 13:17:01 +020030#include <ms_anr_fsm.h>
Andreas Eversberg050ace22013-03-16 16:22:02 +010031
32#include <string.h>
33#include <errno.h>
34
35/*
36 * downlink measurement
37 */
Max5a6bcfb2017-09-01 14:36:44 +020038/* TODO: trigger the measurement report from the pollcontroller and use it for flow control */
Andreas Eversberg050ace22013-03-16 16:22:02 +010039
40/* received Measurement Report */
Pau Espin Pedrolb69928c2020-08-18 20:29:40 +020041int gprs_rlcmac_meas_rep(GprsMs *ms, Packet_Measurement_Report_t *pmr)
Andreas Eversberg050ace22013-03-16 16:22:02 +010042{
43 NC_Measurement_Report_t *ncr;
44 NC_Measurements_t *nc;
45 int i;
Pau Espin Pedroldeed90d2021-05-26 13:17:01 +020046 int rc = 0;
Andreas Eversberg050ace22013-03-16 16:22:02 +010047
Pau Espin Pedrolb69928c2020-08-18 20:29:40 +020048 LOGPMS(ms, DRLCMACMEAS, LOGL_INFO, "Rx Measurement Report:");
Andreas Eversberg050ace22013-03-16 16:22:02 +010049
50 switch (pmr->UnionType) {
51 case 0:
52 ncr = &pmr->u.NC_Measurement_Report;
53 LOGPC(DRLCMACMEAS, LOGL_INFO, " NC%u Serv %d dbm",
54 ncr->NC_MODE + 1,
55 ncr->Serving_Cell_Data.RXLEV_SERVING_CELL - 110);
56 for (i = 0; i < ncr->NUMBER_OF_NC_MEASUREMENTS; i++) {
57 nc = &ncr->NC_Measurements[i];
58 LOGPC(DRLCMACMEAS, LOGL_DEBUG, ", Neigh %u %d dbm",
59 nc->FREQUENCY_N, nc->RXLEV_N - 110);
60 }
61 LOGPC(DRLCMACMEAS, LOGL_INFO, "\n");
62
63 break;
64 case 1:
65 LOGPC(DRLCMACMEAS, LOGL_INFO,
66 " <EXT Reporting not supported!>\n");
67 break;
68 }
69
Pau Espin Pedroldeed90d2021-05-26 13:17:01 +020070 if (ms->anr && ms->anr->fi->state == MS_ANR_ST_WAIT_PKT_MEAS_REPORT)
71 rc = osmo_fsm_inst_dispatch(ms->anr->fi, MS_ANR_EV_RX_PKT_MEAS_REPORT, pmr);
72 return rc;
Andreas Eversberg050ace22013-03-16 16:22:02 +010073}
74
75
76/*
77 * uplink measurement
78 */
79
80/* RSSI values received from MS */
81int gprs_rlcmac_rssi(struct gprs_rlcmac_tbf *tbf, int8_t rssi)
82{
Stefan Sperlingf0f7df12018-05-25 15:12:30 +020083 struct timespec now_tv, *rssi_tv = &tbf->meas.rssi_tv;
Stefan Sperling78ab6242018-05-31 12:28:55 +020084 struct timespec elapsed;
Andreas Eversberg050ace22013-03-16 16:22:02 +010085
86 tbf->meas.rssi_sum += rssi;
87 tbf->meas.rssi_num++;
88
Stefan Sperlingf0f7df12018-05-25 15:12:30 +020089 osmo_clock_gettime(CLOCK_MONOTONIC, &now_tv);
Stefan Sperling78ab6242018-05-31 12:28:55 +020090
91 timespecsub(&now_tv, rssi_tv, &elapsed);
92 if (elapsed.tv_sec < 1)
Andreas Eversberg050ace22013-03-16 16:22:02 +010093 return 0;
94
95 gprs_rlcmac_rssi_rep(tbf);
96
97 /* reset rssi values and timestamp */
Stefan Sperlingf0f7df12018-05-25 15:12:30 +020098 memcpy(rssi_tv, &now_tv, sizeof(*rssi_tv));
Andreas Eversberg050ace22013-03-16 16:22:02 +010099 tbf->meas.rssi_sum = 0;
100 tbf->meas.rssi_num = 0;
101
102 return 0;
103}
104
105/* Give RSSI report */
106int gprs_rlcmac_rssi_rep(struct gprs_rlcmac_tbf *tbf)
107{
108 /* No measurement values */
109 if (!tbf->meas.rssi_num)
110 return -EINVAL;
111
Pau Espin Pedrolf2dad592020-08-18 20:26:25 +0200112 LOGPMS(tbf->ms(), DRLCMACMEAS, LOGL_INFO, "UL RSSI: %d dBm\n",
113 tbf->meas.rssi_sum / tbf->meas.rssi_num);
Andreas Eversberg050ace22013-03-16 16:22:02 +0100114
115 return 0;
116}
117
118
119/*
120 * lost frames
121 */
122
123/* Lost frames reported from RLCMAC layer */
Daniel Willmann418a4232014-08-08 11:21:04 +0200124int gprs_rlcmac_received_lost(struct gprs_rlcmac_dl_tbf *tbf, uint16_t received,
Andreas Eversberg050ace22013-03-16 16:22:02 +0100125 uint16_t lost)
126{
Stefan Sperlingf0f7df12018-05-25 15:12:30 +0200127 struct timespec now_tv, *loss_tv = &tbf->m_bw.dl_loss_tv;
Stefan Sperling78ab6242018-05-31 12:28:55 +0200128 struct timespec elapsed;
Andreas Eversberg050ace22013-03-16 16:22:02 +0100129 uint16_t sum = received + lost;
130
131 /* No measurement values */
132 if (!sum)
133 return -EINVAL;
134
135 LOGP(DRLCMACMEAS, LOGL_DEBUG, "DL Loss of TLLI 0x%08x: Received: %4d "
Holger Hans Peter Freyther474685e2013-10-27 17:01:14 +0100136 "Lost: %4d Sum: %4d\n", tbf->tlli(), received, lost, sum);
Andreas Eversberg050ace22013-03-16 16:22:02 +0100137
Daniel Willmann418a4232014-08-08 11:21:04 +0200138 tbf->m_bw.dl_loss_received += received;
139 tbf->m_bw.dl_loss_lost += lost;
Andreas Eversberg050ace22013-03-16 16:22:02 +0100140
Harald Welte099f4f22018-10-21 11:50:10 +0200141 osmo_clock_gettime(CLOCK_MONOTONIC, &now_tv);
Stefan Sperling78ab6242018-05-31 12:28:55 +0200142 timespecsub(&now_tv, loss_tv, &elapsed);
143 if (elapsed.tv_sec < 1)
Andreas Eversberg050ace22013-03-16 16:22:02 +0100144 return 0;
145
146 gprs_rlcmac_lost_rep(tbf);
147
148 /* reset lost values and timestamp */
Stefan Sperlingf0f7df12018-05-25 15:12:30 +0200149 memcpy(loss_tv, &now_tv, sizeof(*loss_tv));
Daniel Willmann418a4232014-08-08 11:21:04 +0200150 tbf->m_bw.dl_loss_received = 0;
151 tbf->m_bw.dl_loss_lost = 0;
Andreas Eversberg050ace22013-03-16 16:22:02 +0100152
153 return 0;
154}
155
156/* Give Lost report */
Daniel Willmann418a4232014-08-08 11:21:04 +0200157int gprs_rlcmac_lost_rep(struct gprs_rlcmac_dl_tbf *tbf)
Andreas Eversberg050ace22013-03-16 16:22:02 +0100158{
Daniel Willmann418a4232014-08-08 11:21:04 +0200159 uint16_t sum = tbf->m_bw.dl_loss_lost + tbf->m_bw.dl_loss_received;
Andreas Eversberg050ace22013-03-16 16:22:02 +0100160
161 /* No measurement values */
162 if (!sum)
163 return -EINVAL;
164
Stefan Sperling082443d2018-06-05 11:37:00 +0200165 LOGP(DRLCMACMEAS, LOGL_DEBUG, "DL packet loss of IMSI=%s / TLLI=0x%08x: "
Holger Hans Peter Freyther5464c9b2013-10-27 20:57:35 +0100166 "%d%%\n", tbf->imsi(), tbf->tlli(),
Daniel Willmann418a4232014-08-08 11:21:04 +0200167 tbf->m_bw.dl_loss_lost * 100 / sum);
Andreas Eversberg050ace22013-03-16 16:22:02 +0100168
169 return 0;
170}
171
172
173/*
174 * downlink bandwidth
175 */
176
Daniel Willmann418a4232014-08-08 11:21:04 +0200177int gprs_rlcmac_dl_bw(struct gprs_rlcmac_dl_tbf *tbf, uint16_t octets)
Andreas Eversberg050ace22013-03-16 16:22:02 +0100178{
Stefan Sperlingf0f7df12018-05-25 15:12:30 +0200179 struct timespec now_tv, *bw_tv = &tbf->m_bw.dl_bw_tv;
Stefan Sperling78ab6242018-05-31 12:28:55 +0200180 struct timespec elapsed;
Andreas Eversberg050ace22013-03-16 16:22:02 +0100181
Daniel Willmann418a4232014-08-08 11:21:04 +0200182 tbf->m_bw.dl_bw_octets += octets;
Andreas Eversberg050ace22013-03-16 16:22:02 +0100183
Stefan Sperlingf0f7df12018-05-25 15:12:30 +0200184 osmo_clock_gettime(CLOCK_MONOTONIC, &now_tv);
Stefan Sperling78ab6242018-05-31 12:28:55 +0200185 timespecsub(&now_tv, bw_tv, &elapsed);
186 if (elapsed.tv_sec < 1)
Andreas Eversberg050ace22013-03-16 16:22:02 +0100187 return 0;
188
Stefan Sperling78ab6242018-05-31 12:28:55 +0200189 tbf->m_bw.dl_throughput = (tbf->m_bw.dl_bw_octets << 10) / ((elapsed.tv_sec << 10) + (elapsed.tv_nsec >> 20));
Andreas Eversberg050ace22013-03-16 16:22:02 +0100190 LOGP(DRLCMACMEAS, LOGL_INFO, "DL Bandwitdh of IMSI=%s / TLLI=0x%08x: "
Stefan Sperling78ab6242018-05-31 12:28:55 +0200191 "%d KBits/s\n", tbf->imsi(), tbf->tlli(), tbf->m_bw.dl_throughput);
Andreas Eversberg050ace22013-03-16 16:22:02 +0100192
193 /* reset bandwidth values timestamp */
Stefan Sperlingf0f7df12018-05-25 15:12:30 +0200194 memcpy(bw_tv, &now_tv, sizeof(*bw_tv));
Daniel Willmann418a4232014-08-08 11:21:04 +0200195 tbf->m_bw.dl_bw_octets = 0;
Andreas Eversberg050ace22013-03-16 16:22:02 +0100196
197 return 0;
198}