Merge commit '816e24cb4296d6b7110da4a89661bbac8dc7af21' into libosmocore
[osmocom-bb.git] / src / shared / libosmocore / include / osmocore / gsm_utils.h
index 57521ac..7dc2388 100644 (file)
@@ -2,7 +2,7 @@
 /*
  * (C) 2008 by Daniel Willmann <daniel@totalueberwachung.de>
  * (C) 2009 by Holger Hans Peter Freyther <zecke@selfish.org>
- * (C) 2009 by Harald Welte <laforge@gnumonks.org>
+ * (C) 2009-2010 by Harald Welte <laforge@gnumonks.org>
  *
  * All Rights Reserved
  *
 
 #include <stdint.h>
 
+#define ADD_MODULO(sum, delta, modulo) do {    \
+       if ((sum += delta) >= modulo)           \
+               sum -= modulo;                  \
+       } while (0)
+
+#define GSM_MAX_FN     (26*51*2048)
+
+struct gsm_time {
+       uint32_t        fn;     /* FN count */
+       uint16_t        t1;     /* FN div (26*51) */
+       uint8_t         t2;     /* FN modulo 26 */
+       uint8_t         t3;     /* FN modulo 51 */
+       uint8_t         tc;
+};
+
 enum gsm_band {
        GSM_BAND_850    = 1,
        GSM_BAND_900    = 2,
@@ -38,6 +53,9 @@ enum gsm_band {
        GSM_BAND_810    = 0x80,
 };
 
+const char *gsm_band_name(enum gsm_band band);
+enum gsm_band gsm_band_parse(const char *mhz);
+
 int gsm_7bit_decode(char *decoded, const uint8_t *user_data, uint8_t length);
 int gsm_7bit_encode(uint8_t *result, const char *data);
 
@@ -48,6 +66,18 @@ int ms_pwr_dbm(enum gsm_band band, uint8_t lvl);
 int rxlev2dbm(uint8_t rxlev);
 uint8_t dbm2rxlev(int dbm);
 
+/* According to GSM 04.08 Chapter 10.5.1.6 */
+static inline int ms_cm2_a5n_support(uint8_t *cm2, int n) {
+       switch (n) {
+               case 0: return 1;
+               case 1: return (cm2[0] & (1<<3)) ? 0 : 1;
+               case 2: return (cm2[2] & (1<<0)) ? 1 : 0;
+               case 3: return (cm2[2] & (1<<1)) ? 1 : 0;
+               default:
+                       return 0;
+       }
+}
+
 /* According to GSM 04.08 Chapter 10.5.2.29 */
 static inline int rach_max_trans_val2raw(int val) { return (val >> 1) & 3; }
 static inline int rach_max_trans_raw2val(int raw) {
@@ -55,5 +85,33 @@ static inline int rach_max_trans_raw2val(int raw) {
        return tbl[raw & 3];
 }
 
+#define        ARFCN_PCS       0x8000
+#define        ARFCN_UPLINK    0x4000
+
+enum gsm_band gsm_arfcn2band(uint16_t arfcn);
+
+/* Convert an ARFCN to the frequency in MHz * 10 */
+uint16_t gsm_arfcn2freq10(uint16_t arfcn, int uplink);
+
+/* Convert from frame number to GSM time */
+void gsm_fn2gsmtime(struct gsm_time *time, uint32_t fn);
+
+/* Convert from GSM time to frame number */
+uint32_t gsm_gsmtime2fn(struct gsm_time *time);
+
+/* GSM TS 03.03 Chapter 2.6 */
+enum gprs_tlli_type {
+       TLLI_LOCAL,
+       TLLI_FOREIGN,
+       TLLI_RANDOM,
+       TLLI_AUXILIARY,
+       TLLI_RESERVED,
+};
+
+/* TS 03.03 Chapter 2.6 */
+int gprs_tlli_type(uint32_t tlli);
+
+uint32_t gprs_tmsi2tlli(uint32_t p_tmsi, enum gprs_tlli_type type);
+
 void generate_backtrace();
 #endif