blob: 6f965d6809d7836d8f87542911924020338187d7 [file] [log] [blame]
Jacob Erlbeck409f9802015-11-30 18:06:50 +01001/* gprs_coding_scheme.h
2 *
3 * Copyright (C) 2015 by Sysmocom s.f.m.c. GmbH
4 * Author: Jacob Erlbeck <jerlbeck@sysmocom.de>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 */
20
21#pragma once
22
23#include <stdint.h>
24#include <stddef.h>
25
Max19621362017-09-08 12:33:34 +020026extern "C" {
27 #include <osmocom/core/utils.h>
Maxbea2edb2019-03-06 17:04:59 +010028 #include "coding_scheme.h"
Max19621362017-09-08 12:33:34 +020029}
Jacob Erlbeck409f9802015-11-30 18:06:50 +010030
31class GprsCodingScheme {
32public:
Aravind Sirsikar91495522016-07-12 14:17:12 +053033
Aravind Sirsikar91495522016-07-12 14:17:12 +053034#define EGPRS_ARQ1 0x0
35#define EGPRS_ARQ2 0x1
36
Maxbea2edb2019-03-06 17:04:59 +010037 GprsCodingScheme(CodingScheme s = UNKNOWN);
Jacob Erlbeck409f9802015-11-30 18:06:50 +010038
39 operator bool() const {return m_scheme != UNKNOWN;}
Maxbea2edb2019-03-06 17:04:59 +010040 operator CodingScheme() const {return m_scheme;}
Maxb3a17d62017-12-21 12:11:33 +010041 uint8_t to_num() const;
Jacob Erlbeck4c9e5492016-01-04 16:00:05 +010042
Maxbea2edb2019-03-06 17:04:59 +010043 GprsCodingScheme& operator =(CodingScheme s);
44 bool operator == (CodingScheme s) const;
Jacob Erlbeck4c9e5492016-01-04 16:00:05 +010045 GprsCodingScheme& operator =(GprsCodingScheme o);
46
Jacob Erlbeck409f9802015-11-30 18:06:50 +010047 bool isValid() const {return UNKNOWN <= m_scheme && m_scheme <= MCS9;}
48 bool isGprs() const {return CS1 <= m_scheme && m_scheme <= CS4;}
49 bool isEgprs() const {return m_scheme >= MCS1;}
50 bool isEgprsGmsk() const {return isEgprs() && m_scheme <= MCS4;}
Maxa4de02d2019-03-13 16:35:09 +010051 bool isCompatible(enum mcs_kind mode) const;
Jacob Erlbeck4c9e5492016-01-04 16:00:05 +010052 bool isCompatible(GprsCodingScheme o) const;
Jacob Erlbeck2305afd2016-02-03 15:25:04 +010053 bool isFamilyCompatible(GprsCodingScheme o) const;
Jacob Erlbeck409f9802015-11-30 18:06:50 +010054
Maxa4de02d2019-03-13 16:35:09 +010055 void inc(enum mcs_kind mode);
56 void dec(enum mcs_kind mode);
Jacob Erlbeck4c9e5492016-01-04 16:00:05 +010057 void inc();
58 void dec();
Jacob Erlbeck2305afd2016-02-03 15:25:04 +010059 void decToSingleBlock(bool *needStuffing);
Jacob Erlbeck409f9802015-11-30 18:06:50 +010060
Maxb3a17d62017-12-21 12:11:33 +010061 uint8_t sizeUL() const;
62 uint8_t sizeDL() const;
63 uint8_t usedSizeUL() const;
64 uint8_t usedSizeDL() const;
65 uint8_t maxBytesUL() const;
66 uint8_t maxBytesDL() const;
67 uint8_t spareBitsUL() const;
68 uint8_t spareBitsDL() const;
69 uint8_t maxDataBlockBytes() const;
Maxb3a17d62017-12-21 12:11:33 +010070 uint8_t optionalPaddingBits() const;
Max136ebcc2019-03-05 14:59:03 +010071
Max51754b62019-03-13 17:14:13 +010072 enum HeaderType headerTypeData() const;
Jacob Erlbeck409f9802015-11-30 18:06:50 +010073
74 static GprsCodingScheme getBySizeUL(unsigned size);
Jacob Erlbeck4c9e5492016-01-04 16:00:05 +010075 static GprsCodingScheme getGprsByNum(unsigned num);
76 static GprsCodingScheme getEgprsByNum(unsigned num);
Jacob Erlbeck409f9802015-11-30 18:06:50 +010077
Maxbea2edb2019-03-06 17:04:59 +010078 static CodingScheme get_retx_mcs(const GprsCodingScheme mcs,
Aravind Sirsikar50b09702016-08-22 17:21:10 +053079 const GprsCodingScheme retx_mcs,
80 const unsigned arq_type);
Jacob Erlbeck409f9802015-11-30 18:06:50 +010081private:
Jacob Erlbeck7e7a2612016-01-07 18:07:54 +010082 GprsCodingScheme(int s); /* fail on use */
83 GprsCodingScheme& operator =(int s); /* fail on use */
Maxbea2edb2019-03-06 17:04:59 +010084 enum CodingScheme m_scheme;
Jacob Erlbeck409f9802015-11-30 18:06:50 +010085};
86
Maxb3a17d62017-12-21 12:11:33 +010087inline uint8_t GprsCodingScheme::to_num() const
Jacob Erlbeck4c9e5492016-01-04 16:00:05 +010088{
89 if (isGprs())
90 return (m_scheme - CS1) + 1;
91
92 if (isEgprs())
93 return (m_scheme - MCS1) + 1;
94
95 return 0;
96}
97
Maxa4de02d2019-03-13 16:35:09 +010098inline bool GprsCodingScheme::isCompatible(enum mcs_kind mode) const
Jacob Erlbeck409f9802015-11-30 18:06:50 +010099{
100 switch (mode) {
101 case GPRS: return isGprs();
102 case EGPRS_GMSK: return isEgprsGmsk();
103 case EGPRS: return isEgprs();
104 }
105
106 return false;
107}
108
Jacob Erlbeck4c9e5492016-01-04 16:00:05 +0100109inline bool GprsCodingScheme::isCompatible(GprsCodingScheme o) const
Jacob Erlbeck409f9802015-11-30 18:06:50 +0100110{
Jacob Erlbeck4c9e5492016-01-04 16:00:05 +0100111 return (isGprs() && o.isGprs()) || (isEgprs() && o.isEgprs());
Jacob Erlbeck409f9802015-11-30 18:06:50 +0100112}
113
Maxbea2edb2019-03-06 17:04:59 +0100114inline GprsCodingScheme::GprsCodingScheme(CodingScheme s)
Jacob Erlbeck409f9802015-11-30 18:06:50 +0100115 : m_scheme(s)
116{
117 if (!isValid())
118 m_scheme = UNKNOWN;
119}
120
Maxbea2edb2019-03-06 17:04:59 +0100121inline GprsCodingScheme& GprsCodingScheme::operator =(CodingScheme s)
Jacob Erlbeck409f9802015-11-30 18:06:50 +0100122{
123 m_scheme = s;
124
125 if (!isValid())
126 m_scheme = UNKNOWN;
Jacob Erlbeck4c9e5492016-01-04 16:00:05 +0100127
128 return *this;
Jacob Erlbeck409f9802015-11-30 18:06:50 +0100129}
130
Jacob Erlbeck4c9e5492016-01-04 16:00:05 +0100131inline GprsCodingScheme& GprsCodingScheme::operator =(GprsCodingScheme o)
Jacob Erlbeck409f9802015-11-30 18:06:50 +0100132{
133 m_scheme = o.m_scheme;
Jacob Erlbeck4c9e5492016-01-04 16:00:05 +0100134 return *this;
Jacob Erlbeck409f9802015-11-30 18:06:50 +0100135}
Jacob Erlbeck4c9e5492016-01-04 16:00:05 +0100136
137inline GprsCodingScheme GprsCodingScheme::getGprsByNum(unsigned num)
138{
139 if (num < 1 || num > 4)
140 return GprsCodingScheme();
141
Maxbea2edb2019-03-06 17:04:59 +0100142 return GprsCodingScheme(CodingScheme(CS1 + (num - 1)));
Jacob Erlbeck4c9e5492016-01-04 16:00:05 +0100143}
144
145inline GprsCodingScheme GprsCodingScheme::getEgprsByNum(unsigned num)
146{
147 if (num < 1 || num > 9)
148 return GprsCodingScheme();
149
Maxbea2edb2019-03-06 17:04:59 +0100150 return GprsCodingScheme(CodingScheme(MCS1 + (num - 1)));
Jacob Erlbeck4c9e5492016-01-04 16:00:05 +0100151}
152
153/* The coding schemes form a partial ordering */
Maxbea2edb2019-03-06 17:04:59 +0100154inline bool GprsCodingScheme::operator == (CodingScheme scheme) const
Aravind Sirsikare8ccafc2016-07-13 11:37:47 +0530155{
156 return this->m_scheme == scheme;
157}
158
Jacob Erlbeck4c9e5492016-01-04 16:00:05 +0100159inline bool operator !=(GprsCodingScheme a, GprsCodingScheme b)
160{
161 return !(a == b);
162}
163
164inline bool operator <(GprsCodingScheme a, GprsCodingScheme b)
165{
Maxbea2edb2019-03-06 17:04:59 +0100166 return a.isCompatible(b) && a.to_num() < b.to_num();
Jacob Erlbeck4c9e5492016-01-04 16:00:05 +0100167}