libosmogsm  0.9.3
Osmocom GSM library
include/osmocom/gsm/gsm_utils.h
00001 /* GSM utility functions, e.g. coding and decoding */
00002 /*
00003  * (C) 2008 by Daniel Willmann <daniel@totalueberwachung.de>
00004  * (C) 2009 by Holger Hans Peter Freyther <zecke@selfish.org>
00005  * (C) 2009-2010 by Harald Welte <laforge@gnumonks.org>
00006  *
00007  * All Rights Reserved
00008  *
00009  * This program is free software; you can redistribute it and/or modify
00010  * it under the terms of the GNU General Public License as published by
00011  * the Free Software Foundation; either version 2 of the License, or
00012  * (at your option) any later version.
00013  *
00014  * This program is distributed in the hope that it will be useful,
00015  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00016  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017  * GNU General Public License for more details.
00018  *
00019  * You should have received a copy of the GNU General Public License along
00020  * with this program; if not, write to the Free Software Foundation, Inc.,
00021  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
00022  *
00023  */
00024 
00025 #pragma once
00026 
00027 #include <stddef.h>
00028 #include <stdint.h>
00029 
00030 #include <osmocom/core/defs.h>
00031 
00032 #define ADD_MODULO(sum, delta, modulo) do {     \
00033         if ((sum += delta) >= modulo)           \
00034                 sum -= modulo;                  \
00035         } while (0)
00036 
00037 #define GSM_MAX_FN      (26*51*2048)
00038 
00039 struct gsm_time {
00040         uint32_t        fn;     /* FN count */
00041         uint16_t        t1;     /* FN div (26*51) */
00042         uint8_t         t2;     /* FN modulo 26 */
00043         uint8_t         t3;     /* FN modulo 51 */
00044         uint8_t         tc;
00045 };
00046 
00047 enum gsm_band {
00048         GSM_BAND_850    = 1,
00049         GSM_BAND_900    = 2,
00050         GSM_BAND_1800   = 4,
00051         GSM_BAND_1900   = 8,
00052         GSM_BAND_450    = 0x10,
00053         GSM_BAND_480    = 0x20,
00054         GSM_BAND_750    = 0x40,
00055         GSM_BAND_810    = 0x80,
00056 };
00057 
00058 const char *gsm_band_name(enum gsm_band band);
00059 enum gsm_band gsm_band_parse(const char *mhz);
00060 
00074 int gsm_7bit_decode_n(char *decoded, size_t n, const uint8_t *user_data, uint8_t length);
00075 
00081 int gsm_7bit_decode_n_ussd(char *decoded, size_t n, const uint8_t *user_data, uint8_t length);
00082 
00095 int gsm_7bit_encode_n(uint8_t *result, size_t n, const char *data, int *octets_written);
00096 
00102 int gsm_7bit_encode_n_ussd(uint8_t *result, size_t n, const char *data, int *octets_written);
00103 
00104 /* the four functions below are helper functions and here for the unit test */
00105 int gsm_septets2octets(uint8_t *result, const uint8_t *rdata, uint8_t septet_len, uint8_t padding);
00106 int gsm_septet_encode(uint8_t *result, const char *data);
00107 uint8_t gsm_get_octet_len(const uint8_t sept_len);
00108 int gsm_7bit_decode_n_hdr(char *decoded, size_t n, const uint8_t *user_data, uint8_t length, uint8_t ud_hdr_ind);
00109 
00110 unsigned int ms_class_gmsk_dbm(enum gsm_band band, int ms_class);
00111 
00112 int ms_pwr_ctl_lvl(enum gsm_band band, unsigned int dbm);
00113 int ms_pwr_dbm(enum gsm_band band, uint8_t lvl);
00114 
00115 /* According to TS 05.08 Chapter 8.1.4 */
00116 int rxlev2dbm(uint8_t rxlev);
00117 uint8_t dbm2rxlev(int dbm);
00118 
00119 /* According to GSM 04.08 Chapter 10.5.1.6 */
00120 static inline int ms_cm2_a5n_support(uint8_t *cm2, int n) {
00121         switch (n) {
00122                 case 0: return 1;
00123                 case 1: return (cm2[0] & (1<<3)) ? 0 : 1;
00124                 case 2: return (cm2[2] & (1<<0)) ? 1 : 0;
00125                 case 3: return (cm2[2] & (1<<1)) ? 1 : 0;
00126                 default:
00127                         return 0;
00128         }
00129 }
00130 
00131 /* According to GSM 04.08 Chapter 10.5.2.29 */
00132 static inline int rach_max_trans_val2raw(int val) { return (val >> 1) & 3; }
00133 static inline int rach_max_trans_raw2val(int raw) {
00134         const int tbl[4] = { 1, 2, 4, 7 };
00135         return tbl[raw & 3];
00136 }
00137 
00138 #define ARFCN_PCS       0x8000
00139 #define ARFCN_UPLINK    0x4000
00140 #define ARFCN_FLAG_MASK 0xf000  /* Reserve the upper 5 bits for flags */
00141 
00142 enum gsm_band gsm_arfcn2band(uint16_t arfcn);
00143 
00144 /* Convert an ARFCN to the frequency in MHz * 10 */
00145 uint16_t gsm_arfcn2freq10(uint16_t arfcn, int uplink);
00146 
00147 /* Convert a Frequency in MHz * 10 to ARFCN */
00148 uint16_t gsm_freq102arfcn(uint16_t freq10, int uplink);
00149 
00150 /* Convert from frame number to GSM time */
00151 void gsm_fn2gsmtime(struct gsm_time *time, uint32_t fn);
00152 
00153 /* Convert from GSM time to frame number */
00154 uint32_t gsm_gsmtime2fn(struct gsm_time *time);
00155 
00156 /* GSM TS 03.03 Chapter 2.6 */
00157 enum gprs_tlli_type {
00158         TLLI_LOCAL,
00159         TLLI_FOREIGN,
00160         TLLI_RANDOM,
00161         TLLI_AUXILIARY,
00162         TLLI_RESERVED,
00163         TLLI_G_RNTI,
00164         TLLI_RAND_G_RNTI,
00165 };
00166 
00167 /* TS 03.03 Chapter 2.6 */
00168 int gprs_tlli_type(uint32_t tlli);
00169 
00170 uint32_t gprs_tmsi2tlli(uint32_t p_tmsi, enum gprs_tlli_type type);
00171 
00172 /* Osmocom internal, not part of any gsm spec */
00173 enum gsm_phys_chan_config {
00174         GSM_PCHAN_NONE,
00175         GSM_PCHAN_CCCH,
00176         GSM_PCHAN_CCCH_SDCCH4,
00177         GSM_PCHAN_TCH_F,
00178         GSM_PCHAN_TCH_H,
00179         GSM_PCHAN_SDCCH8_SACCH8C,
00180         GSM_PCHAN_PDCH,         /* GPRS PDCH */
00181         GSM_PCHAN_TCH_F_PDCH,   /* TCH/F if used, PDCH otherwise */
00182         GSM_PCHAN_UNKNOWN,
00183         GSM_PCHAN_CCCH_SDCCH4_CBCH,
00184         GSM_PCHAN_SDCCH8_SACCH8C_CBCH,
00185         _GSM_PCHAN_MAX
00186 };
00187 
00188 /* Osmocom internal, not part of any gsm spec */
00189 enum gsm_chan_t {
00190         GSM_LCHAN_NONE,
00191         GSM_LCHAN_SDCCH,
00192         GSM_LCHAN_TCH_F,
00193         GSM_LCHAN_TCH_H,
00194         GSM_LCHAN_UNKNOWN,
00195         GSM_LCHAN_CCCH,
00196         GSM_LCHAN_PDTCH,
00197         GSM_LCHAN_CBCH,
00198         _GSM_LCHAN_MAX
00199 };
00200 
00201 /* Deprectated functions */
00202 /* Limit encoding and decoding to use no more than this amount of buffer bytes */
00203 #define GSM_7BIT_LEGACY_MAX_BUFFER_SIZE  0x10000
00204 
00205 int gsm_7bit_decode(char *decoded, const uint8_t *user_data, uint8_t length) OSMO_DEPRECATED("Use gsm_7bit_decode_n() instead");
00206 int gsm_7bit_decode_ussd(char *decoded, const uint8_t *user_data, uint8_t length) OSMO_DEPRECATED("Use gsm_7bit_decode_n_ussd() instead");
00207 int gsm_7bit_encode(uint8_t *result, const char *data) OSMO_DEPRECATED("Use gsm_7bit_encode_n() instead");
00208 int gsm_7bit_encode_ussd(uint8_t *result, const char *data, int *octets_written) OSMO_DEPRECATED("Use gsm_7bit_encode_n_ussd() instead");
00209 int gsm_7bit_encode_oct(uint8_t *result, const char *data, int *octets_written) OSMO_DEPRECATED("Use gsm_7bit_encode_n() instead");