blob: 055c1664127331854882d359f5f1beaa9f226ecd [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
Jacob Erlbeck409f9802015-11-30 18:06:50 +010037 enum Mode {
38 GPRS,
39 EGPRS_GMSK,
40 EGPRS,
41 };
42
Maxbea2edb2019-03-06 17:04:59 +010043 GprsCodingScheme(CodingScheme s = UNKNOWN);
Jacob Erlbeck409f9802015-11-30 18:06:50 +010044
45 operator bool() const {return m_scheme != UNKNOWN;}
Maxbea2edb2019-03-06 17:04:59 +010046 operator CodingScheme() const {return m_scheme;}
Maxb3a17d62017-12-21 12:11:33 +010047 uint8_t to_num() const;
Jacob Erlbeck4c9e5492016-01-04 16:00:05 +010048
Maxbea2edb2019-03-06 17:04:59 +010049 GprsCodingScheme& operator =(CodingScheme s);
50 bool operator == (CodingScheme s) const;
Jacob Erlbeck4c9e5492016-01-04 16:00:05 +010051 GprsCodingScheme& operator =(GprsCodingScheme o);
52
Jacob Erlbeck409f9802015-11-30 18:06:50 +010053 bool isValid() const {return UNKNOWN <= m_scheme && m_scheme <= MCS9;}
54 bool isGprs() const {return CS1 <= m_scheme && m_scheme <= CS4;}
55 bool isEgprs() const {return m_scheme >= MCS1;}
56 bool isEgprsGmsk() const {return isEgprs() && m_scheme <= MCS4;}
57 bool isCompatible(Mode mode) const;
Jacob Erlbeck4c9e5492016-01-04 16:00:05 +010058 bool isCompatible(GprsCodingScheme o) const;
Jacob Erlbeck2305afd2016-02-03 15:25:04 +010059 bool isFamilyCompatible(GprsCodingScheme o) const;
Jacob Erlbeck409f9802015-11-30 18:06:50 +010060
61 void inc(Mode mode);
62 void dec(Mode mode);
Jacob Erlbeck4c9e5492016-01-04 16:00:05 +010063 void inc();
64 void dec();
Jacob Erlbeck2305afd2016-02-03 15:25:04 +010065 void decToSingleBlock(bool *needStuffing);
Jacob Erlbeck409f9802015-11-30 18:06:50 +010066
Maxb3a17d62017-12-21 12:11:33 +010067 uint8_t sizeUL() const;
68 uint8_t sizeDL() const;
69 uint8_t usedSizeUL() const;
70 uint8_t usedSizeDL() const;
71 uint8_t maxBytesUL() const;
72 uint8_t maxBytesDL() const;
73 uint8_t spareBitsUL() const;
74 uint8_t spareBitsDL() const;
75 uint8_t maxDataBlockBytes() const;
Maxb3a17d62017-12-21 12:11:33 +010076 uint8_t optionalPaddingBits() const;
Max136ebcc2019-03-05 14:59:03 +010077
Max51754b62019-03-13 17:14:13 +010078 enum HeaderType headerTypeData() const;
Jacob Erlbeck409f9802015-11-30 18:06:50 +010079
80 static GprsCodingScheme getBySizeUL(unsigned size);
Jacob Erlbeck4c9e5492016-01-04 16:00:05 +010081 static GprsCodingScheme getGprsByNum(unsigned num);
82 static GprsCodingScheme getEgprsByNum(unsigned num);
Jacob Erlbeck409f9802015-11-30 18:06:50 +010083
Jacob Erlbeck7b579972016-01-05 15:54:24 +010084 static const char *modeName(Mode mode);
Maxbea2edb2019-03-06 17:04:59 +010085 static CodingScheme get_retx_mcs(const GprsCodingScheme mcs,
Aravind Sirsikar50b09702016-08-22 17:21:10 +053086 const GprsCodingScheme retx_mcs,
87 const unsigned arq_type);
Jacob Erlbeck409f9802015-11-30 18:06:50 +010088private:
Jacob Erlbeck7e7a2612016-01-07 18:07:54 +010089 GprsCodingScheme(int s); /* fail on use */
90 GprsCodingScheme& operator =(int s); /* fail on use */
Maxbea2edb2019-03-06 17:04:59 +010091 enum CodingScheme m_scheme;
Jacob Erlbeck409f9802015-11-30 18:06:50 +010092};
93
Maxb3a17d62017-12-21 12:11:33 +010094inline uint8_t GprsCodingScheme::to_num() const
Jacob Erlbeck4c9e5492016-01-04 16:00:05 +010095{
96 if (isGprs())
97 return (m_scheme - CS1) + 1;
98
99 if (isEgprs())
100 return (m_scheme - MCS1) + 1;
101
102 return 0;
103}
104
Jacob Erlbeck409f9802015-11-30 18:06:50 +0100105inline bool GprsCodingScheme::isCompatible(Mode mode) const
106{
107 switch (mode) {
108 case GPRS: return isGprs();
109 case EGPRS_GMSK: return isEgprsGmsk();
110 case EGPRS: return isEgprs();
111 }
112
113 return false;
114}
115
Jacob Erlbeck4c9e5492016-01-04 16:00:05 +0100116inline bool GprsCodingScheme::isCompatible(GprsCodingScheme o) const
Jacob Erlbeck409f9802015-11-30 18:06:50 +0100117{
Jacob Erlbeck4c9e5492016-01-04 16:00:05 +0100118 return (isGprs() && o.isGprs()) || (isEgprs() && o.isEgprs());
Jacob Erlbeck409f9802015-11-30 18:06:50 +0100119}
120
Maxbea2edb2019-03-06 17:04:59 +0100121inline GprsCodingScheme::GprsCodingScheme(CodingScheme s)
Jacob Erlbeck409f9802015-11-30 18:06:50 +0100122 : m_scheme(s)
123{
124 if (!isValid())
125 m_scheme = UNKNOWN;
126}
127
Maxbea2edb2019-03-06 17:04:59 +0100128inline GprsCodingScheme& GprsCodingScheme::operator =(CodingScheme s)
Jacob Erlbeck409f9802015-11-30 18:06:50 +0100129{
130 m_scheme = s;
131
132 if (!isValid())
133 m_scheme = UNKNOWN;
Jacob Erlbeck4c9e5492016-01-04 16:00:05 +0100134
135 return *this;
Jacob Erlbeck409f9802015-11-30 18:06:50 +0100136}
137
Jacob Erlbeck4c9e5492016-01-04 16:00:05 +0100138inline GprsCodingScheme& GprsCodingScheme::operator =(GprsCodingScheme o)
Jacob Erlbeck409f9802015-11-30 18:06:50 +0100139{
140 m_scheme = o.m_scheme;
Jacob Erlbeck4c9e5492016-01-04 16:00:05 +0100141 return *this;
Jacob Erlbeck409f9802015-11-30 18:06:50 +0100142}
Jacob Erlbeck4c9e5492016-01-04 16:00:05 +0100143
144inline GprsCodingScheme GprsCodingScheme::getGprsByNum(unsigned num)
145{
146 if (num < 1 || num > 4)
147 return GprsCodingScheme();
148
Maxbea2edb2019-03-06 17:04:59 +0100149 return GprsCodingScheme(CodingScheme(CS1 + (num - 1)));
Jacob Erlbeck4c9e5492016-01-04 16:00:05 +0100150}
151
152inline GprsCodingScheme GprsCodingScheme::getEgprsByNum(unsigned num)
153{
154 if (num < 1 || num > 9)
155 return GprsCodingScheme();
156
Maxbea2edb2019-03-06 17:04:59 +0100157 return GprsCodingScheme(CodingScheme(MCS1 + (num - 1)));
Jacob Erlbeck4c9e5492016-01-04 16:00:05 +0100158}
159
160/* The coding schemes form a partial ordering */
Maxbea2edb2019-03-06 17:04:59 +0100161inline bool GprsCodingScheme::operator == (CodingScheme scheme) const
Aravind Sirsikare8ccafc2016-07-13 11:37:47 +0530162{
163 return this->m_scheme == scheme;
164}
165
Jacob Erlbeck4c9e5492016-01-04 16:00:05 +0100166inline bool operator !=(GprsCodingScheme a, GprsCodingScheme b)
167{
168 return !(a == b);
169}
170
171inline bool operator <(GprsCodingScheme a, GprsCodingScheme b)
172{
Maxbea2edb2019-03-06 17:04:59 +0100173 return a.isCompatible(b) && a.to_num() < b.to_num();
Jacob Erlbeck4c9e5492016-01-04 16:00:05 +0100174}