| /* 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(); |
| } |