blob: 854deb670db41e87a4609db53748f02ced8934bf [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,
50 };
51
Jacob Erlbeck409f9802015-11-30 18:06:50 +010052 GprsCodingScheme(Scheme s = UNKNOWN);
53
54 operator bool() const {return m_scheme != UNKNOWN;}
Jacob Erlbeck4c9e5492016-01-04 16:00:05 +010055 operator Scheme() const {return m_scheme;}
56 unsigned int to_num() const;
57
58 GprsCodingScheme& operator =(Scheme s);
59 GprsCodingScheme& operator =(GprsCodingScheme o);
60
Jacob Erlbeck409f9802015-11-30 18:06:50 +010061 bool isValid() const {return UNKNOWN <= m_scheme && m_scheme <= MCS9;}
62 bool isGprs() const {return CS1 <= m_scheme && m_scheme <= CS4;}
63 bool isEgprs() const {return m_scheme >= MCS1;}
64 bool isEgprsGmsk() const {return isEgprs() && m_scheme <= MCS4;}
65 bool isCompatible(Mode mode) const;
Jacob Erlbeck4c9e5492016-01-04 16:00:05 +010066 bool isCompatible(GprsCodingScheme o) const;
Jacob Erlbeck409f9802015-11-30 18:06:50 +010067
68 void inc(Mode mode);
69 void dec(Mode mode);
Jacob Erlbeck4c9e5492016-01-04 16:00:05 +010070 void inc();
71 void dec();
Jacob Erlbeck409f9802015-11-30 18:06:50 +010072
73 unsigned int sizeUL() const;
74 unsigned int sizeDL() const;
Jacob Erlbeckfc1b3e62016-01-11 09:58:11 +010075 unsigned int usedSizeUL() const;
76 unsigned int usedSizeDL() const;
Jacob Erlbeck409f9802015-11-30 18:06:50 +010077 unsigned int maxBytesUL() const;
78 unsigned int maxBytesDL() const;
79 unsigned int spareBitsUL() const;
80 unsigned int spareBitsDL() const;
Jacob Erlbeck392a5452015-12-14 10:38:29 +010081 unsigned int maxDataBlockBytes() const;
82 unsigned int numDataBlocks() const;
Jacob Erlbeck409f9802015-11-30 18:06:50 +010083 const char *name() const;
Jacob Erlbeck6c3dc612015-12-14 10:21:26 +010084 HeaderType headerTypeData() const;
85 HeaderType headerTypeControl() const;
Jacob Erlbeck409f9802015-11-30 18:06:50 +010086
87 static GprsCodingScheme getBySizeUL(unsigned size);
Jacob Erlbeck4c9e5492016-01-04 16:00:05 +010088 static GprsCodingScheme getGprsByNum(unsigned num);
89 static GprsCodingScheme getEgprsByNum(unsigned num);
Jacob Erlbeck409f9802015-11-30 18:06:50 +010090
Jacob Erlbeck7b579972016-01-05 15:54:24 +010091 static const char *modeName(Mode mode);
Jacob Erlbeck409f9802015-11-30 18:06:50 +010092private:
Jacob Erlbeck7e7a2612016-01-07 18:07:54 +010093 GprsCodingScheme(int s); /* fail on use */
94 GprsCodingScheme& operator =(int s); /* fail on use */
Jacob Erlbeck409f9802015-11-30 18:06:50 +010095 enum Scheme m_scheme;
96};
97
Jacob Erlbeck4c9e5492016-01-04 16:00:05 +010098inline unsigned int GprsCodingScheme::to_num() const
99{
100 if (isGprs())
101 return (m_scheme - CS1) + 1;
102
103 if (isEgprs())
104 return (m_scheme - MCS1) + 1;
105
106 return 0;
107}
108
Jacob Erlbeck409f9802015-11-30 18:06:50 +0100109inline bool GprsCodingScheme::isCompatible(Mode mode) const
110{
111 switch (mode) {
112 case GPRS: return isGprs();
113 case EGPRS_GMSK: return isEgprsGmsk();
114 case EGPRS: return isEgprs();
115 }
116
117 return false;
118}
119
Jacob Erlbeck4c9e5492016-01-04 16:00:05 +0100120inline bool GprsCodingScheme::isCompatible(GprsCodingScheme o) const
Jacob Erlbeck409f9802015-11-30 18:06:50 +0100121{
Jacob Erlbeck4c9e5492016-01-04 16:00:05 +0100122 return (isGprs() && o.isGprs()) || (isEgprs() && o.isEgprs());
Jacob Erlbeck409f9802015-11-30 18:06:50 +0100123}
124
Jacob Erlbeck6c3dc612015-12-14 10:21:26 +0100125inline GprsCodingScheme::HeaderType GprsCodingScheme::headerTypeControl() const
126{
127 return HEADER_GPRS_CONTROL;
128}
129
Jacob Erlbeck409f9802015-11-30 18:06:50 +0100130inline GprsCodingScheme::GprsCodingScheme(Scheme s)
131 : m_scheme(s)
132{
133 if (!isValid())
134 m_scheme = UNKNOWN;
135}
136
Jacob Erlbeck4c9e5492016-01-04 16:00:05 +0100137inline GprsCodingScheme& GprsCodingScheme::operator =(Scheme s)
Jacob Erlbeck409f9802015-11-30 18:06:50 +0100138{
139 m_scheme = s;
140
141 if (!isValid())
142 m_scheme = UNKNOWN;
Jacob Erlbeck4c9e5492016-01-04 16:00:05 +0100143
144 return *this;
Jacob Erlbeck409f9802015-11-30 18:06:50 +0100145}
146
Jacob Erlbeck4c9e5492016-01-04 16:00:05 +0100147inline GprsCodingScheme& GprsCodingScheme::operator =(GprsCodingScheme o)
Jacob Erlbeck409f9802015-11-30 18:06:50 +0100148{
149 m_scheme = o.m_scheme;
Jacob Erlbeck4c9e5492016-01-04 16:00:05 +0100150 return *this;
Jacob Erlbeck409f9802015-11-30 18:06:50 +0100151}
Jacob Erlbeck4c9e5492016-01-04 16:00:05 +0100152
153inline GprsCodingScheme GprsCodingScheme::getGprsByNum(unsigned num)
154{
155 if (num < 1 || num > 4)
156 return GprsCodingScheme();
157
158 return GprsCodingScheme(Scheme(CS1 + (num - 1)));
159}
160
161inline GprsCodingScheme GprsCodingScheme::getEgprsByNum(unsigned num)
162{
163 if (num < 1 || num > 9)
164 return GprsCodingScheme();
165
166 return GprsCodingScheme(Scheme(MCS1 + (num - 1)));
167}
168
169/* The coding schemes form a partial ordering */
170inline bool operator ==(GprsCodingScheme a, GprsCodingScheme b)
171{
Jacob Erlbeck7e7a2612016-01-07 18:07:54 +0100172 return GprsCodingScheme::Scheme(a) == GprsCodingScheme::Scheme(b);
Jacob Erlbeck4c9e5492016-01-04 16:00:05 +0100173}
174
175inline bool operator !=(GprsCodingScheme a, GprsCodingScheme b)
176{
177 return !(a == b);
178}
179
180inline bool operator <(GprsCodingScheme a, GprsCodingScheme b)
181{
Jacob Erlbeck7e7a2612016-01-07 18:07:54 +0100182 return a.isCompatible(b) &&
183 GprsCodingScheme::Scheme(a) < GprsCodingScheme::Scheme(b);
Jacob Erlbeck4c9e5492016-01-04 16:00:05 +0100184}
185
186inline bool operator >(GprsCodingScheme a, GprsCodingScheme b)
187{
Jacob Erlbeck7e7a2612016-01-07 18:07:54 +0100188 return b < a;
Jacob Erlbeck4c9e5492016-01-04 16:00:05 +0100189}
190
191inline bool operator <=(GprsCodingScheme a, GprsCodingScheme b)
192{
193 return a == b || a < b;
194}
195
196inline bool operator >=(GprsCodingScheme a, GprsCodingScheme b)
197{
198 return a == b || a > b;
199}
200