blob: 3229795c24e12ccda4e8054d244e24f185b4b54a [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 */
31
32/* received Measurement Report */
33int gprs_rlcmac_meas_rep(Packet_Measurement_Report_t *pmr)
34{
35 NC_Measurement_Report_t *ncr;
36 NC_Measurements_t *nc;
37 int i;
38
39 LOGP(DRLCMACMEAS, LOGL_INFO, "Measuement Report of TLLI=0x%08x:",
40 pmr->TLLI);
41
42 switch (pmr->UnionType) {
43 case 0:
44 ncr = &pmr->u.NC_Measurement_Report;
45 LOGPC(DRLCMACMEAS, LOGL_INFO, " NC%u Serv %d dbm",
46 ncr->NC_MODE + 1,
47 ncr->Serving_Cell_Data.RXLEV_SERVING_CELL - 110);
48 for (i = 0; i < ncr->NUMBER_OF_NC_MEASUREMENTS; i++) {
49 nc = &ncr->NC_Measurements[i];
50 LOGPC(DRLCMACMEAS, LOGL_DEBUG, ", Neigh %u %d dbm",
51 nc->FREQUENCY_N, nc->RXLEV_N - 110);
52 }
53 LOGPC(DRLCMACMEAS, LOGL_INFO, "\n");
54
55 break;
56 case 1:
57 LOGPC(DRLCMACMEAS, LOGL_INFO,
58 " <EXT Reporting not supported!>\n");
59 break;
60 }
61
62 return 0;
63}
64
65
66/*
67 * uplink measurement
68 */
69
70/* RSSI values received from MS */
71int gprs_rlcmac_rssi(struct gprs_rlcmac_tbf *tbf, int8_t rssi)
72{
73 struct timeval now_tv, *rssi_tv = &tbf->meas.rssi_tv;
74 uint32_t elapsed;
75
76 tbf->meas.rssi_sum += rssi;
77 tbf->meas.rssi_num++;
78
79 gettimeofday(&now_tv, NULL);
80 elapsed = ((now_tv.tv_sec - rssi_tv->tv_sec) << 7)
81 + ((now_tv.tv_usec - rssi_tv->tv_usec) << 7) / 1000000;
82 if (elapsed < 128)
83 return 0;
84
85 gprs_rlcmac_rssi_rep(tbf);
86
87 /* reset rssi values and timestamp */
88 memcpy(rssi_tv, &now_tv, sizeof(struct timeval));
89 tbf->meas.rssi_sum = 0;
90 tbf->meas.rssi_num = 0;
91
92 return 0;
93}
94
95/* Give RSSI report */
96int gprs_rlcmac_rssi_rep(struct gprs_rlcmac_tbf *tbf)
97{
98 /* No measurement values */
99 if (!tbf->meas.rssi_num)
100 return -EINVAL;
101
102 LOGP(DRLCMACMEAS, LOGL_INFO, "UL RSSI of TLLI=0x%08x: %d dBm\n",
103 tbf->tlli, tbf->meas.rssi_sum / tbf->meas.rssi_num);
104
105 return 0;
106}
107
108
109/*
110 * lost frames
111 */
112
113/* Lost frames reported from RLCMAC layer */
114int gprs_rlcmac_received_lost(struct gprs_rlcmac_tbf *tbf, uint16_t received,
115 uint16_t lost)
116{
117 struct timeval now_tv, *loss_tv = &tbf->meas.dl_loss_tv;
118 uint32_t elapsed;
119 uint16_t sum = received + lost;
120
121 /* No measurement values */
122 if (!sum)
123 return -EINVAL;
124
125 LOGP(DRLCMACMEAS, LOGL_DEBUG, "DL Loss of TLLI 0x%08x: Received: %4d "
126 "Lost: %4d Sum: %4d\n", tbf->tlli, received, lost, sum);
127
128 tbf->meas.dl_loss_received += received;
129 tbf->meas.dl_loss_lost += lost;
130
131 gettimeofday(&now_tv, NULL);
132 elapsed = ((now_tv.tv_sec - loss_tv->tv_sec) << 7)
133 + ((now_tv.tv_usec - loss_tv->tv_usec) << 7) / 1000000;
134 if (elapsed < 128)
135 return 0;
136
137 gprs_rlcmac_lost_rep(tbf);
138
139 /* reset lost values and timestamp */
140 memcpy(loss_tv, &now_tv, sizeof(struct timeval));
141 tbf->meas.dl_loss_received = 0;
142 tbf->meas.dl_loss_lost = 0;
143
144 return 0;
145}
146
147/* Give Lost report */
148int gprs_rlcmac_lost_rep(struct gprs_rlcmac_tbf *tbf)
149{
150 uint16_t sum = tbf->meas.dl_loss_lost + tbf->meas.dl_loss_received;
151
152 /* No measurement values */
153 if (!sum)
154 return -EINVAL;
155
156 LOGP(DRLCMACMEAS, LOGL_INFO, "DL packet loss of IMSI=%s / TLLI=0x%08x: "
157 "%d%%\n", tbf->meas.imsi, tbf->tlli,
158 tbf->meas.dl_loss_lost * 100 / sum);
159
160 return 0;
161}
162
163
164/*
165 * downlink bandwidth
166 */
167
168int gprs_rlcmac_dl_bw(struct gprs_rlcmac_tbf *tbf, uint16_t octets)
169{
170 struct timeval now_tv, *bw_tv = &tbf->meas.dl_bw_tv;
171 uint32_t elapsed;
172
173 tbf->meas.dl_bw_octets += octets;
174
175 gettimeofday(&now_tv, NULL);
176 elapsed = ((now_tv.tv_sec - bw_tv->tv_sec) << 7)
177 + ((now_tv.tv_usec - bw_tv->tv_usec) << 7) / 1000000;
178 if (elapsed < 128)
179 return 0;
180
181 LOGP(DRLCMACMEAS, LOGL_INFO, "DL Bandwitdh of IMSI=%s / TLLI=0x%08x: "
182 "%d KBits/s\n", tbf->meas.imsi, tbf->tlli,
183 tbf->meas.dl_bw_octets / elapsed);
184
185 /* reset bandwidth values timestamp */
186 memcpy(bw_tv, &now_tv, sizeof(struct timeval));
187 tbf->meas.dl_bw_octets = 0;
188
189 return 0;
190}
191