blob: ac01f2ae8251c5e8a95ee18a376359646e9e8501 [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 */
19
20#include <gprs_rlcmac.h>
21#include <gprs_debug.h>
22#include <pcu_l1_if.h>
Holger Hans Peter Freyther099535a2013-10-16 17:42:31 +020023#include <tbf.h>
Andreas Eversberg050ace22013-03-16 16:22:02 +010024
25#include <string.h>
26#include <errno.h>
27
28/*
29 * downlink measurement
30 */
Max5a6bcfb2017-09-01 14:36:44 +020031/* TODO: trigger the measurement report from the pollcontroller and use it for flow control */
Andreas Eversberg050ace22013-03-16 16:22:02 +010032
33/* received Measurement Report */
34int gprs_rlcmac_meas_rep(Packet_Measurement_Report_t *pmr)
35{
36 NC_Measurement_Report_t *ncr;
37 NC_Measurements_t *nc;
38 int i;
39
40 LOGP(DRLCMACMEAS, LOGL_INFO, "Measuement Report of TLLI=0x%08x:",
41 pmr->TLLI);
42
43 switch (pmr->UnionType) {
44 case 0:
45 ncr = &pmr->u.NC_Measurement_Report;
46 LOGPC(DRLCMACMEAS, LOGL_INFO, " NC%u Serv %d dbm",
47 ncr->NC_MODE + 1,
48 ncr->Serving_Cell_Data.RXLEV_SERVING_CELL - 110);
49 for (i = 0; i < ncr->NUMBER_OF_NC_MEASUREMENTS; i++) {
50 nc = &ncr->NC_Measurements[i];
51 LOGPC(DRLCMACMEAS, LOGL_DEBUG, ", Neigh %u %d dbm",
52 nc->FREQUENCY_N, nc->RXLEV_N - 110);
53 }
54 LOGPC(DRLCMACMEAS, LOGL_INFO, "\n");
55
56 break;
57 case 1:
58 LOGPC(DRLCMACMEAS, LOGL_INFO,
59 " <EXT Reporting not supported!>\n");
60 break;
61 }
62
63 return 0;
64}
65
66
67/*
68 * uplink measurement
69 */
70
71/* RSSI values received from MS */
72int gprs_rlcmac_rssi(struct gprs_rlcmac_tbf *tbf, int8_t rssi)
73{
Stefan Sperlingf0f7df12018-05-25 15:12:30 +020074 struct timespec now_tv, *rssi_tv = &tbf->meas.rssi_tv;
Andreas Eversberg050ace22013-03-16 16:22:02 +010075 uint32_t elapsed;
76
77 tbf->meas.rssi_sum += rssi;
78 tbf->meas.rssi_num++;
79
Stefan Sperlingf0f7df12018-05-25 15:12:30 +020080 osmo_clock_gettime(CLOCK_MONOTONIC, &now_tv);
Andreas Eversberg050ace22013-03-16 16:22:02 +010081 elapsed = ((now_tv.tv_sec - rssi_tv->tv_sec) << 7)
Stefan Sperlingf0f7df12018-05-25 15:12:30 +020082 + (((now_tv.tv_nsec - rssi_tv->tv_nsec)/1000) << 7) / 1000000;
Andreas Eversberg050ace22013-03-16 16:22:02 +010083 if (elapsed < 128)
84 return 0;
85
86 gprs_rlcmac_rssi_rep(tbf);
87
88 /* reset rssi values and timestamp */
Stefan Sperlingf0f7df12018-05-25 15:12:30 +020089 memcpy(rssi_tv, &now_tv, sizeof(*rssi_tv));
Andreas Eversberg050ace22013-03-16 16:22:02 +010090 tbf->meas.rssi_sum = 0;
91 tbf->meas.rssi_num = 0;
92
93 return 0;
94}
95
96/* Give RSSI report */
97int gprs_rlcmac_rssi_rep(struct gprs_rlcmac_tbf *tbf)
98{
99 /* No measurement values */
100 if (!tbf->meas.rssi_num)
101 return -EINVAL;
102
103 LOGP(DRLCMACMEAS, LOGL_INFO, "UL RSSI of TLLI=0x%08x: %d dBm\n",
Holger Hans Peter Freyther474685e2013-10-27 17:01:14 +0100104 tbf->tlli(), tbf->meas.rssi_sum / tbf->meas.rssi_num);
Andreas Eversberg050ace22013-03-16 16:22:02 +0100105
106 return 0;
107}
108
109
110/*
111 * lost frames
112 */
113
114/* Lost frames reported from RLCMAC layer */
Daniel Willmann418a4232014-08-08 11:21:04 +0200115int gprs_rlcmac_received_lost(struct gprs_rlcmac_dl_tbf *tbf, uint16_t received,
Andreas Eversberg050ace22013-03-16 16:22:02 +0100116 uint16_t lost)
117{
Stefan Sperlingf0f7df12018-05-25 15:12:30 +0200118 struct timespec now_tv, *loss_tv = &tbf->m_bw.dl_loss_tv;
Andreas Eversberg050ace22013-03-16 16:22:02 +0100119 uint32_t elapsed;
120 uint16_t sum = received + lost;
121
122 /* No measurement values */
123 if (!sum)
124 return -EINVAL;
125
126 LOGP(DRLCMACMEAS, LOGL_DEBUG, "DL Loss of TLLI 0x%08x: Received: %4d "
Holger Hans Peter Freyther474685e2013-10-27 17:01:14 +0100127 "Lost: %4d Sum: %4d\n", tbf->tlli(), received, lost, sum);
Andreas Eversberg050ace22013-03-16 16:22:02 +0100128
Daniel Willmann418a4232014-08-08 11:21:04 +0200129 tbf->m_bw.dl_loss_received += received;
130 tbf->m_bw.dl_loss_lost += lost;
Andreas Eversberg050ace22013-03-16 16:22:02 +0100131
Stefan Sperlingf0f7df12018-05-25 15:12:30 +0200132 osmo_clock_gettime(CLOCK_MONOTONIC, &now_tv);
Andreas Eversberg050ace22013-03-16 16:22:02 +0100133 elapsed = ((now_tv.tv_sec - loss_tv->tv_sec) << 7)
Stefan Sperlingf0f7df12018-05-25 15:12:30 +0200134 + (((now_tv.tv_nsec - loss_tv->tv_nsec)/1000) << 7) / 1000000;
Andreas Eversberg050ace22013-03-16 16:22:02 +0100135 if (elapsed < 128)
136 return 0;
137
138 gprs_rlcmac_lost_rep(tbf);
139
140 /* reset lost values and timestamp */
Stefan Sperlingf0f7df12018-05-25 15:12:30 +0200141 memcpy(loss_tv, &now_tv, sizeof(*loss_tv));
Daniel Willmann418a4232014-08-08 11:21:04 +0200142 tbf->m_bw.dl_loss_received = 0;
143 tbf->m_bw.dl_loss_lost = 0;
Andreas Eversberg050ace22013-03-16 16:22:02 +0100144
145 return 0;
146}
147
148/* Give Lost report */
Daniel Willmann418a4232014-08-08 11:21:04 +0200149int gprs_rlcmac_lost_rep(struct gprs_rlcmac_dl_tbf *tbf)
Andreas Eversberg050ace22013-03-16 16:22:02 +0100150{
Daniel Willmann418a4232014-08-08 11:21:04 +0200151 uint16_t sum = tbf->m_bw.dl_loss_lost + tbf->m_bw.dl_loss_received;
Andreas Eversberg050ace22013-03-16 16:22:02 +0100152
153 /* No measurement values */
154 if (!sum)
155 return -EINVAL;
156
157 LOGP(DRLCMACMEAS, LOGL_INFO, "DL packet loss of IMSI=%s / TLLI=0x%08x: "
Holger Hans Peter Freyther5464c9b2013-10-27 20:57:35 +0100158 "%d%%\n", tbf->imsi(), tbf->tlli(),
Daniel Willmann418a4232014-08-08 11:21:04 +0200159 tbf->m_bw.dl_loss_lost * 100 / sum);
Andreas Eversberg050ace22013-03-16 16:22:02 +0100160
161 return 0;
162}
163
164
165/*
166 * downlink bandwidth
167 */
168
Daniel Willmann418a4232014-08-08 11:21:04 +0200169int gprs_rlcmac_dl_bw(struct gprs_rlcmac_dl_tbf *tbf, uint16_t octets)
Andreas Eversberg050ace22013-03-16 16:22:02 +0100170{
Stefan Sperlingf0f7df12018-05-25 15:12:30 +0200171 struct timespec now_tv, *bw_tv = &tbf->m_bw.dl_bw_tv;
Andreas Eversberg050ace22013-03-16 16:22:02 +0100172 uint32_t elapsed;
173
Daniel Willmann418a4232014-08-08 11:21:04 +0200174 tbf->m_bw.dl_bw_octets += octets;
Andreas Eversberg050ace22013-03-16 16:22:02 +0100175
Stefan Sperlingf0f7df12018-05-25 15:12:30 +0200176 osmo_clock_gettime(CLOCK_MONOTONIC, &now_tv);
Andreas Eversberg050ace22013-03-16 16:22:02 +0100177 elapsed = ((now_tv.tv_sec - bw_tv->tv_sec) << 7)
Stefan Sperlingf0f7df12018-05-25 15:12:30 +0200178 + (((now_tv.tv_nsec - bw_tv->tv_nsec)/1000) << 7) / 1000000;
Andreas Eversberg050ace22013-03-16 16:22:02 +0100179 if (elapsed < 128)
180 return 0;
181
sivasankari53950732016-12-08 17:15:17 +0530182 tbf->m_bw.dl_throughput = (tbf->m_bw.dl_bw_octets/elapsed);
183
Andreas Eversberg050ace22013-03-16 16:22:02 +0100184 LOGP(DRLCMACMEAS, LOGL_INFO, "DL Bandwitdh of IMSI=%s / TLLI=0x%08x: "
Holger Hans Peter Freyther5464c9b2013-10-27 20:57:35 +0100185 "%d KBits/s\n", tbf->imsi(), tbf->tlli(),
Daniel Willmann418a4232014-08-08 11:21:04 +0200186 tbf->m_bw.dl_bw_octets / elapsed);
Andreas Eversberg050ace22013-03-16 16:22:02 +0100187
188 /* reset bandwidth values timestamp */
Stefan Sperlingf0f7df12018-05-25 15:12:30 +0200189 memcpy(bw_tv, &now_tv, sizeof(*bw_tv));
Daniel Willmann418a4232014-08-08 11:21:04 +0200190 tbf->m_bw.dl_bw_octets = 0;
Andreas Eversberg050ace22013-03-16 16:22:02 +0100191
192 return 0;
193}
194