blob: 348aefbdcac6e2f985dd01423aa889ddaa5806fd [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
26
27class GprsCodingScheme {
28public:
29 enum Scheme {
30 UNKNOWN,
31 CS1, CS2, CS3, CS4,
32 MCS1, MCS2, MCS3, MCS4,
33 MCS5, MCS6, MCS7, MCS8, MCS9,
34 NUM_SCHEMES
35 };
36
37 enum Mode {
38 GPRS,
39 EGPRS_GMSK,
40 EGPRS,
41 };
42
Jacob Erlbeck6c3dc612015-12-14 10:21:26 +010043 enum HeaderType {
44 HEADER_INVALID,
45 HEADER_GPRS_CONTROL,
46 HEADER_GPRS_DATA,
47 HEADER_EGPRS_DATA_TYPE_1,
48 HEADER_EGPRS_DATA_TYPE_2,
49 HEADER_EGPRS_DATA_TYPE_3,
Jacob Erlbeck22f80872016-01-11 10:56:50 +010050 NUM_HEADER_TYPES
Jacob Erlbeck6c3dc612015-12-14 10:21:26 +010051 };
52
Jacob Erlbeck409f9802015-11-30 18:06:50 +010053 GprsCodingScheme(Scheme s = UNKNOWN);
54
55 operator bool() const {return m_scheme != UNKNOWN;}
Jacob Erlbeck4c9e5492016-01-04 16:00:05 +010056 operator Scheme() const {return m_scheme;}
57 unsigned int to_num() const;
58
59 GprsCodingScheme& operator =(Scheme s);
60 GprsCodingScheme& operator =(GprsCodingScheme o);
61
Jacob Erlbeck409f9802015-11-30 18:06:50 +010062 bool isValid() const {return UNKNOWN <= m_scheme && m_scheme <= MCS9;}
63 bool isGprs() const {return CS1 <= m_scheme && m_scheme <= CS4;}
64 bool isEgprs() const {return m_scheme >= MCS1;}
65 bool isEgprsGmsk() const {return isEgprs() && m_scheme <= MCS4;}
66 bool isCompatible(Mode mode) const;
Jacob Erlbeck4c9e5492016-01-04 16:00:05 +010067 bool isCompatible(GprsCodingScheme o) const;
Jacob Erlbeck409f9802015-11-30 18:06:50 +010068
69 void inc(Mode mode);
70 void dec(Mode mode);
Jacob Erlbeck4c9e5492016-01-04 16:00:05 +010071 void inc();
72 void dec();
Jacob Erlbeck409f9802015-11-30 18:06:50 +010073
74 unsigned int sizeUL() const;
75 unsigned int sizeDL() const;
Jacob Erlbeckfc1b3e62016-01-11 09:58:11 +010076 unsigned int usedSizeUL() const;
77 unsigned int usedSizeDL() const;
Jacob Erlbeck409f9802015-11-30 18:06:50 +010078 unsigned int maxBytesUL() const;
79 unsigned int maxBytesDL() const;
80 unsigned int spareBitsUL() const;
81 unsigned int spareBitsDL() const;
Jacob Erlbeck392a5452015-12-14 10:38:29 +010082 unsigned int maxDataBlockBytes() const;
83 unsigned int numDataBlocks() const;
Jacob Erlbeck22f80872016-01-11 10:56:50 +010084 unsigned int numDataHeaderBitsUL() const;
85 unsigned int numDataHeaderBitsDL() const;
86 unsigned int numDataBlockHeaderBits() const;
Jacob Erlbeck409f9802015-11-30 18:06:50 +010087 const char *name() const;
Jacob Erlbeck6c3dc612015-12-14 10:21:26 +010088 HeaderType headerTypeData() const;
89 HeaderType headerTypeControl() const;
Jacob Erlbeck409f9802015-11-30 18:06:50 +010090
91 static GprsCodingScheme getBySizeUL(unsigned size);
Jacob Erlbeck4c9e5492016-01-04 16:00:05 +010092 static GprsCodingScheme getGprsByNum(unsigned num);
93 static GprsCodingScheme getEgprsByNum(unsigned num);
Jacob Erlbeck409f9802015-11-30 18:06:50 +010094
Jacob Erlbeck7b579972016-01-05 15:54:24 +010095 static const char *modeName(Mode mode);
Jacob Erlbeck409f9802015-11-30 18:06:50 +010096private:
Jacob Erlbeck7e7a2612016-01-07 18:07:54 +010097 GprsCodingScheme(int s); /* fail on use */
98 GprsCodingScheme& operator =(int s); /* fail on use */
Jacob Erlbeck409f9802015-11-30 18:06:50 +010099 enum Scheme m_scheme;
100};
101
Jacob Erlbeck4c9e5492016-01-04 16:00:05 +0100102inline unsigned int GprsCodingScheme::to_num() const
103{
104 if (isGprs())
105 return (m_scheme - CS1) + 1;
106
107 if (isEgprs())
108 return (m_scheme - MCS1) + 1;
109
110 return 0;
111}
112
Jacob Erlbeck409f9802015-11-30 18:06:50 +0100113inline bool GprsCodingScheme::isCompatible(Mode mode) const
114{
115 switch (mode) {
116 case GPRS: return isGprs();
117 case EGPRS_GMSK: return isEgprsGmsk();
118 case EGPRS: return isEgprs();
119 }
120
121 return false;
122}
123
Jacob Erlbeck4c9e5492016-01-04 16:00:05 +0100124inline bool GprsCodingScheme::isCompatible(GprsCodingScheme o) const
Jacob Erlbeck409f9802015-11-30 18:06:50 +0100125{
Jacob Erlbeck4c9e5492016-01-04 16:00:05 +0100126 return (isGprs() && o.isGprs()) || (isEgprs() && o.isEgprs());
Jacob Erlbeck409f9802015-11-30 18:06:50 +0100127}
128
Jacob Erlbeck6c3dc612015-12-14 10:21:26 +0100129inline GprsCodingScheme::HeaderType GprsCodingScheme::headerTypeControl() const
130{
131 return HEADER_GPRS_CONTROL;
132}
133
Jacob Erlbeck409f9802015-11-30 18:06:50 +0100134inline GprsCodingScheme::GprsCodingScheme(Scheme s)
135 : m_scheme(s)
136{
137 if (!isValid())
138 m_scheme = UNKNOWN;
139}
140
Jacob Erlbeck4c9e5492016-01-04 16:00:05 +0100141inline GprsCodingScheme& GprsCodingScheme::operator =(Scheme s)
Jacob Erlbeck409f9802015-11-30 18:06:50 +0100142{
143 m_scheme = s;
144
145 if (!isValid())
146 m_scheme = UNKNOWN;
Jacob Erlbeck4c9e5492016-01-04 16:00:05 +0100147
148 return *this;
Jacob Erlbeck409f9802015-11-30 18:06:50 +0100149}
150
Jacob Erlbeck4c9e5492016-01-04 16:00:05 +0100151inline GprsCodingScheme& GprsCodingScheme::operator =(GprsCodingScheme o)
Jacob Erlbeck409f9802015-11-30 18:06:50 +0100152{
153 m_scheme = o.m_scheme;
Jacob Erlbeck4c9e5492016-01-04 16:00:05 +0100154 return *this;
Jacob Erlbeck409f9802015-11-30 18:06:50 +0100155}
Jacob Erlbeck4c9e5492016-01-04 16:00:05 +0100156
157inline GprsCodingScheme GprsCodingScheme::getGprsByNum(unsigned num)
158{
159 if (num < 1 || num > 4)
160 return GprsCodingScheme();
161
162 return GprsCodingScheme(Scheme(CS1 + (num - 1)));
163}
164
165inline GprsCodingScheme GprsCodingScheme::getEgprsByNum(unsigned num)
166{
167 if (num < 1 || num > 9)
168 return GprsCodingScheme();
169
170 return GprsCodingScheme(Scheme(MCS1 + (num - 1)));
171}
172
173/* The coding schemes form a partial ordering */
174inline bool operator ==(GprsCodingScheme a, GprsCodingScheme b)
175{
Jacob Erlbeck7e7a2612016-01-07 18:07:54 +0100176 return GprsCodingScheme::Scheme(a) == GprsCodingScheme::Scheme(b);
Jacob Erlbeck4c9e5492016-01-04 16:00:05 +0100177}
178
179inline bool operator !=(GprsCodingScheme a, GprsCodingScheme b)
180{
181 return !(a == b);
182}
183
184inline bool operator <(GprsCodingScheme a, GprsCodingScheme b)
185{
Jacob Erlbeck7e7a2612016-01-07 18:07:54 +0100186 return a.isCompatible(b) &&
187 GprsCodingScheme::Scheme(a) < GprsCodingScheme::Scheme(b);
Jacob Erlbeck4c9e5492016-01-04 16:00:05 +0100188}
189
190inline bool operator >(GprsCodingScheme a, GprsCodingScheme b)
191{
Jacob Erlbeck7e7a2612016-01-07 18:07:54 +0100192 return b < a;
Jacob Erlbeck4c9e5492016-01-04 16:00:05 +0100193}
194
195inline bool operator <=(GprsCodingScheme a, GprsCodingScheme b)
196{
197 return a == b || a < b;
198}
199
200inline bool operator >=(GprsCodingScheme a, GprsCodingScheme b)
201{
202 return a == b || a > b;
203}
204