osmo-pcu/src/gprs_coding_scheme.h

164 lines
4.1 KiB
C++

/* gprs_coding_scheme.h
*
* Copyright (C) 2015 by Sysmocom s.f.m.c. GmbH
* Author: Jacob Erlbeck <jerlbeck@sysmocom.de>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#pragma once
#include <stdint.h>
#include <stddef.h>
extern "C" {
#include <osmocom/core/utils.h>
#include "coding_scheme.h"
}
class GprsCodingScheme {
public:
#define EGPRS_ARQ1 0x0
#define EGPRS_ARQ2 0x1
GprsCodingScheme(CodingScheme s = UNKNOWN);
operator bool() const {return m_scheme != UNKNOWN;}
operator CodingScheme() const {return m_scheme;}
uint8_t to_num() const;
GprsCodingScheme& operator =(CodingScheme s);
bool operator == (CodingScheme s) const;
GprsCodingScheme& operator =(GprsCodingScheme o);
bool isValid() const {return UNKNOWN <= m_scheme && m_scheme <= MCS9;}
bool isCompatible(enum mcs_kind mode) const;
bool isCompatible(GprsCodingScheme o) const;
bool isFamilyCompatible(GprsCodingScheme o) const;
void inc(enum mcs_kind mode);
void dec(enum mcs_kind mode);
void inc();
void dec();
void decToSingleBlock(bool *needStuffing);
uint8_t sizeUL() const;
uint8_t sizeDL() const;
uint8_t usedSizeUL() const;
uint8_t usedSizeDL() const;
uint8_t maxBytesUL() const;
uint8_t maxBytesDL() const;
uint8_t spareBitsUL() const;
uint8_t spareBitsDL() const;
uint8_t maxDataBlockBytes() const;
uint8_t optionalPaddingBits() const;
enum HeaderType headerTypeData() const;
static GprsCodingScheme getBySizeUL(unsigned size);
static GprsCodingScheme getGprsByNum(unsigned num);
static GprsCodingScheme getEgprsByNum(unsigned num);
private:
GprsCodingScheme(int s); /* fail on use */
GprsCodingScheme& operator =(int s); /* fail on use */
enum CodingScheme m_scheme;
};
// FIXME: remove once < comparison operator below is no longer necessary
inline uint8_t GprsCodingScheme::to_num() const
{
if (mcs_is_gprs(m_scheme))
return (m_scheme - CS1) + 1;
if (mcs_is_edge(m_scheme))
return (m_scheme - MCS1) + 1;
return 0;
}
inline bool GprsCodingScheme::isCompatible(enum mcs_kind mode) const
{
switch (mode) {
case GPRS: return mcs_is_gprs(m_scheme);
case EGPRS_GMSK: return mcs_is_edge_gmsk(m_scheme);
case EGPRS: return mcs_is_edge(m_scheme);
}
return false;
}
inline bool GprsCodingScheme::isCompatible(GprsCodingScheme o) const
{
return (mcs_is_gprs(m_scheme) && mcs_is_gprs(o)) || (mcs_is_edge(m_scheme) && mcs_is_edge(o));
}
inline GprsCodingScheme::GprsCodingScheme(CodingScheme s)
: m_scheme(s)
{
if (!isValid())
m_scheme = UNKNOWN;
}
inline GprsCodingScheme& GprsCodingScheme::operator =(CodingScheme s)
{
m_scheme = s;
if (!isValid())
m_scheme = UNKNOWN;
return *this;
}
inline GprsCodingScheme& GprsCodingScheme::operator =(GprsCodingScheme o)
{
m_scheme = o.m_scheme;
return *this;
}
inline GprsCodingScheme GprsCodingScheme::getGprsByNum(unsigned num)
{
if (num < 1 || num > 4)
return GprsCodingScheme();
return GprsCodingScheme(CodingScheme(CS1 + (num - 1)));
}
inline GprsCodingScheme GprsCodingScheme::getEgprsByNum(unsigned num)
{
if (num < 1 || num > 9)
return GprsCodingScheme();
return GprsCodingScheme(CodingScheme(MCS1 + (num - 1)));
}
/* The coding schemes form a partial ordering */
inline bool GprsCodingScheme::operator == (CodingScheme scheme) const
{
return this->m_scheme == scheme;
}
inline bool operator !=(GprsCodingScheme a, GprsCodingScheme b)
{
return !(a == b);
}
inline bool operator <(GprsCodingScheme a, GprsCodingScheme b)
{
return a.isCompatible(b) && a.to_num() < b.to_num();
}