/* gprs_coding_scheme.h * * Copyright (C) 2015 by Sysmocom s.f.m.c. GmbH * Author: Jacob Erlbeck * * 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 #include extern "C" { #include #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); static CodingScheme get_retx_mcs(const GprsCodingScheme mcs, const GprsCodingScheme retx_mcs, const unsigned arq_type); 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(); }